Allow finer grained control for dupe YAML keys (#56933)

* Allow finer grained control for dupe YAML keys

  fixes #16903

* expand option to handle errors

* remove clog for previous version of toggle

* added missing parens

* fix typoe
This commit is contained in:
Brian Coca 2019-05-28 11:57:16 -04:00 committed by GitHub
parent c97d8ce25b
commit 1a893a48a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 13 deletions

View file

@ -1,3 +0,0 @@
---
minor_changes:
- added config toggle for YAML duplicate dict key warnings

View file

@ -0,0 +1,2 @@
minor_changes:
- Allow expanded options for user to control behaviour on duplicate YAML keys.

View file

@ -1253,16 +1253,17 @@ DOCSITE_ROOT_URL:
ini: ini:
- {key: docsite_root_url, section: defaults} - {key: docsite_root_url, section: defaults}
version_added: "2.8" version_added: "2.8"
DUPLICATE_DICT_KEY_WARNINGS: DUPLICATE_YAML_DICT_KEY:
name: Toggle warnings for duplicate dict keys in YAML name: Controls ansible behaviour when finding duplicate keys in YAML.
default: True default: warn
description: description:
- By default Ansible will issue a warning when a duplicate dict key is encountered in YAML. - 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. - 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: ini:
- {key: duplicate_dict_key_warnings, section: defaults} - {key: duplicate_dict_key, section: defaults}
type: boolean type: string
choices: ['warn', 'error', 'ignore']
version_added: "2.9" version_added: "2.9"
ERROR_ON_MISSING_HANDLER: ERROR_ON_MISSING_HANDLER:
name: Missing handler error name: Missing handler error

View file

@ -23,7 +23,7 @@ from yaml.constructor import SafeConstructor, ConstructorError
from yaml.nodes import MappingNode from yaml.nodes import MappingNode
from ansible import constants as C 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 AnsibleMapping, AnsibleSequence, AnsibleUnicode
from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
from ansible.utils.unsafe_proxy import wrap_var from ansible.utils.unsafe_proxy import wrap_var
@ -71,9 +71,15 @@ class AnsibleConstructor(SafeConstructor):
"found unacceptable key (%s)" % exc, key_node.start_mark) "found unacceptable key (%s)" % exc, key_node.start_mark)
if key in mapping: if key in mapping:
if C.DUPLICATE_DICT_KEY_WARNINGS: msg = (u'While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).'
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)) 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) value = self.construct_object(value_node, deep=deep)
mapping[key] = value mapping[key] = value