mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Merge pull request #1903 from leucos/mergeable-hash-vars
Adds user-selectable hash merging support in vars
This commit is contained in:
commit
53fd85e2c4
4 changed files with 43 additions and 3 deletions
|
@ -76,6 +76,16 @@ remote_port=22
|
||||||
|
|
||||||
sudo_exe=sudo
|
sudo_exe=sudo
|
||||||
|
|
||||||
|
# how to handle hash defined in several places
|
||||||
|
# hash can be merged, or replaced
|
||||||
|
# if you use replace, and have multiple hashes named 'x', the last defined
|
||||||
|
# will override the previously defined one
|
||||||
|
# if you use merge here, hash will cumulate their keys, but keys will still
|
||||||
|
# override each other
|
||||||
|
# replace is the default value, and is how ansible always handled hash variables
|
||||||
|
#
|
||||||
|
# hash_behaviour=replace
|
||||||
|
|
||||||
# if set, always use this private key file for authentication, same as if passing
|
# if set, always use this private key file for authentication, same as if passing
|
||||||
# --private-key to ansible or ansible-playbook
|
# --private-key to ansible or ansible-playbook
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ DEFAULT_MANAGED_STR = get_config(p, DEFAULTS, 'ansible_managed', None,
|
||||||
DEFAULT_SYSLOG_FACILITY = get_config(p, DEFAULTS, 'syslog_facility', 'ANSIBLE_SYSLOG_FACILITY', 'LOG_USER')
|
DEFAULT_SYSLOG_FACILITY = get_config(p, DEFAULTS, 'syslog_facility', 'ANSIBLE_SYSLOG_FACILITY', 'LOG_USER')
|
||||||
DEFAULT_KEEP_REMOTE_FILES = get_config(p, DEFAULTS, 'keep_remote_files', 'ANSIBLE_KEEP_REMOTE_FILES', '0')
|
DEFAULT_KEEP_REMOTE_FILES = get_config(p, DEFAULTS, 'keep_remote_files', 'ANSIBLE_KEEP_REMOTE_FILES', '0')
|
||||||
DEFAULT_SUDO_EXE = get_config(p, DEFAULTS, 'sudo_exe', 'ANSIBLE_SUDO_EXE', 'sudo')
|
DEFAULT_SUDO_EXE = get_config(p, DEFAULTS, 'sudo_exe', 'ANSIBLE_SUDO_EXE', 'sudo')
|
||||||
|
DEFAULT_HASH_BEHAVIOUR = get_config(p, DEFAULTS, 'hash_behaviour', 'ANSIBLE_HASH_BEHAVIOUR', 'replace')
|
||||||
|
|
||||||
DEFAULT_ACTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'action_plugins', None, '/usr/share/ansible_plugins/action_plugins'))
|
DEFAULT_ACTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'action_plugins', None, '/usr/share/ansible_plugins/action_plugins'))
|
||||||
DEFAULT_CALLBACK_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'callback_plugins', None, '/usr/share/ansible_plugins/callback_plugins'))
|
DEFAULT_CALLBACK_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'callback_plugins', None, '/usr/share/ansible_plugins/callback_plugins'))
|
||||||
|
|
|
@ -19,6 +19,7 @@ import os
|
||||||
import glob
|
import glob
|
||||||
from ansible import errors
|
from ansible import errors
|
||||||
from ansible import utils
|
from ansible import utils
|
||||||
|
import ansible.constants as C
|
||||||
|
|
||||||
class VarsModule(object):
|
class VarsModule(object):
|
||||||
|
|
||||||
|
@ -48,6 +49,10 @@ class VarsModule(object):
|
||||||
data = utils.parse_yaml_from_file(path)
|
data = utils.parse_yaml_from_file(path)
|
||||||
if type(data) != dict:
|
if type(data) != dict:
|
||||||
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
|
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
|
||||||
|
if C.DEFAULT_HASH_BEHAVIOUR == "merge":
|
||||||
|
# let data content override results if needed
|
||||||
|
results = utils.merge_hash(results, data)
|
||||||
|
else:
|
||||||
results.update(data)
|
results.update(data)
|
||||||
|
|
||||||
# load vars in playbook_dir/group_vars/name_of_host
|
# load vars in playbook_dir/group_vars/name_of_host
|
||||||
|
@ -56,7 +61,10 @@ class VarsModule(object):
|
||||||
data = utils.parse_yaml_from_file(path)
|
data = utils.parse_yaml_from_file(path)
|
||||||
if type(data) != dict:
|
if type(data) != dict:
|
||||||
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
|
raise errors.AnsibleError("%s must be stored as a dictionary/hash" % path)
|
||||||
|
if C.DEFAULT_HASH_BEHAVIOUR == "merge":
|
||||||
|
# let data content override results if needed
|
||||||
|
results = utils.merge_hash(results, data)
|
||||||
|
else:
|
||||||
results.update(data)
|
results.update(data)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import sys
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import yaml
|
import yaml
|
||||||
|
import copy
|
||||||
import optparse
|
import optparse
|
||||||
import operator
|
import operator
|
||||||
from ansible import errors
|
from ansible import errors
|
||||||
|
@ -273,6 +274,26 @@ def parse_kv(args):
|
||||||
options[k]=v
|
options[k]=v
|
||||||
return options
|
return options
|
||||||
|
|
||||||
|
def merge_hash(a, b):
|
||||||
|
''' merges hash b into a
|
||||||
|
this means that if b has key k, the resulting has will have a key k
|
||||||
|
which value comes from b
|
||||||
|
said differently, all key/value combination from b will override a's '''
|
||||||
|
|
||||||
|
# and iterate over b keys
|
||||||
|
for k, v in b.iteritems():
|
||||||
|
if k in a and isinstance(a[k], dict):
|
||||||
|
# if this key is a hash and exists in a
|
||||||
|
# we recursively call ourselves with
|
||||||
|
# the key value of b
|
||||||
|
a[k] = merge_hash(a[k], v)
|
||||||
|
else:
|
||||||
|
# k is not in a, no need to merge b, we just deecopy
|
||||||
|
# or k is not a dictionnary, no need to merge b either, we just deecopy it
|
||||||
|
a[k] = v
|
||||||
|
# finally, return the resulting hash when we're done iterating keys
|
||||||
|
return a
|
||||||
|
|
||||||
def md5s(data):
|
def md5s(data):
|
||||||
''' Return MD5 hex digest of data. '''
|
''' Return MD5 hex digest of data. '''
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue