I like Ansible/Jinja2's interfaces for writing custom filters. Easy work. As an example for others my code is below with some helpful references. Note: I'm a very junior Pythonian.
# ansible-python-jinja2 filter that removes sensitive data
# INPUT: dictionary - ie. Ansible's hostvars dictionary that may contain passwords
# OUTPUT: A filtered copy of dict with
# sensitive data removed
# METHOD: Make a copy of the incoming dictionary (don't touch the source)
# Recursively iterate through the whole tree
# Replaces sensitive values with the string "hidden by remove_sensitive_data jinja2 filter"
# Warning: I don't think Lists are handled properly
# The purpose is updating named strings so this is OK for now
# Code Quality: poor - learning python and this is a spike
# Sensitive data fields are hard coded
# Future: The sensitive field list should be pulled from Ansible's dict
import re
import collections
import yaml
import copy
# Recursive traverse of the dict
# Calling update_callback() for each element
# and stuffing the results back into the dict
def update_dict(d, update_callback):
# Check that d is a dictionary
if isinstance(d, collections.Mapping):
for k, v in d.items():
if isinstance(v, collections.Mapping):
updated = update_dict(v, update_callback)
d[k] = updated
#print "D: %s" % k
else:
d[k] = update_callback(k, v)
#print "V: %s" % k
# always return d whether it was modified or not
return d
# This is the callback func that filters/not each value in the dict
def rm_sensitive_data(key, value):
srchObj = re.search( r'ssh_pass', key )
if( srchObj ):
return 'value hidden by remove_sensitive_data jinja2 filter'
else:
return value
def remove_sensitive_data(arg):
# Don't change the original
mycopy = copy.deepcopy(arg)
update_dict( mycopy, rm_sensitive_data )
return mycopy
class FilterModule(object):
def filters(self):
return {'remove_sensitive_data': remove_sensitive_data}