From 6e448edc63ecfdaf3f6ebb2e015e2d3c12dd1d95 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 16 Nov 2023 14:04:34 -0500 Subject: [PATCH] no_log avoid masking booleans (#82217) * no_log avoid masking booleans * clog * fix issues --- changelogs/fragments/no_log_booly.yml | 2 + lib/ansible/module_utils/basic.py | 12 ++++++ .../library/module_that_has_secret.py | 18 +++++++++ .../targets/module_no_log/tasks/main.yml | 38 +++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 changelogs/fragments/no_log_booly.yml create mode 100644 test/integration/targets/module_no_log/library/module_that_has_secret.py diff --git a/changelogs/fragments/no_log_booly.yml b/changelogs/fragments/no_log_booly.yml new file mode 100644 index 00000000000..2fc499ddd9f --- /dev/null +++ b/changelogs/fragments/no_log_booly.yml @@ -0,0 +1,2 @@ +bugfixes: + - module no_log will no longer affect top level booleans, for example ``no_log_module_parameter='a'`` will no longer hide ``changed=False`` as a 'no log value' (matches 'a'). diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 9cfe32e56f0..a4d28c267df 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -1479,7 +1479,19 @@ class AnsibleModule(object): if deprecations: kwargs['deprecations'] = deprecations + # preserve bools/none from no_log + # TODO: once python version on target high enough, dict comprh + preserved = {} + for k, v in kwargs.items(): + if v is None or isinstance(v, bool): + preserved[k] = v + + # strip no_log collisions kwargs = remove_values(kwargs, self.no_log_values) + + # return preserved + kwargs.update(preserved) + print('\n%s' % self.jsonify(kwargs)) def exit_json(self, **kwargs): diff --git a/test/integration/targets/module_no_log/library/module_that_has_secret.py b/test/integration/targets/module_no_log/library/module_that_has_secret.py new file mode 100644 index 00000000000..5bdfc8507d5 --- /dev/null +++ b/test/integration/targets/module_no_log/library/module_that_has_secret.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +from __future__ import annotations + +from ansible.module_utils.basic import AnsibleModule + + +def main(): + module = AnsibleModule(argument_spec=dict( + secret=dict(no_log=True), + notsecret=dict(no_log=False), + )) + + msg = "My secret is: (%s), but don't tell %s" % (module.params['secret'], module.params['notsecret']) + module.exit_json(msg=msg, changed=bool(module.params['secret'] == module.params['notsecret'])) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/module_no_log/tasks/main.yml b/test/integration/targets/module_no_log/tasks/main.yml index cf9e5802570..bf024105f3d 100644 --- a/test/integration/targets/module_no_log/tasks/main.yml +++ b/test/integration/targets/module_no_log/tasks/main.yml @@ -59,3 +59,41 @@ # 2) the AnsibleModule.log method is not working - good_message in grep.stdout - bad_message not in grep.stdout + +- name: Ensure we do not obscure what we should not + block: + - module_that_has_secret: + secret: u + notsecret: u + register: ouch + ignore_errors: true + + - name: no log wont obscure booleans when True, but still hide in msg + assert: + that: + - ouch['changed'] is boolean + - "'*' in ouch['msg']" + + - module_that_has_secret: + secret: a + notsecret: b + register: ouch + ignore_errors: true + + - name: no log wont obscure booleans when False, but still hide in msg + assert: + that: + - ouch['changed'] is boolean + - "'*' in ouch['msg']" + + - module_that_has_secret: + secret: True + notsecret: False + register: ouch + ignore_errors: true + + - name: no log does not hide bool values + assert: + that: + - ouch['changed'] is boolean + - "'*' not in ouch['msg']"