diff --git a/changelogs/fragments/56805-duplicate-dict-key-warnings.yml b/changelogs/fragments/56805-duplicate-dict-key-warnings.yml deleted file mode 100644 index 82715cc54b..0000000000 --- a/changelogs/fragments/56805-duplicate-dict-key-warnings.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - added config toggle for YAML duplicate dict key warnings diff --git a/changelogs/fragments/dupe_yaml_key.yml b/changelogs/fragments/dupe_yaml_key.yml new file mode 100644 index 0000000000..b1000c204d --- /dev/null +++ b/changelogs/fragments/dupe_yaml_key.yml @@ -0,0 +1,2 @@ +minor_changes: + - Allow expanded options for user to control behaviour on duplicate YAML keys. diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 5aaf8e30ee..c860919a2f 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -1253,16 +1253,17 @@ DOCSITE_ROOT_URL: ini: - {key: docsite_root_url, section: defaults} version_added: "2.8" -DUPLICATE_DICT_KEY_WARNINGS: - name: Toggle warnings for duplicate dict keys in YAML - default: True +DUPLICATE_YAML_DICT_KEY: + name: Controls ansible behaviour when finding duplicate keys in YAML. + default: warn description: - By default Ansible will issue a warning when a duplicate dict key is encountered in YAML. - These warnings can be silenced by adjusting this setting to False. - env: [{name: ANSIBLE_DUPLICATE_DICT_KEY_WARNINGS}] + env: [{name: ANSIBLE_DUPLICATE_YAML_DICT_KEY}] ini: - - {key: duplicate_dict_key_warnings, section: defaults} - type: boolean + - {key: duplicate_dict_key, section: defaults} + type: string + choices: ['warn', 'error', 'ignore'] version_added: "2.9" ERROR_ON_MISSING_HANDLER: name: Missing handler error diff --git a/lib/ansible/parsing/yaml/constructor.py b/lib/ansible/parsing/yaml/constructor.py index ea7c38edac..cea855d7fc 100644 --- a/lib/ansible/parsing/yaml/constructor.py +++ b/lib/ansible/parsing/yaml/constructor.py @@ -23,7 +23,7 @@ from yaml.constructor import SafeConstructor, ConstructorError from yaml.nodes import MappingNode from ansible import constants as C -from ansible.module_utils._text import to_bytes +from ansible.module_utils._text import to_bytes, to_native from ansible.parsing.yaml.objects import AnsibleMapping, AnsibleSequence, AnsibleUnicode from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode from ansible.utils.unsafe_proxy import wrap_var @@ -71,9 +71,15 @@ class AnsibleConstructor(SafeConstructor): "found unacceptable key (%s)" % exc, key_node.start_mark) if key in mapping: - if C.DUPLICATE_DICT_KEY_WARNINGS: - display.warning(u'While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).' - u' Using last defined value only.'.format(key, *mapping.ansible_pos)) + msg = (u'While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).' + u' Using last defined value only.'.format(key, *mapping.ansible_pos)) + if C.DUPLICATE_YAML_DICT_KEY == 'warn': + display.warning(msg) + elif C.DUPLICATE_YAML_DICT_KEY == 'error': + raise ConstructorError(to_native(msg)) + else: + # when 'ignore' + display.debug(msg) value = self.construct_object(value_node, deep=deep) mapping[key] = value