summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2015-10-18 10:07:20 -0400
committerJames Cammarata <jimi@sngx.net>2015-10-18 10:09:05 -0400
commit0bbe9d5bd019c684b7753f9b2da17bc15bc99cef (patch)
treef13d3ffa1f0eb2f1b1b05dbf4cbaa1f2da98bc86
parent22cbfacab00bfc1c4e5a1e79a109f976e88f0dc8 (diff)
downloadansible-0bbe9d5bd019c684b7753f9b2da17bc15bc99cef.tar.gz
Make hostvars json/yaml serializable in filters
Fixes #12615
-rw-r--r--lib/ansible/parsing/yaml/dumper.py9
-rw-r--r--lib/ansible/plugins/filter/core.py16
-rw-r--r--lib/ansible/vars/hostvars.py5
3 files changed, 26 insertions, 4 deletions
diff --git a/lib/ansible/parsing/yaml/dumper.py b/lib/ansible/parsing/yaml/dumper.py
index 372972109c..a51289b09b 100644
--- a/lib/ansible/parsing/yaml/dumper.py
+++ b/lib/ansible/parsing/yaml/dumper.py
@@ -23,6 +23,7 @@ import yaml
from ansible.compat.six import PY3
from ansible.parsing.yaml.objects import AnsibleUnicode
+from ansible.vars.hostvars import HostVars
class AnsibleDumper(yaml.SafeDumper):
'''
@@ -31,6 +32,9 @@ class AnsibleDumper(yaml.SafeDumper):
'''
pass
+def represent_hostvars(self, data):
+ return self.represent_dict(dict(data))
+
if PY3:
represent_unicode = yaml.representer.SafeRepresenter.represent_str
else:
@@ -41,3 +45,8 @@ AnsibleDumper.add_representer(
represent_unicode,
)
+AnsibleDumper.add_representer(
+ HostVars,
+ represent_hostvars,
+)
+
diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py
index 224502a22d..d469550f0f 100644
--- a/lib/ansible/plugins/filter/core.py
+++ b/lib/ansible/plugins/filter/core.py
@@ -45,6 +45,7 @@ from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.utils.hashing import md5s, checksum_s
from ansible.utils.unicode import unicode_wrap, to_unicode
from ansible.utils.vars import merge_hash
+from ansible.vars.hostvars import HostVars
try:
import passlib.hash
@@ -55,6 +56,17 @@ except:
UUID_NAMESPACE_ANSIBLE = uuid.UUID('361E6D51-FAEC-444A-9079-341386DA8E2E')
+class AnsibleJSONEncoder(json.JSONEncoder):
+ '''
+ Simple encoder class to deal with JSON encoding of internal
+ types like HostVars
+ '''
+ def default(self, o):
+ if isinstance(o, HostVars):
+ return dict(o)
+ else:
+ return o
+
def to_yaml(a, *args, **kw):
'''Make verbose, human readable yaml'''
transformed = yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, **kw)
@@ -67,7 +79,7 @@ def to_nice_yaml(a, *args, **kw):
def to_json(a, *args, **kw):
''' Convert the value to JSON '''
- return json.dumps(a, *args, **kw)
+ return json.dumps(a, cls=AnsibleJSONEncoder, *args, **kw)
def to_nice_json(a, *args, **kw):
'''Make verbose, human readable JSON'''
@@ -87,7 +99,7 @@ def to_nice_json(a, *args, **kw):
return simplejson.dumps(a, indent=4, sort_keys=True, *args, **kw)
# Fallback to the to_json filter
return to_json(a, *args, **kw)
- return json.dumps(a, indent=4, sort_keys=True, *args, **kw)
+ return json.dumps(a, indent=4, sort_keys=True, cls=AnsibleJSONEncoder, *args, **kw)
def bool(a):
''' return a bool for the arg '''
diff --git a/lib/ansible/vars/hostvars.py b/lib/ansible/vars/hostvars.py
index 17325e219b..9f83342be3 100644
--- a/lib/ansible/vars/hostvars.py
+++ b/lib/ansible/vars/hostvars.py
@@ -78,10 +78,11 @@ class HostVars(collections.Mapping):
return False
def __iter__(self):
- raise NotImplementedError('HostVars does not support iteration as hosts are discovered on an as needed basis.')
+ for host in self._lookup:
+ yield host
def __len__(self):
- raise NotImplementedError('HostVars does not support len. hosts entries are discovered dynamically as needed')
+ return len(self._lookup)
def __getstate__(self):
return dict(loader=self._loader, lookup=self._lookup, play=self._play, var_manager=self._variable_manager)