diff options
author | Sam Doran <github@samdoran.com> | 2022-05-10 17:40:19 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-10 16:40:19 -0500 |
commit | 4bde2d8a9788a47506004da0878775761ee3761d (patch) | |
tree | f3b0f5ac8954ca2abcffe1b040c77d74e5a43a6d | |
parent | 625a99aa32be39cbd9a8c7c8ad326d57cf03812c (diff) | |
download | ansible-4bde2d8a9788a47506004da0878775761ee3761d.tar.gz |
[stable-2.12] arg_spec - Return aliases in validation result and update aliases (#77576) (#77602)
* [stable-2.12] arg_spec - Return aliases in validation result and update aliases (#77576)
When looking up the `no_log` setting for a parameter that is an alias in
`AnsibleModule._log_invocation()`, the alias value will always be an
empty dictionary since `self.aliases` on the `AnsibleModule` instance is
never updated after initialization. Since the `no_log` setting is on the
canonical parameter not the alias, an incorrect warning is issued if the
parameter matches `PASSWORD_MATCH`.
This PR returns the aliases dictionary as an attribute of the
`ValidationResult` and updates the `aliases` attribute on the
`AnsibleModule` instance.
(cherry picked from commit 1b947eaf92)
Co-authored-by: Sam Doran <github@samdoran.com>
* Rewrite test comprehension for Python 2.6
* No need for list inside the dict constructor
-rw-r--r-- | changelogs/fragments/77576-arg_spec-no_log-aliases.yml | 2 | ||||
-rw-r--r-- | lib/ansible/module_utils/basic.py | 1 | ||||
-rw-r--r-- | lib/ansible/module_utils/common/arg_spec.py | 6 | ||||
-rw-r--r-- | test/units/module_utils/basic/test_argument_spec.py | 13 | ||||
-rw-r--r-- | test/units/module_utils/common/arg_spec/test_aliases.py | 5 |
5 files changed, 24 insertions, 3 deletions
diff --git a/changelogs/fragments/77576-arg_spec-no_log-aliases.yml b/changelogs/fragments/77576-arg_spec-no_log-aliases.yml new file mode 100644 index 0000000000..4dfce34cbb --- /dev/null +++ b/changelogs/fragments/77576-arg_spec-no_log-aliases.yml @@ -0,0 +1,2 @@ +bugfixes: + - arg_spec - Fix incorrect ``no_log`` warning when a parameter alias is used (https://github.com/ansible/ansible/pull/77576) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index f243414295..b48e779d43 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -508,6 +508,7 @@ class AnsibleModule(object): self.validation_result = self.validator.validate(self.params) self.params.update(self.validation_result.validated_parameters) self.no_log_values.update(self.validation_result._no_log_values) + self.aliases.update(self.validation_result._aliases) try: error = self.validation_result.errors[0] diff --git a/lib/ansible/module_utils/common/arg_spec.py b/lib/ansible/module_utils/common/arg_spec.py index d3846659c7..9fa2b4d2c9 100644 --- a/lib/ansible/module_utils/common/arg_spec.py +++ b/lib/ansible/module_utils/common/arg_spec.py @@ -61,6 +61,7 @@ class ValidationResult: self._validated_parameters = deepcopy(parameters) self._deprecations = [] self._warnings = [] + self._aliases = {} self.errors = AnsibleValidationErrorMultiple() """ :class:`~ansible.module_utils.errors.AnsibleValidationErrorMultiple` containing all @@ -180,12 +181,11 @@ class ArgumentSpecValidator: alias_warnings = [] alias_deprecations = [] try: - aliases = _handle_aliases(self.argument_spec, result._validated_parameters, alias_warnings, alias_deprecations) + result._aliases.update(_handle_aliases(self.argument_spec, result._validated_parameters, alias_warnings, alias_deprecations)) except (TypeError, ValueError) as e: - aliases = {} result.errors.append(AliasError(to_native(e))) - legal_inputs = _get_legal_inputs(self.argument_spec, result._validated_parameters, aliases) + legal_inputs = _get_legal_inputs(self.argument_spec, result._validated_parameters, result._aliases) for option, alias in alias_warnings: result._warnings.append({'option': option, 'alias': alias}) diff --git a/test/units/module_utils/basic/test_argument_spec.py b/test/units/module_utils/basic/test_argument_spec.py index 24bbe2e906..211d65a22f 100644 --- a/test/units/module_utils/basic/test_argument_spec.py +++ b/test/units/module_utils/basic/test_argument_spec.py @@ -709,3 +709,16 @@ def test_no_log_none(stdin, capfd): # makes it into am.no_log_values. Instead we can check for the warning # emitted by am._log_invocation. assert len(get_warning_messages()) > 0 + + +@pytest.mark.parametrize("stdin", [{"pass": "testing"}], indirect=["stdin"]) +def test_no_log_alias(stdin, capfd): + """Given module parameters that use an alias for a parameter that matches + PASSWORD_MATCH and has no_log=True set, a warning should not be issued. + """ + arg_spec = { + "other_pass": {"no_log": True, "aliases": ["pass"]}, + } + am = basic.AnsibleModule(arg_spec) + + assert len(get_warning_messages()) == 0 diff --git a/test/units/module_utils/common/arg_spec/test_aliases.py b/test/units/module_utils/common/arg_spec/test_aliases.py index f4c96c74e5..4410572b09 100644 --- a/test/units/module_utils/common/arg_spec/test_aliases.py +++ b/test/units/module_utils/common/arg_spec/test_aliases.py @@ -95,6 +95,11 @@ def test_aliases(arg_spec, parameters, expected, deprecation, warning): assert isinstance(result, ValidationResult) assert result.validated_parameters == expected assert result.error_messages == [] + assert result._aliases == dict( + (alias, param) + for param, value in arg_spec.items() + for alias in value.get("aliases", []) + ) if deprecation: assert deprecation == result._deprecations[0] |