From b8d057296a4096047f0d6fe07e032e13f6879996 Mon Sep 17 00:00:00 2001 From: Serge van Ginderachter Date: Thu, 21 Aug 2014 17:40:47 +0200 Subject: [PATCH 1/3] variable merging: detect if both vars are really dicts when combining/merging dicts --- lib/ansible/utils/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index c18174b00d2..401d35ed860 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -696,10 +696,17 @@ def parse_kv(args): options[k.strip()] = unquote(v.strip()) return options +def _validate_both_dicts(a, b): + + if not (isinstance(a, dict) and isinstance(b, dict)): + raise errors.AnsibleError("Failed to combine two values which are not " + "both hashes, got these differing values now:\n\n%s\n and\n%s" % (a, b)) + def merge_hash(a, b): ''' recursively merges hash b into a keys from b take precedence over keys from a ''' + _validate_both_dicts(a, b) result = {} for dicts in a, b: @@ -1308,6 +1315,8 @@ def listify_lookup_plugin_terms(terms, basedir, inject): def combine_vars(a, b): + _validate_both_dicts(a, b) + if C.DEFAULT_HASH_BEHAVIOUR == "merge": return merge_hash(a, b) else: From 3a228b9d55b00aa419b8beb8b3f24040cf52b2b5 Mon Sep 17 00:00:00 2001 From: Serge van Ginderachter Date: Thu, 21 Aug 2014 17:53:11 +0200 Subject: [PATCH 2/3] InventoryScript: better syntax checking for json stream --- lib/ansible/inventory/script.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/ansible/inventory/script.py b/lib/ansible/inventory/script.py index 8b2e4619a9c..e43cf249724 100644 --- a/lib/ansible/inventory/script.py +++ b/lib/ansible/inventory/script.py @@ -84,10 +84,14 @@ class InventoryScript(object): if not isinstance(data, dict): data = {'hosts': data} + # is not those subkeys, then simplified syntax, host with vars elif not any(k in data for k in ('hosts','vars')): data = {'hosts': [group_name], 'vars': data} if 'hosts' in data: + if not isinstance(data['hosts'], list): + raise errors.AnsibleError("You defined a group \"%s\" with bad " + "data for the host list:\n %s" % (group_name, data)) for hostname in data['hosts']: if not hostname in all_hosts: @@ -96,6 +100,10 @@ class InventoryScript(object): group.add_host(host) if 'vars' in data: + if not isinstance(data['vars'], dict): + raise errors.AnsibleError("You defined a group \"%s\" with bad " + "data for variables:\n %s" % (group_name, data)) + for k, v in data['vars'].iteritems(): if group.name == all.name: all.set_variable(k, v) From b81e77cfecf7ead5f1f2da836e5302f6987ac2ed Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Thu, 21 Aug 2014 13:24:53 -0500 Subject: [PATCH 3/3] Tweak error language in dict validation --- lib/ansible/utils/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 401d35ed860..1e6a5383c03 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -699,16 +699,20 @@ def parse_kv(args): def _validate_both_dicts(a, b): if not (isinstance(a, dict) and isinstance(b, dict)): - raise errors.AnsibleError("Failed to combine two values which are not " - "both hashes, got these differing values now:\n\n%s\n and\n%s" % (a, b)) + raise errors.AnsibleError( + "failed to combine variables, expected dicts but got a '%s' and a '%s'" % (type(a).__name__, type(b).__name__) + ) def merge_hash(a, b): ''' recursively merges hash b into a keys from b take precedence over keys from a ''' - _validate_both_dicts(a, b) result = {} + # we check here as well as in combine_vars() since this + # function can work recursively with nested dicts + _validate_both_dicts(a, b) + for dicts in a, b: # next, iterate over b keys and values for k, v in dicts.iteritems():