diff options
Diffstat (limited to 'filter_plugins/oo_filters.py')
-rw-r--r-- | filter_plugins/oo_filters.py | 101 |
1 files changed, 62 insertions, 39 deletions
diff --git a/filter_plugins/oo_filters.py b/filter_plugins/oo_filters.py index ed6923687..b550bd16a 100644 --- a/filter_plugins/oo_filters.py +++ b/filter_plugins/oo_filters.py @@ -1,26 +1,36 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # vim: expandtab:tabstop=4:shiftwidth=4 -# pylint: disable=no-name-in-module, import-error, wrong-import-order, ungrouped-imports +# pylint: disable=too-many-lines """ Custom filters for use in openshift-ansible """ +import json import os import pdb -import pkg_resources -import re -import json -import yaml import random +import re -from ansible import errors from collections import Mapping -from distutils.util import strtobool -from distutils.version import LooseVersion +# pylint no-name-in-module and import-error disabled here because pylint +# fails to properly detect the packages when installed in a virtualenv +from distutils.util import strtobool # pylint:disable=no-name-in-module,import-error +from distutils.version import LooseVersion # pylint:disable=no-name-in-module,import-error from operator import itemgetter -from ansible.module_utils.six.moves.urllib.parse import urlparse + +import pkg_resources +import yaml + +from ansible import errors from ansible.parsing.yaml.dumper import AnsibleDumper -from six import string_types + +# ansible.compat.six goes away with Ansible 2.4 +try: + from ansible.compat.six import string_types, u + from ansible.compat.six.moves.urllib.parse import urlparse +except ImportError: + from ansible.module_utils.six import string_types, u + from ansible.module_utils.six.moves.urllib.parse import urlparse HAS_OPENSSL = False try: @@ -29,15 +39,6 @@ try: except ImportError: pass -try: - # ansible-2.2 - # ansible.utils.unicode.to_unicode is deprecated in ansible-2.2, - # ansible.module_utils._text.to_text should be used instead. - from ansible.module_utils._text import to_text -except ImportError: - # ansible-2.1 - from ansible.utils.unicode import to_unicode as to_text - def oo_pdb(arg): """ This pops you into a pdb instance where arg is the data passed in @@ -117,8 +118,7 @@ def oo_merge_hostvars(hostvars, variables, inventory_hostname): raise errors.AnsibleFilterError("|failed expects variables is a dictionary") if not isinstance(inventory_hostname, string_types): raise errors.AnsibleFilterError("|failed expects inventory_hostname is a string") - # pylint: disable=no-member - ansible_version = pkg_resources.get_distribution("ansible").version + ansible_version = pkg_resources.get_distribution("ansible").version # pylint: disable=maybe-no-member merged_hostvars = {} if LooseVersion(ansible_version) >= LooseVersion('2.0.0'): merged_hostvars = oo_merge_dicts( @@ -129,34 +129,57 @@ def oo_merge_hostvars(hostvars, variables, inventory_hostname): return merged_hostvars -def oo_collect(data, attribute=None, filters=None): +def oo_collect(data_list, attribute=None, filters=None): """ This takes a list of dict and collects all attributes specified into a list. If filter is specified then we will include all items that match _ALL_ of filters. If a dict entry is missing the key in a filter it will be excluded from the match. - Ex: data = [ {'a':1, 'b':5, 'z': 'z'}, # True, return - {'a':2, 'z': 'z'}, # True, return - {'a':3, 'z': 'z'}, # True, return - {'a':4, 'z': 'b'}, # FAILED, obj['z'] != obj['z'] - ] + Ex: data_list = [ {'a':1, 'b':5, 'z': 'z'}, # True, return + {'a':2, 'z': 'z'}, # True, return + {'a':3, 'z': 'z'}, # True, return + {'a':4, 'z': 'b'}, # FAILED, obj['z'] != obj['z'] + ] attribute = 'a' filters = {'z': 'z'} returns [1, 2, 3] + + This also deals with lists of lists with dict as elements. + Ex: data_list = [ + [ {'a':1, 'b':5, 'z': 'z'}, # True, return + {'a':2, 'b':6, 'z': 'z'} # True, return + ], + [ {'a':3, 'z': 'z'}, # True, return + {'a':4, 'z': 'b'} # FAILED, obj['z'] != obj['z'] + ], + {'a':5, 'z': 'z'}, # True, return + ] + attribute = 'a' + filters = {'z': 'z'} + returns [1, 2, 3, 5] """ - if not isinstance(data, list): - raise errors.AnsibleFilterError("|failed expects to filter on a List") + if not isinstance(data_list, list): + raise errors.AnsibleFilterError("oo_collect expects to filter on a List") if not attribute: - raise errors.AnsibleFilterError("|failed expects attribute to be set") + raise errors.AnsibleFilterError("oo_collect expects attribute to be set") + + data = [] + retval = [] + + for item in data_list: + if isinstance(item, list): + retval.extend(oo_collect(item, attribute, filters)) + else: + data.append(item) if filters is not None: if not isinstance(filters, dict): - raise errors.AnsibleFilterError("|failed expects filter to be a" - " dict") - retval = [get_attr(d, attribute) for d in data if ( - all([d.get(key, None) == filters[key] for key in filters]))] + raise errors.AnsibleFilterError( + "oo_collect expects filter to be a dict") + retval.extend([get_attr(d, attribute) for d in data if ( + all([d.get(key, None) == filters[key] for key in filters]))]) else: - retval = [get_attr(d, attribute) for d in data] + retval.extend([get_attr(d, attribute) for d in data]) retval = [val for val in retval if val is not None] @@ -659,11 +682,11 @@ def to_padded_yaml(data, level=0, indent=2, **kw): return "" try: - transformed = yaml.dump(data, indent=indent, allow_unicode=True, - default_flow_style=False, - Dumper=AnsibleDumper, **kw) + transformed = u(yaml.dump(data, indent=indent, allow_unicode=True, + default_flow_style=False, + Dumper=AnsibleDumper, **kw)) padded = "\n".join([" " * level * indent + line for line in transformed.splitlines()]) - return to_text("\n{0}".format(padded)) + return "\n{0}".format(padded) except Exception as my_e: raise errors.AnsibleFilterError('Failed to convert: %s' % my_e) |