예제 #1
0
    def test_helper_for_securitygroup_informer(self):
        '''Test a CidrCatalogHelper instance with a Security Group Informer.'''

        informers = self.sg_surv.informers()

        # - - - - - - - - - - - - - - - -
        informers_with_cidrip = [
            i for i in informers
            if prune.Pruner().leaf_satisfies(i.to_dict(
            ), 'IpPermissions.[].IpRanges.[]', lambda x: 'CidrIp' in x)
        ]

        self.assertTrue(len(informers_with_cidrip) > 0)

        self.helper.annotate_group_cidrip(informers_with_cidrip[0], 'name')

        self.assertTrue(prune.Pruner().leaf_satisfies(
            informers_with_cidrip[0].to_dict(), 'IpPermissions.[].IpRanges.[]',
            lambda x: 'name' in x))

        self.helper.annotate_group_cidrip(informers_with_cidrip[0],
                                          'short_name', 'description')

        self.assertTrue(prune.Pruner().leaf_satisfies(
            informers_with_cidrip[0].to_dict(), 'IpPermissions.[].IpRanges.[]',
            lambda x: 'short_name' in x and 'description' in x))

        # - - - - - - - - - - - - - - - -

        informers_with_egress_cidrip = [
            i for i in informers
            if prune.Pruner().leaf_satisfies(i.to_dict(
            ), 'IpPermissions.[].IpRanges.[]', lambda x: 'CidrIp' in x)
        ]

        self.assertTrue(len(informers_with_egress_cidrip) > 0)

        self.helper.annotate_group_cidrip(informers_with_egress_cidrip[0],
                                          'name')

        self.assertTrue(prune.Pruner().leaf_satisfies(
            informers_with_egress_cidrip[0].to_dict(),
            'IpPermissions.[].IpRanges.[]', lambda x: 'name' in x))
예제 #2
0
    def extract_from(self, informers, flat=True):
        '''Extract the fields specified by prune_specs.

        Arguments:

            informers (list of AWSInformer):
                ``AWSInformer`` instances from which to extract
                report data. Any informer whose ``entity_type``
                attribute doesn't match the report definition's
                ``entity_type`` attribute will be skipped.

            flat (bool):
                If ``True``, return a *flat* result; if ``False``,
                return a nested result. See the documentation for
                ``utensils.prune`` and ``utensils.flatten``
                for more information.

        '''
        pruner = prune.Pruner(*self.prune_specs)
        extractable_informers = [
            i for i in informers if i.entity_type == self.entity_type
        ]

        if flat:
            records = flatten.flatten([
                pruner.prune_branches(informer.to_dict(), balanced=True)
                for informer in extractable_informers
            ])

        else:
            records = [
                pruner.prune_tree(informer.to_dict())
                for informer in extractable_informers
            ]

        return records
예제 #3
0
파일: indexers.py 프로젝트: osgirl/boogio
def uid_index(forest, uid_path=None, uid_method=None):
    '''Index a set of nested structures by a specified unique id.

    Arguments:

        forest (list):
            A list of nested structures composed of lists, dicts and
            scalars to be indexed by unique id.

        uid_path (str):
            A prune path specification specifying the path to the
            unique ID value for each structure in ``forest``. See the
            ``utensils.prune`` module documentation for details.

        uid_method (function):
            A function that takes a single argument and when passed a
            structure in ``forest`` returns the unique ID value for
            that structure.

    Exactly one of uid_path and uid_method is required.

    Returns:

        (dict) A dictionary where each item key is the value selected
        by ``uid_path`` in each element of ``forest``, and the
        corresponding item value is the element of ``forest`` from
        which that value was selected.

    Raises:

        KeyError: if the value selected by ``uid_path`` from an
        element of ``forest`` was already selected from a previous
        element of ``forest``. This would indicate a duplication of
        the supposedly unique IDs.

        TypeError: if neither uid_path nor uid_method is provided, or
        if both are.

    '''
    logger = logging.getLogger(__name__)

    index = {}

    # Exactly one of uid_path and uid_method must be defined.
    defined_extractor_count = 2 - (uid_path, uid_method).count(None)
    if defined_extractor_count != 1:
        err_msg = (
            'uid_index: exactly one of uid_path and uid_method is required;'
            ' found %s' % ('neither', '', 'both')[defined_extractor_count]
            )
        logger.error(err_msg)
        raise TypeError(err_msg)

    for tree in forest:

        index_keys = []

        if uid_path:

            # It's unclear whether this ought to enforce getting a
            # single element list for index_keys.
            pruner = prune.Pruner({'path': prune.dotpath(uid_path)})
            for (_, pruned_keys) in pruner.prune_leaves(tree).items():
                index_keys.extend(pruned_keys)

        else:
            # Wrap this for consistency with the prune_leaves return
            # value type.
            index_keys = [uid_method(tree)]

        for index_key in list(set(index_keys)):

            if index_key in index:
                msg = (
                    'uid_index: duplicate occurrence of unique ID %s'
                    )
                logger.error(msg, index_key)
                raise KeyError(msg % index_key)

            index[index_key] = tree

    return index
예제 #4
0
파일: indexers.py 프로젝트: osgirl/boogio
def index_subtrees_by_paths(
        forest, paths, subtree_paths, duplicates=False,
        prep_method=None, key_method=None, value_method=None,
        ):  # pylint: disable=bad-continuation
    '''Build indices of subtrees of nested structures.

    Arguments:

        forest:
            A nested structure composed of lists, dicts and scalars.

        paths:
            A list of prune path specifications. See the
            ``utensils.prune`` module documentation for details.

        subtree_paths:
            A list of prune-style path specifications to the subelements
            to be indexed.

        duplicates (boolean, optional):
            If ``False`` (the default), no duplicate values will
            appear in the lists of values for each key in the indices
            returned. If ``True``, duplicates can occur.

        prep_method (function):
            If defined, each element of ``forest`` will be replaced
            locally with the result of passing it to the
            ``prep_method`` method. Thus,
            ``index_subtrees_by_paths([t1, t2], p, sp, prep_method=m)``
            will return the same value as
            ``index_subtrees_by_paths([m(t1), m(t2)], p, sp)``.

        key_method (function, optional):
            If defined,  each key ``K`` that would appear as a key in
            the resulting index will be replaced by the result of
            evaluating ``key_method(K)``.

        value_method (function, optional):
            If defined,  each value ``V`` that would appear in the
            list of values for any key in the resulting index will be
            replaced by the result of evaluating ``value_method(V)``.


    Returns:

        (dict) A dict whose keys are the list-reduced elements of paths,
        and whose values are dicts. The structure will look like this::

            {
            index_path:
                {
                    path_valueA: [subtree1, subtree2, ...],
                    path_valueB: [...],
                    ...
                    },
                ...
            }

        Here, the path_valueX keys are the values that occur at path
        in any of the elements of forest, and the list for each key is
        the specified subtrees taken from the elements of forest for
        which the path_valueX value occurs at path.

    '''
    index_pruner = prune.Pruner(
        *[{'path': prune.dotpath(p)} for p in paths]
        )
    subtree_pruner = prune.Pruner(
        *[{'path': prune.dotpath(p)} for p in subtree_paths]
        )

    indices = {}
    # print [{'path': p} for p in paths]

    for tree in forest:

        prepped_tree = prep_method(tree) if prep_method else tree

        index_leaves = index_pruner.prune_leaves(prepped_tree)
        subtrees = subtree_pruner.prune_leaves(prepped_tree)
        # print subtrees

        for (index_path, path_values) in index_leaves.items():

            if index_path not in indices:
                indices[index_path] = {}

            # for path_value in list(set(path_values)):

            for index_key in list(set(
                    [key_method(v) if key_method else v for v in path_values]
                    )):  # pylint: disable=bad-continuation

                if index_key not in indices[index_path]:
                    indices[index_path][index_key] = []

                for (_, subtree) in subtrees.items():
                    if value_method:
                        subtree = [value_method(t) for t in subtree]
                    # if (
                    #         value not in indices[index_path][index_key] or
                    #         duplicates
                    #         ):  # pylint: disable=bad-continuation
                    #     # print value
                    #     # print indices[index_path][index_key]
                    #     # print value not in indices[index_path][index_key]
                    indices[index_path][index_key].extend(
                        [
                            v for v in subtree
                            if (
                                v not in indices[index_path][index_key] or
                                duplicates
                                )
                            ]
                        )
                    # print indices[index_path][index_key]
                    # print

    return indices
예제 #5
0
파일: indexers.py 프로젝트: osgirl/boogio
def index_by_paths(
        forest, paths, duplicates=False,
        prep_method=None, key_method=None, value_method=None,
        ):  # pylint: disable=bad-continuation
    '''Build indices by values at specified paths into nested structures.

    Arguments:

        forest (list):
            A list of nested structures composed of lists, dicts and
            scalars.

        paths (list):
            A list of prune path specifications. See the
            ``utensils.prune`` module documentation for details.

        duplicates (boolean, optional):
            If ``False`` (the default), no duplicate values will
            appear in the lists of values for each key in the indices
            returned. If ``True``, duplicates can occur.

        prep_method (function, optional):
            If defined, the indices' keys will be the values at the
            specified paths in the output of ``prep_method`` applied
            to each member of ``forest``. The values of the indices
            will be the original members of ``forest``.

        key_method (function, optional):
            If defined,  each key ``K` that would appear as a key in
            the resulting indices will be replaced by the result of
            evaluating ``key_method(K)``.

        value_method (function, optional):
            If defined,  each value ``V`` that would appear in the
            list of values for any key in the resulting indices will
            be replaced by the result of evaluating
            ``value_method(V)``.

    Returns:

        (dict) A dictionary in which each value is an index of the
        structures in ``forest`` by the values of the elements
        selected by one ``path`` in ``paths``. The dictionary key for
        a given index value will be the "list-reduced dot separated"
        representation of ``path``. This is the string returned by
        the function call
        ``utensils.prune.dotpath(path, no_lists=True)``.


    The resulting structure will look like this::

        {
        path:
                {
                path_valueA: [tree1, tree2, ...],
                path_valueB: [...],
                ...
                },
            ...
            }

    Here, the path_valueX keys are the values that occur at path
    in any of the elements of forest, and the list for each key is
    exactly the elements of forest for which the path_valueX value
    occurs at path. Note that the values selected by a path in
    ``paths``, or the values returned by ``key_method()``, if defined,
    must be hashable, as they will be keys in an index.

    '''
    pruner = prune.Pruner(
        *[{'path': prune.dotpath(p)} for p in paths]
        )
    indices = {}
    # print [{'path': p} for p in paths]

    for tree in forest:

        prepped_tree = prep_method(tree) if prep_method else tree

        for (path, path_values) in pruner.prune_leaves(prepped_tree).items():

            if path not in indices:
                indices[path] = {}

            for index_key in list(set(
                    [key_method(v) if key_method else v for v in path_values]
                    )):  # pylint: disable=bad-continuation

                if index_key not in indices[path]:
                    indices[path][index_key] = []

                value = value_method(tree) if value_method else tree

                if value not in indices[path][index_key] or duplicates:
                    indices[path][index_key].append(value)

    return indices