Add 'hash_behaviour' option to include_vars module (#72944)
This commit is contained in:
parent
c404a9003f
commit
8e755707b9
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- include_vars - add ``hash_behaviour`` option (https://github.com/ansible/ansible/pull/72944).
|
|
@ -70,6 +70,14 @@ options:
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: no
|
||||||
version_added: "2.7"
|
version_added: "2.7"
|
||||||
|
hash_behaviour:
|
||||||
|
description:
|
||||||
|
- If set to C(merge), merges existing hash variables instead of overwriting them.
|
||||||
|
- If omitted C(null), the behavior falls back to the global I(hash_behaviour) configuration.
|
||||||
|
default: null
|
||||||
|
type: str
|
||||||
|
choices: ["replace", "merge"]
|
||||||
|
version_added: "2.12"
|
||||||
free-form:
|
free-form:
|
||||||
description:
|
description:
|
||||||
- This module allows you to specify the 'file' option directly without any other options.
|
- This module allows you to specify the 'file' option directly without any other options.
|
||||||
|
|
|
@ -7,10 +7,12 @@ __metaclass__ = type
|
||||||
from os import path, walk
|
from os import path, walk
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import ansible.constants as C
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.module_utils.six import string_types
|
from ansible.module_utils.six import string_types
|
||||||
from ansible.module_utils._text import to_native, to_text
|
from ansible.module_utils._text import to_native, to_text
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
|
from ansible.utils.vars import combine_vars
|
||||||
|
|
||||||
|
|
||||||
class ActionModule(ActionBase):
|
class ActionModule(ActionBase):
|
||||||
|
@ -20,7 +22,7 @@ class ActionModule(ActionBase):
|
||||||
VALID_FILE_EXTENSIONS = ['yaml', 'yml', 'json']
|
VALID_FILE_EXTENSIONS = ['yaml', 'yml', 'json']
|
||||||
VALID_DIR_ARGUMENTS = ['dir', 'depth', 'files_matching', 'ignore_files', 'extensions', 'ignore_unknown_extensions']
|
VALID_DIR_ARGUMENTS = ['dir', 'depth', 'files_matching', 'ignore_files', 'extensions', 'ignore_unknown_extensions']
|
||||||
VALID_FILE_ARGUMENTS = ['file', '_raw_params']
|
VALID_FILE_ARGUMENTS = ['file', '_raw_params']
|
||||||
VALID_ALL = ['name']
|
VALID_ALL = ['name', 'hash_behaviour']
|
||||||
|
|
||||||
def _set_dir_defaults(self):
|
def _set_dir_defaults(self):
|
||||||
if not self.depth:
|
if not self.depth:
|
||||||
|
@ -46,6 +48,7 @@ class ActionModule(ActionBase):
|
||||||
def _set_args(self):
|
def _set_args(self):
|
||||||
""" Set instance variables based on the arguments that were passed """
|
""" Set instance variables based on the arguments that were passed """
|
||||||
|
|
||||||
|
self.hash_behaviour = self._task.args.get('hash_behaviour', None)
|
||||||
self.return_results_as_name = self._task.args.get('name', None)
|
self.return_results_as_name = self._task.args.get('name', None)
|
||||||
self.source_dir = self._task.args.get('dir', None)
|
self.source_dir = self._task.args.get('dir', None)
|
||||||
self.source_file = self._task.args.get('file', None)
|
self.source_file = self._task.args.get('file', None)
|
||||||
|
@ -135,6 +138,11 @@ class ActionModule(ActionBase):
|
||||||
if failed:
|
if failed:
|
||||||
result['failed'] = failed
|
result['failed'] = failed
|
||||||
result['message'] = err_msg
|
result['message'] = err_msg
|
||||||
|
elif self.hash_behaviour is not None and self.hash_behaviour != C.DEFAULT_HASH_BEHAVIOUR:
|
||||||
|
merge_hashes = self.hash_behaviour == 'merge'
|
||||||
|
for key, value in results.items():
|
||||||
|
old_value = task_vars.get(key, None)
|
||||||
|
results[key] = combine_vars(old_value, value, merge=merge_hashes)
|
||||||
|
|
||||||
result['ansible_included_var_files'] = self.included_files
|
result['ansible_included_var_files'] = self.included_files
|
||||||
result['ansible_facts'] = results
|
result['ansible_facts'] = results
|
||||||
|
|
|
@ -79,12 +79,12 @@ def _validate_mutable_mappings(a, b):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def combine_vars(a, b):
|
def combine_vars(a, b, merge=None):
|
||||||
"""
|
"""
|
||||||
Return a copy of dictionaries of variables based on configured hash behavior
|
Return a copy of dictionaries of variables based on configured hash behavior
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if C.DEFAULT_HASH_BEHAVIOUR == "merge":
|
if merge or merge is None and C.DEFAULT_HASH_BEHAVIOUR == "merge":
|
||||||
return merge_hash(a, b)
|
return merge_hash(a, b)
|
||||||
else:
|
else:
|
||||||
# HASH_BEHAVIOUR == 'replace'
|
# HASH_BEHAVIOUR == 'replace'
|
||||||
|
|
|
@ -166,6 +166,48 @@
|
||||||
- "'my_custom_service' == service_name_fqcn"
|
- "'my_custom_service' == service_name_fqcn"
|
||||||
- "'my_custom_service' == service_name_tmpl_fqcn"
|
- "'my_custom_service' == service_name_tmpl_fqcn"
|
||||||
|
|
||||||
|
- name: Include a vars file with a hash variable
|
||||||
|
include_vars:
|
||||||
|
file: vars2/hashes/hash1.yml
|
||||||
|
|
||||||
|
- name: Verify the hash variable
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "{{ config | length }} == 3"
|
||||||
|
- "config.key0 == 0"
|
||||||
|
- "config.key1 == 0"
|
||||||
|
- "{{ config.key2 | length }} == 1"
|
||||||
|
- "config.key2.a == 21"
|
||||||
|
|
||||||
|
- name: Include the second file to merge the hash variable
|
||||||
|
include_vars:
|
||||||
|
file: vars2/hashes/hash2.yml
|
||||||
|
hash_behaviour: merge
|
||||||
|
|
||||||
|
- name: Verify that the hash is merged
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "{{ config | length }} == 4"
|
||||||
|
- "config.key0 == 0"
|
||||||
|
- "config.key1 == 1"
|
||||||
|
- "{{ config.key2 | length }} == 2"
|
||||||
|
- "config.key2.a == 21"
|
||||||
|
- "config.key2.b == 22"
|
||||||
|
- "config.key3 == 3"
|
||||||
|
|
||||||
|
- name: Include the second file again without hash_behaviour option
|
||||||
|
include_vars:
|
||||||
|
file: vars2/hashes/hash2.yml
|
||||||
|
|
||||||
|
- name: Verify that the properties from the first file is cleared
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "{{ config | length }} == 3"
|
||||||
|
- "config.key1 == 1"
|
||||||
|
- "{{ config.key2 | length }} == 1"
|
||||||
|
- "config.key2.b == 22"
|
||||||
|
- "config.key3 == 3"
|
||||||
|
|
||||||
- include_vars:
|
- include_vars:
|
||||||
file: no_auto_unsafe.yml
|
file: no_auto_unsafe.yml
|
||||||
register: baz
|
register: baz
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
key0: 0
|
||||||
|
key1: 0
|
||||||
|
key2: { a: 21 }
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
key1: 1
|
||||||
|
key2: { b: 22 }
|
||||||
|
key3: 3
|
Loading…
Reference in a new issue