(cherry picked from commit 0cdc410dce6658e93c06fa27e0100ddbb11e7015)
Jordan Borean authored on 2021/02/07 16:11:27... | ... |
@@ -712,6 +712,9 @@ class AnsibleModule(object): |
712 | 712 |
if k not in self.argument_spec: |
713 | 713 |
self.argument_spec[k] = v |
714 | 714 |
|
715 |
+ # Save parameter values that should never be logged |
|
716 |
+ self.no_log_values = set() |
|
717 |
+ |
|
715 | 718 |
self._load_params() |
716 | 719 |
self._set_fallbacks() |
717 | 720 |
|
... | ... |
@@ -723,8 +726,6 @@ class AnsibleModule(object): |
723 | 723 |
print('\n{"failed": true, "msg": "Module alias error: %s"}' % to_native(e)) |
724 | 724 |
sys.exit(1) |
725 | 725 |
|
726 |
- # Save parameter values that should never be logged |
|
727 |
- self.no_log_values = set() |
|
728 | 726 |
self._handle_no_log_values() |
729 | 727 |
|
730 | 728 |
# check the locale as set by the current environment, and reset to |
... | ... |
@@ -1944,14 +1945,15 @@ class AnsibleModule(object): |
1944 | 1944 |
param = self.params |
1945 | 1945 |
for (k, v) in spec.items(): |
1946 | 1946 |
default = v.get('default', None) |
1947 |
- if pre is True: |
|
1948 |
- # this prevents setting defaults on required items |
|
1949 |
- if default is not None and k not in param: |
|
1950 |
- param[k] = default |
|
1951 |
- else: |
|
1952 |
- # make sure things without a default still get set None |
|
1953 |
- if k not in param: |
|
1954 |
- param[k] = default |
|
1947 |
+ |
|
1948 |
+ # This prevents setting defaults on required items on the 1st run, |
|
1949 |
+ # otherwise will set things without a default to None on the 2nd. |
|
1950 |
+ if k not in param and (default is not None or not pre): |
|
1951 |
+ # Make sure any default value for no_log fields are masked. |
|
1952 |
+ if v.get('no_log', False) and default: |
|
1953 |
+ self.no_log_values.add(default) |
|
1954 |
+ |
|
1955 |
+ param[k] = default |
|
1955 | 1956 |
|
1956 | 1957 |
def _set_fallbacks(self, spec=None, param=None): |
1957 | 1958 |
if spec is None: |
... | ... |
@@ -1971,9 +1973,13 @@ class AnsibleModule(object): |
1971 | 1971 |
else: |
1972 | 1972 |
fallback_args = item |
1973 | 1973 |
try: |
1974 |
- param[k] = fallback_strategy(*fallback_args, **fallback_kwargs) |
|
1974 |
+ fallback_value = fallback_strategy(*fallback_args, **fallback_kwargs) |
|
1975 | 1975 |
except AnsibleFallbackNotFound: |
1976 | 1976 |
continue |
1977 |
+ else: |
|
1978 |
+ if v.get('no_log', False) and fallback_value: |
|
1979 |
+ self.no_log_values.add(fallback_value) |
|
1980 |
+ param[k] = fallback_value |
|
1977 | 1981 |
|
1978 | 1982 |
def _load_params(self): |
1979 | 1983 |
''' read the input and set the params attribute. |
1980 | 1984 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,31 @@ |
0 |
+# (c) 2021 Ansible Project |
|
1 |
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) |
|
2 |
+ |
|
3 |
+from __future__ import (absolute_import, division, print_function) |
|
4 |
+__metaclass__ = type |
|
5 |
+ |
|
6 |
+DOCUMENTATION = ''' |
|
7 |
+ name: pure_json |
|
8 |
+ type: stdout |
|
9 |
+ short_description: only outputs the module results as json |
|
10 |
+''' |
|
11 |
+ |
|
12 |
+import json |
|
13 |
+ |
|
14 |
+from ansible.plugins.callback import CallbackBase |
|
15 |
+ |
|
16 |
+ |
|
17 |
+class CallbackModule(CallbackBase): |
|
18 |
+ |
|
19 |
+ CALLBACK_VERSION = 2.0 |
|
20 |
+ CALLBACK_TYPE = 'stdout' |
|
21 |
+ CALLBACK_NAME = 'pure_json' |
|
22 |
+ |
|
23 |
+ def v2_runner_on_failed(self, result, ignore_errors=False): |
|
24 |
+ self._display.display(json.dumps(result._result)) |
|
25 |
+ |
|
26 |
+ def v2_runner_on_ok(self, result): |
|
27 |
+ self._display.display(json.dumps(result._result)) |
|
28 |
+ |
|
29 |
+ def v2_runner_on_skipped(self, result): |
|
30 |
+ self._display.display(json.dumps(result._result)) |
0 | 31 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,35 @@ |
0 |
+#!/usr/bin/python |
|
1 |
+# (c) 2021 Ansible Project |
|
2 |
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) |
|
3 |
+ |
|
4 |
+from __future__ import absolute_import, division, print_function |
|
5 |
+__metaclass__ = type |
|
6 |
+ |
|
7 |
+ |
|
8 |
+from ansible.module_utils.basic import AnsibleModule, env_fallback |
|
9 |
+ |
|
10 |
+ |
|
11 |
+def main(): |
|
12 |
+ module = AnsibleModule( |
|
13 |
+ argument_spec=dict( |
|
14 |
+ explicit_pass=dict(type='str', no_log=True), |
|
15 |
+ fallback_pass=dict(type='str', no_log=True, fallback=(env_fallback, ['SECRET_ENV'])), |
|
16 |
+ default_pass=dict(type='str', no_log=True, default='zyx'), |
|
17 |
+ normal=dict(type='str', default='plaintext'), |
|
18 |
+ suboption=dict( |
|
19 |
+ type='dict', |
|
20 |
+ options=dict( |
|
21 |
+ explicit_sub_pass=dict(type='str', no_log=True), |
|
22 |
+ fallback_sub_pass=dict(type='str', no_log=True, fallback=(env_fallback, ['SECRET_SUB_ENV'])), |
|
23 |
+ default_sub_pass=dict(type='str', no_log=True, default='xvu'), |
|
24 |
+ normal=dict(type='str', default='plaintext'), |
|
25 |
+ ), |
|
26 |
+ ), |
|
27 |
+ ), |
|
28 |
+ ) |
|
29 |
+ |
|
30 |
+ module.exit_json(changed=False) |
|
31 |
+ |
|
32 |
+ |
|
33 |
+if __name__ == '__main__': |
|
34 |
+ main() |
0 | 9 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,27 @@ |
0 |
+- hosts: testhost |
|
1 |
+ gather_facts: no |
|
2 |
+ tasks: |
|
3 |
+ # Invocation usually is output with 3vs or more, our callback plugin displays it anyway |
|
4 |
+ - name: Check no_log invocation results |
|
5 |
+ command: ansible-playbook -i {{ inventory_file }} module_utils_test_no_log.yml |
|
6 |
+ environment: |
|
7 |
+ ANSIBLE_CALLBACK_PLUGINS: callback |
|
8 |
+ ANSIBLE_STDOUT_CALLBACK: pure_json |
|
9 |
+ SECRET_ENV: ghi |
|
10 |
+ SECRET_SUB_ENV: jkl |
|
11 |
+ register: no_log_invocation |
|
12 |
+ |
|
13 |
+ - set_fact: |
|
14 |
+ no_log_invocation: '{{ no_log_invocation.stdout | trim | from_json }}' |
|
15 |
+ |
|
16 |
+ - name: check no log values from fallback or default are masked |
|
17 |
+ assert: |
|
18 |
+ that: |
|
19 |
+ - no_log_invocation.invocation.module_args.default_pass == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' |
|
20 |
+ - no_log_invocation.invocation.module_args.explicit_pass == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' |
|
21 |
+ - no_log_invocation.invocation.module_args.fallback_pass == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' |
|
22 |
+ - no_log_invocation.invocation.module_args.normal == 'plaintext' |
|
23 |
+ - no_log_invocation.invocation.module_args.suboption.default_sub_pass == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' |
|
24 |
+ - no_log_invocation.invocation.module_args.suboption.explicit_sub_pass == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' |
|
25 |
+ - no_log_invocation.invocation.module_args.suboption.fallback_sub_pass == 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER' |
|
26 |
+ - no_log_invocation.invocation.module_args.suboption.normal == 'plaintext' |
... | ... |
@@ -4,6 +4,10 @@ set -eux |
4 | 4 |
|
5 | 5 |
ANSIBLE_ROLES_PATH=../ ansible-playbook module_utils_basic_setcwd.yml -i ../../inventory "$@" |
6 | 6 |
|
7 |
+# Keep the -vvvvv here. This acts as a test for testing that higher verbosity |
|
8 |
+# doesn't traceback with unicode in the custom module_utils directory path. |
|
9 |
+ansible-playbook module_utils_vvvvv.yml -i ../../inventory -vvvvv "$@" |
|
10 |
+ |
|
7 | 11 |
ansible-playbook module_utils_test.yml -i ../../inventory -v "$@" |
8 | 12 |
ANSIBLE_MODULE_UTILS=other_mu_dir ansible-playbook module_utils_envvar.yml -i ../../inventory -v "$@" |
9 | 13 |
|