added slice filter for dicts
also minor exception optimization
This commit is contained in:
parent
107934241e
commit
73a003aa50
1 changed files with 37 additions and 24 deletions
|
@ -47,7 +47,7 @@ try:
|
||||||
except:
|
except:
|
||||||
HAS_PASSLIB = False
|
HAS_PASSLIB = False
|
||||||
|
|
||||||
from ansible import errors
|
from ansible.errors import AnsibleFilterError
|
||||||
from ansible.module_utils.six import iteritems, string_types, integer_types
|
from ansible.module_utils.six import iteritems, string_types, integer_types
|
||||||
from ansible.module_utils.six.moves import reduce, shlex_quote
|
from ansible.module_utils.six.moves import reduce, shlex_quote
|
||||||
from ansible.module_utils._text import to_bytes, to_text
|
from ansible.module_utils._text import to_bytes, to_text
|
||||||
|
@ -135,7 +135,7 @@ def strftime(string_format, second=None):
|
||||||
try:
|
try:
|
||||||
second = int(second)
|
second = int(second)
|
||||||
except:
|
except:
|
||||||
raise errors.AnsibleFilterError('Invalid value for epoch value (%s)' % second)
|
raise AnsibleFilterError('Invalid value for epoch value (%s)' % second)
|
||||||
return time.strftime(string_format, time.localtime(second))
|
return time.strftime(string_format, time.localtime(second))
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ def regex_search(value, regex, *args, **kwargs):
|
||||||
match = int(re.match(r'\\(\d+)', arg).group(1))
|
match = int(re.match(r'\\(\d+)', arg).group(1))
|
||||||
groups.append(match)
|
groups.append(match)
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleFilterError('Unknown argument')
|
raise AnsibleFilterError('Unknown argument')
|
||||||
|
|
||||||
flags = 0
|
flags = 0
|
||||||
if kwargs.get('ignorecase'):
|
if kwargs.get('ignorecase'):
|
||||||
|
@ -236,10 +236,10 @@ def rand(environment, end, start=None, step=None, seed=None):
|
||||||
return r.randrange(start, end, step)
|
return r.randrange(start, end, step)
|
||||||
elif hasattr(end, '__iter__'):
|
elif hasattr(end, '__iter__'):
|
||||||
if start or step:
|
if start or step:
|
||||||
raise errors.AnsibleFilterError('start and step can only be used with integer values')
|
raise AnsibleFilterError('start and step can only be used with integer values')
|
||||||
return r.choice(end)
|
return r.choice(end)
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleFilterError('random can only be used on sequences and integers')
|
raise AnsibleFilterError('random can only be used on sequences and integers')
|
||||||
|
|
||||||
|
|
||||||
def randomize_list(mylist, seed=None):
|
def randomize_list(mylist, seed=None):
|
||||||
|
@ -288,7 +288,7 @@ def get_encrypted_password(password, hashtype='sha512', salt=None):
|
||||||
|
|
||||||
if not HAS_PASSLIB:
|
if not HAS_PASSLIB:
|
||||||
if sys.platform.startswith('darwin'):
|
if sys.platform.startswith('darwin'):
|
||||||
raise errors.AnsibleFilterError('|password_hash requires the passlib python module to generate password hashes on Mac OS X/Darwin')
|
raise AnsibleFilterError('|password_hash requires the passlib python module to generate password hashes on Mac OS X/Darwin')
|
||||||
saltstring = "$%s$%s" % (cryptmethod[hashtype], salt)
|
saltstring = "$%s$%s" % (cryptmethod[hashtype], salt)
|
||||||
encrypted = crypt.crypt(password, saltstring)
|
encrypted = crypt.crypt(password, saltstring)
|
||||||
else:
|
else:
|
||||||
|
@ -313,14 +313,14 @@ def mandatory(a):
|
||||||
|
|
||||||
''' Make a variable mandatory '''
|
''' Make a variable mandatory '''
|
||||||
if isinstance(a, Undefined):
|
if isinstance(a, Undefined):
|
||||||
raise errors.AnsibleFilterError('Mandatory variable not defined.')
|
raise AnsibleFilterError('Mandatory variable not defined.')
|
||||||
return a
|
return a
|
||||||
|
|
||||||
|
|
||||||
def combine(*terms, **kwargs):
|
def combine(*terms, **kwargs):
|
||||||
recursive = kwargs.get('recursive', False)
|
recursive = kwargs.get('recursive', False)
|
||||||
if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs):
|
if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs):
|
||||||
raise errors.AnsibleFilterError("'recursive' is the only valid keyword argument")
|
raise AnsibleFilterError("'recursive' is the only valid keyword argument")
|
||||||
|
|
||||||
dicts = []
|
dicts = []
|
||||||
for t in terms:
|
for t in terms:
|
||||||
|
@ -329,7 +329,7 @@ def combine(*terms, **kwargs):
|
||||||
elif isinstance(t, list):
|
elif isinstance(t, list):
|
||||||
dicts.append(combine(*t, **kwargs))
|
dicts.append(combine(*t, **kwargs))
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleFilterError("|combine expects dictionaries, got " + repr(t))
|
raise AnsibleFilterError("|combine expects dictionaries, got " + repr(t))
|
||||||
|
|
||||||
if recursive:
|
if recursive:
|
||||||
return reduce(merge_hash, dicts)
|
return reduce(merge_hash, dicts)
|
||||||
|
@ -486,6 +486,22 @@ def flatten(mylist, levels=None):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def dict_slice(mydict, keys):
|
||||||
|
''' takes a dictionary and a list of keys and returns a list of values corresponding to those keys, if they exist '''
|
||||||
|
|
||||||
|
if not isinstance(mydict, MutableMapping):
|
||||||
|
raise AnsibleFilterError("The slice filter requires a mapping to operate on, got a %s." % type(mydict))
|
||||||
|
|
||||||
|
if not isinstance(keys, MutableSequence):
|
||||||
|
|
||||||
|
if isinstance(keys, string_types):
|
||||||
|
keys = [keys]
|
||||||
|
else:
|
||||||
|
AnsibleFilterError("The slice filter requires a key or list of keys, got %s instead." % type(keys))
|
||||||
|
|
||||||
|
return [mydict[key] for key in keys if key in mydict]
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
class FilterModule(object):
|
||||||
''' Ansible core jinja2 filters '''
|
''' Ansible core jinja2 filters '''
|
||||||
|
|
||||||
|
@ -493,7 +509,6 @@ class FilterModule(object):
|
||||||
return {
|
return {
|
||||||
# jinja2 overrides
|
# jinja2 overrides
|
||||||
'groupby': do_groupby,
|
'groupby': do_groupby,
|
||||||
'flatten': flatten,
|
|
||||||
|
|
||||||
# base 64
|
# base 64
|
||||||
'b64decode': b64decode,
|
'b64decode': b64decode,
|
||||||
|
@ -512,9 +527,6 @@ class FilterModule(object):
|
||||||
'to_nice_yaml': to_nice_yaml,
|
'to_nice_yaml': to_nice_yaml,
|
||||||
'from_yaml': from_yaml,
|
'from_yaml': from_yaml,
|
||||||
|
|
||||||
# date
|
|
||||||
'to_datetime': to_datetime,
|
|
||||||
|
|
||||||
# path
|
# path
|
||||||
'basename': partial(unicode_wrap, os.path.basename),
|
'basename': partial(unicode_wrap, os.path.basename),
|
||||||
'dirname': partial(unicode_wrap, os.path.dirname),
|
'dirname': partial(unicode_wrap, os.path.dirname),
|
||||||
|
@ -526,8 +538,12 @@ class FilterModule(object):
|
||||||
'win_dirname': partial(unicode_wrap, ntpath.dirname),
|
'win_dirname': partial(unicode_wrap, ntpath.dirname),
|
||||||
'win_splitdrive': partial(unicode_wrap, ntpath.splitdrive),
|
'win_splitdrive': partial(unicode_wrap, ntpath.splitdrive),
|
||||||
|
|
||||||
# value as boolean
|
# file glob
|
||||||
|
'fileglob': fileglob,
|
||||||
|
|
||||||
|
# types
|
||||||
'bool': to_bool,
|
'bool': to_bool,
|
||||||
|
'to_datetime': to_datetime,
|
||||||
|
|
||||||
# date formating
|
# date formating
|
||||||
'strftime': strftime,
|
'strftime': strftime,
|
||||||
|
@ -546,9 +562,6 @@ class FilterModule(object):
|
||||||
'password_hash': get_encrypted_password,
|
'password_hash': get_encrypted_password,
|
||||||
'hash': get_hash,
|
'hash': get_hash,
|
||||||
|
|
||||||
# file glob
|
|
||||||
'fileglob': fileglob,
|
|
||||||
|
|
||||||
# regex
|
# regex
|
||||||
'regex_replace': regex_replace,
|
'regex_replace': regex_replace,
|
||||||
'regex_escape': regex_escape,
|
'regex_escape': regex_escape,
|
||||||
|
@ -558,22 +571,22 @@ class FilterModule(object):
|
||||||
# ? : ;
|
# ? : ;
|
||||||
'ternary': ternary,
|
'ternary': ternary,
|
||||||
|
|
||||||
# list
|
|
||||||
# random stuff
|
# random stuff
|
||||||
'random': rand,
|
'random': rand,
|
||||||
'shuffle': randomize_list,
|
'shuffle': randomize_list,
|
||||||
|
|
||||||
# undefined
|
# undefined
|
||||||
'mandatory': mandatory,
|
'mandatory': mandatory,
|
||||||
|
|
||||||
# merge dicts
|
|
||||||
'combine': combine,
|
|
||||||
|
|
||||||
# comment-style decoration
|
# comment-style decoration
|
||||||
'comment': comment,
|
'comment': comment,
|
||||||
|
|
||||||
# array and dict lookups
|
|
||||||
'extract': extract,
|
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
'type_debug': lambda o: o.__class__.__name__,
|
'type_debug': lambda o: o.__class__.__name__,
|
||||||
|
|
||||||
|
# Data structures
|
||||||
|
'combine': combine,
|
||||||
|
'extract': extract,
|
||||||
|
'flatten': flatten,
|
||||||
|
'slice': dict_slice,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue