Ejemplo n.º 1
0
    def _set_operator_specified_filters(self, operator):
        """Set any filters using AND instead of OR."""
        filters = QueryFilterCollection()
        composed_filter = Q()
        for filter_key in self.SUPPORTED_FILTERS:
            operator_key = operator + ":" + filter_key
            filter_value = self.parameters.get_filter(operator_key)
            logical_operator = operator
            if filter_value and len(filter_value) < 2:
                logical_operator = "or"
            if filter_value and not OrgQueryHandler.has_wildcard(filter_value):
                filter_obj = self.FILTER_MAP.get(filter_key)
                if isinstance(filter_obj, list):
                    for _filt in filter_obj:
                        filt_filters = QueryFilterCollection()
                        for item in filter_value:
                            q_filter = QueryFilter(parameter=item, logical_operator=logical_operator, **_filt)
                            filt_filters.add(q_filter)
                        composed_filter = composed_filter | filt_filters.compose()
                else:
                    for item in filter_value:
                        q_filter = QueryFilter(parameter=item, logical_operator=logical_operator, **filter_obj)
                        filters.add(q_filter)
        if filters:
            composed_filter = composed_filter & filters.compose()

        return composed_filter
Ejemplo n.º 2
0
 def test_set_access_filters_with_list(self):
     """Test that the execute query runs properly with value query and an RBAC restriction on cluster."""
     key = "app"
     value = "b"
     url = f"/app/?filter[value]={value}"
     query_params = self.mocked_query_params(url, OCPTagView)
     # the mocked query parameters dont include the key from the url so it needs to be added
     query_params.kwargs = {"key": key}
     handler = OCPTagQueryHandler(query_params)
     access = ["my-ocp-cluster-2"]
     filt = [
         {
             "field": "report_period__cluster_id",
             "operation": "icontains",
             "composition_key": "cluster_filter"
         },
         {
             "field": "report_period__cluster_alias",
             "operation": "icontains",
             "composition_key": "cluster_filter"
         },
     ]
     filters = QueryFilterCollection()
     handler.set_access_filters(access, filt, filters)
     expected = []
     expected.append(
         QueryFilter(field="report_period__cluster_id",
                     operation="icontains",
                     parameter=["my-ocp-cluster-2"]))
     expected.append(
         QueryFilter(field="report_period__cluster_alias",
                     operation="icontains",
                     parameter=["my-ocp-cluster-2"]))
     self.assertEqual(filters._filters, expected)
Ejemplo n.º 3
0
    def test_set_operator_specified_tag_filters_or(self):
        """Test that AND/OR terms are correctly applied to tag filters."""
        operator = "or"

        term = self.mock_tag_key
        first = FAKE.word()
        second = FAKE.word()
        operation = "icontains"

        url = (
            f"?filter[time_scope_value]=-1&"
            f"filter[or:tag:{term}]={first}&"
            f"filter[or:tag:{term}]={second}&"
            f"group_by[or:tag:{term}]={first}&"
            f"group_by[or:tag:{term}]={second}"
        )
        params = self.mocked_query_params(url, self.mock_view)
        mapper = {"filter": [{}], "filters": {term: {"field": term, "operation": operation}}}
        rqh = create_test_handler(params, mapper=mapper)
        output = rqh._set_operator_specified_tag_filters(QueryFilterCollection(), operator)
        self.assertIsNotNone(output)

        expected = QueryFilterCollection(
            filters=[
                QueryFilter(field=term, operation=operation, parameter=second, logical_operator=operator),
                QueryFilter(field=term, operation=operation, parameter=first, logical_operator=operator),
            ]
        )
        self.assertIsInstance(output, QueryFilterCollection)
        assertSameQ(output.compose(), expected.compose())
Ejemplo n.º 4
0
 def _set_tag_filters(self, filters):
     """Create tag_filters."""
     tag_column = self._mapper.tag_column
     tag_filters = self.get_tag_filter_keys()
     tag_group_by = self.get_tag_group_by_keys()
     tag_filters.extend(tag_group_by)
     tag_filters = [
         tag for tag in tag_filters
         if 'and:' not in tag and 'or:' not in tag
     ]
     for tag in tag_filters:
         # Update the filter to use the label column name
         tag_db_name = tag_column + '__' + strip_tag_prefix(tag)
         filt = {'field': tag_db_name, 'operation': 'icontains'}
         group_by = self.parameters.get_group_by(tag, list())
         filter_ = self.parameters.get_filter(tag, list())
         list_ = list(set(group_by + filter_))  # uniquify the list
         if list_ and not ReportQueryHandler.has_wildcard(list_):
             for item in list_:
                 q_filter = QueryFilter(parameter=item, **filt)
                 filters.add(q_filter)
         elif list_ and ReportQueryHandler.has_wildcard(list_):
             wild_card_filt = {'field': tag_column, 'operation': 'has_key'}
             q_filter = QueryFilter(parameter=strip_tag_prefix(tag),
                                    **wild_card_filt)
             filters.add(q_filter)
     return filters
Ejemplo n.º 5
0
 def test_set_access_filter_with_list(self):
     """
     Tests that when an access restriction, filters, and a filter list are passed in,
     the correct query filters are added
     """
     # create the elements needed to mock the query handler
     term = self.mock_tag_key
     operation = "icontains"
     params = self.mocked_query_params("", self.mock_view)
     mapper = {"filter": [{}], "filters": {term: {"field": term, "operation": operation}}}
     rqh = create_test_handler(params, mapper=mapper)
     # set filters and access to be used in function
     filters = QueryFilterCollection()
     access = ["589173575009"]
     filt = [
         {"field": "account_alias__account_alias", "operation": "icontains", "composition_key": "account_filter"},
         {"field": "usage_account_id", "operation": "icontains", "composition_key": "account_filter"},
     ]
     expected = QueryFilterCollection(
         filters=[
             QueryFilter(field="account_alias__account_alias", operation="in", composition_key="account_filter"),
             QueryFilter(field="usage_account_id", operation="in", composition_key="account_filter"),
         ]
     )
     rqh._set_access_filters(access, filt, filters)
     self.assertIsInstance(filters, QueryFilterCollection)
     assertSameQ(filters.compose(), expected.compose())
Ejemplo n.º 6
0
    def test_execute_query_current_month_filter_service(self):
        """Test execute_query for current month on monthly filtered by service."""
        self.generator = OCPAzureReportDataGenerator(self.tenant, self.provider, current_month_only=True)
        self.generator.add_data_to_tenant(
            fixed_fields=["subscription_guid", "resource_location", "tags", "service_name"]
        )

        service = self.generator.config.service_name
        url = f"?filter[time_scope_units]=month&filter[time_scope_value]=-1&filter[resolution]=monthly&filter[service_name]={service}"  # noqa: E501
        query_params = self.mocked_query_params(url, OCPAzureCostView)
        handler = OCPAzureReportQueryHandler(query_params)
        query_output = handler.execute_query()

        data = query_output.get("data")
        self.assertIsNotNone(data)
        self.assertIsNotNone(query_output.get("total"))

        total = query_output.get("total")
        aggregates = handler._mapper.report_type_map.get("aggregates")
        filters = {**self.this_month_filter, "service_name__icontains": service}
        for filt in handler._mapper.report_type_map.get("filter"):
            if filt:
                qf = QueryFilter(**filt)
                filters.update({qf.composed_query_string(): qf.parameter})
        current_totals = self.get_totals_by_time_scope(aggregates, filters)
        self.assertIsNotNone(total.get("cost"))
        self.assertEqual(total.get("cost", {}).get("value", 0), current_totals.get("cost", 1))

        cmonth_str = self.dh.this_month_start.strftime("%Y-%m")
        for data_item in data:
            month_val = data_item.get("date", "not-a-date")
            month_data = data_item.get("values")
            self.assertEqual(month_val, cmonth_str)
            self.assertIsInstance(month_data, list)
Ejemplo n.º 7
0
 def _get_sub_ou_list(self, data, org_ids):
     """Get a list of the sub org units for a org unit."""
     level = data.get("level")
     level = level + 1
     unit_path = data.get("org_unit_path")
     final_sub_ou_list = []
     with tenant_context(self.tenant):
         for source in self.data_sources:
             # Grab columns for this query
             account_info = source.get("account_alias_column")
             level_column = source.get("level_column")
             org_path = source.get("org_path_column")
             # Build filters
             filters = QueryFilterCollection()
             no_accounts = QueryFilter(field=f"{account_info}", operation="isnull", parameter=True)
             filters.add(no_accounts)
             exact_parent_id = QueryFilter(field=f"{level_column}", operation="exact", parameter=level)
             filters.add(exact_parent_id)
             path_on_like = QueryFilter(field=f"{org_path}", operation="icontains", parameter=unit_path)
             filters.add(path_on_like)
             composed_filters = filters.compose()
             # Start quering
             sub_org_query = source.get("db_table").objects
             sub_org_query = sub_org_query.filter(composed_filters)
             sub_org_query = sub_org_query.filter(id__in=org_ids)
             sub_ou_list = sub_org_query.values_list("org_unit_id", flat=True)
             final_sub_ou_list.extend(sub_ou_list)
     return final_sub_ou_list
Ejemplo n.º 8
0
    def _get_filter(self, delta=False):
        """Create dictionary for filter parameters.

        Args:
            delta (Boolean): Construct timeframe for delta
        Returns:
            (Dict): query filter dictionary

        """
        filters = QueryFilterCollection()

        # add time constraint filters
        if delta:
            date_delta = self._get_date_delta()
            start = self.start_datetime - date_delta
            end = self.end_datetime - date_delta
        else:
            start = self.start_datetime
            end = self.end_datetime

        start_filter = QueryFilter(field='usage_start__date',
                                   operation='gte',
                                   parameter=start)
        end_filter = QueryFilter(field='usage_end__date',
                                 operation='lte',
                                 parameter=end)
        filters.add(query_filter=start_filter)
        filters.add(query_filter=end_filter)

        return filters
Ejemplo n.º 9
0
    def test_execute_query_by_filtered_cluster(self):
        """Test execute_query monthly breakdown by filtered cluster."""
        self.generator.add_data_to_tenant()

        cluster = self.generator.cluster_id
        url = f"?filter[time_scope_units]=month&filter[time_scope_value]=-1&filter[resolution]=monthly&group_by[cluster]={cluster}"  # noqa: E501
        query_params = self.mocked_query_params(url, OCPAzureCostView)
        handler = OCPAzureReportQueryHandler(query_params)
        query_output = handler.execute_query()
        data = query_output.get("data")
        self.assertIsNotNone(data)
        self.assertIsNotNone(query_output.get("total"))
        total = query_output.get("total")
        aggregates = handler._mapper.report_type_map.get("aggregates")
        filters = {**self.this_month_filter, "cluster_id__icontains": cluster}
        for filt in handler._mapper.report_type_map.get("filter"):
            if filt:
                qf = QueryFilter(**filt)
                filters.update({qf.composed_query_string(): qf.parameter})
        current_totals = self.get_totals_by_time_scope(aggregates, filters)
        self.assertIsNotNone(total.get("cost"))
        self.assertEqual(total.get("cost", {}).get("value", 0), current_totals.get("cost", 1))

        cmonth_str = self.dh.this_month_start.strftime("%Y-%m")
        for data_item in data:
            month_val = data_item.get("date", "not-a-date")
            month_data = data_item.get("clusters")
            self.assertEqual(month_val, cmonth_str)
            self.assertIsInstance(month_data, list)
            for month_item in month_data:
                self.assertIsInstance(month_item.get("cluster"), str)
                self.assertIsInstance(month_item.get("values"), list)
                self.assertIsNotNone(month_item.get("values")[0].get("cost"))
Ejemplo n.º 10
0
 def _get_time_based_filters(self, delta=False):
     """Overridden from QueryHandler."""
     start_filter = QueryFilter(field='usage_start', operation='gte',
                                parameter=self.start_datetime)
     end_filter = QueryFilter(field='usage_start', operation='lte',
                              parameter=self.end_datetime)
     return start_filter, end_filter
Ejemplo n.º 11
0
    def _get_search_filter(self, filters):
        """Populate the query filter collection for search filters.

        Args:
            filters (QueryFilterCollection): collection of query filters
        Returns:
            (QueryFilterCollection): populated collection of query filters
        """
        # define filter parameters using API query params.
        fields = self._mapper._provider_map.get('filters')
        for q_param, filt in fields.items():
            group_by = self.get_query_param_data('group_by', q_param, list())
            filter_ = self.get_query_param_data('filter', q_param, list())
            list_ = list(set(group_by + filter_))    # uniquify the list
            if list_ and not ReportQueryHandler.has_wildcard(list_):
                if isinstance(filt, list):
                    for _filt in filt:
                        for item in list_:
                            q_filter = QueryFilter(parameter=item, **_filt)
                            filters.add(q_filter)
                else:
                    for item in list_:
                        q_filter = QueryFilter(parameter=item, **filt)
                        filters.add(q_filter)

        # Update filters with tag filters
        filters = self._set_tag_filters(filters)

        composed_filters = filters.compose()
        LOG.debug(f'_get_search_filter: {composed_filters}')
        return composed_filters
Ejemplo n.º 12
0
 def test_set_access_filter_with_list(self):
     """
     Tests that when an access restriction, filters, and a filter list are passed in,
     the correct query filters are added
     """
     # create the elements needed to mock the query handler
     params = self.mocked_query_params("", AWSCostForecastView)
     instance = AWSForecast(params)
     # set filters and access to be used in function
     filters = QueryFilterCollection()
     access = ["589173575009"]
     filt = [
         {
             "field": "account_alias__account_alias",
             "operation": "icontains",
             "composition_key": "account_filter"
         },
         {
             "field": "usage_account_id",
             "operation": "icontains",
             "composition_key": "account_filter"
         },
     ]
     expected = QueryFilterCollection(filters=[
         QueryFilter(field="account_alias__account_alias",
                     operation="in",
                     composition_key="account_filter"),
         QueryFilter(field="usage_account_id",
                     operation="in",
                     composition_key="account_filter"),
     ])
     instance.set_access_filters(access, filt, filters)
     self.assertIsInstance(filters, QueryFilterCollection)
     assertSameQ(filters.compose(), expected.compose())
Ejemplo n.º 13
0
    def _get_filter(self, delta=False):
        """Create dictionary for filter parameters.

        Args:
            delta (Boolean): Construct timeframe for delta
        Returns:
            (Dict): query filter dictionary

        """
        filters = super()._get_filter(delta)

        for filter_key in SUPPORTED_FILTERS:
            filter_value = self.get_query_param_data('filter', filter_key)
            if filter_value and not TagQueryHandler.has_wildcard(filter_value):
                filter_obj = FILTER_MAP.get(filter_key)
                if isinstance(filter_obj, list):
                    for _filt in filter_obj:
                        for item in filter_value:
                            q_filter = QueryFilter(parameter=item, **_filt)
                            filters.add(q_filter)
                else:
                    for item in filter_value:
                        q_filter = QueryFilter(parameter=item, **filter_obj)
                        filters.add(q_filter)

        # Update filters that specifiy and or or in the query parameter
        and_composed_filters = self._set_operator_specified_filters('and')
        or_composed_filters = self._set_operator_specified_filters('or')

        composed_filters = filters.compose()
        composed_filters = composed_filters & and_composed_filters & or_composed_filters

        LOG.debug(f'_get_filter: {composed_filters}')
        return composed_filters
Ejemplo n.º 14
0
 def test_composed_string_table_op(self):
     """Test composed_query_string() method using table and operation parameters."""
     table = self.fake.word()
     operation = self.fake.word()
     filt = QueryFilter(table=table, operation=operation)
     expected = f'{table}__{operation}'
     self.assertEqual(filt.composed_query_string(), expected)
Ejemplo n.º 15
0
 def test_composed_string_all(self):
     """Test composed_query_string() method using all parameters."""
     table = self.fake.word()
     field = self.fake.word()
     operation = self.fake.word()
     parameter = self.fake.word()
     filt = QueryFilter(table, field, operation, parameter)
     expected = f'{table}__{field}__{operation}'
     self.assertEqual(filt.composed_query_string(), expected)
Ejemplo n.º 16
0
    def _set_operator_specified_filters(self, operator):
        """Set any filters using AND instead of OR."""
        fields = self._mapper._provider_map.get("filters")
        filters = QueryFilterCollection()
        composed_filter = Q()

        for q_param, filt in fields.items():
            q_param = operator + ":" + q_param
            group_by = self.parameters.get_group_by(q_param, list())
            filter_ = self.parameters.get_filter(q_param, list())
            list_ = list(set(group_by + filter_))  # uniquify the list
            logical_operator = operator
            # This is a flexibilty feature allowing a user to set
            # a single and: value and still get a result instead
            # of erroring on validation
            if len(list_) < 2:
                logical_operator = "or"
            if list_ and not ReportQueryHandler.has_wildcard(list_):
                if isinstance(filt, list):
                    for _filt in filt:
                        filt_filters = QueryFilterCollection()
                        for item in list_:
                            q_filter = QueryFilter(
                                parameter=item,
                                logical_operator=logical_operator,
                                **_filt)
                            filt_filters.add(q_filter)
                        # List filter are a complex mix of and/or logic
                        # Each filter in the list must be ORed together
                        # regardless of the operator on the item in the filter
                        # Ex:
                        # (OR:
                        #     (AND:
                        #         ('cluster_alias__icontains', 'ni'),
                        #         ('cluster_alias__icontains', 'se')
                        #     ),
                        #     (AND:
                        #         ('cluster_id__icontains', 'ni'),
                        #         ('cluster_id__icontains', 'se')
                        #     )
                        # )
                        composed_filter = composed_filter | filt_filters.compose(
                        )
                else:
                    list_ = self._build_custom_filter_list(
                        q_param, filt.get("custom"), list_)
                    for item in list_:
                        q_filter = QueryFilter(
                            parameter=item,
                            logical_operator=logical_operator,
                            **filt)
                        filters.add(q_filter)
        if filters:
            composed_filter = composed_filter & filters.compose()
        return composed_filter
Ejemplo n.º 17
0
 def test_composed_dict_field(self):
     """Test composed_dict() method without a Table parameter."""
     field = self.fake.word()
     operation = self.fake.word()
     parameter = self.fake.word()
     filt = QueryFilter(field=field,
                        operation=operation,
                        parameter=parameter)
     expected_dict = {f'{field}__{operation}': parameter}
     expected = Q(**expected_dict)
     self.assertEqual(filt.composed_Q(), expected)
Ejemplo n.º 18
0
 def test_contains_fail(self):
     """Test the __contains__() method fails with a non-matching filter."""
     qf1 = QueryFilter(table=self.fake.word(),
                       field=self.fake.word(),
                       parameter=self.fake.word())
     qf2 = QueryFilter(table=self.fake.word(),
                       field=self.fake.word(),
                       parameter=self.fake.word())
     qf_coll = QueryFilterCollection([qf1])
     self.assertNotIn(qf2, qf_coll)
     self.assertFalse(qf2 in qf_coll)
Ejemplo n.º 19
0
    def test_iterable(self):
        """Test the __iter__() method returns an iterable."""
        qf1 = QueryFilter(table=self.fake.word(),
                          field=self.fake.word(),
                          parameter=self.fake.word())
        qf2 = QueryFilter(table=self.fake.word(),
                          field=self.fake.word(),
                          parameter=self.fake.word())
        qf_coll = QueryFilterCollection([qf1, qf2])

        self.assertIsInstance(qf_coll.__iter__(), Iterable)
Ejemplo n.º 20
0
    def test_composed_dict_all(self):
        """Test composed_dict() method with all parameters."""
        table = self.fake.word()
        field = self.fake.word()
        operation = self.fake.word()
        parameter = self.fake.word()

        filt = QueryFilter(table, field, operation, parameter)
        expected_dict = {f'{table}__{field}__{operation}': parameter}
        expected = Q(**expected_dict)
        self.assertEqual(filt.composed_Q(), expected)
Ejemplo n.º 21
0
    def test_from_string_two_parts(self):
        """Test from_string() method with two parts."""
        table = self.fake.word()
        operation = self.fake.word()
        SEP = QueryFilter.SEP
        test_string = table + SEP + operation
        filt = QueryFilter().from_string(test_string)

        self.assertEqual(filt.table, table)
        self.assertEqual(filt.operation, operation)
        self.assertEqual(filt.composed_query_string(), test_string)
Ejemplo n.º 22
0
    def _get_time_based_filters(self, delta=False):
        if delta:
            date_delta = self._get_date_delta()
            start = self.start_datetime - date_delta
            end = self.end_datetime - date_delta
        else:
            start = self.start_datetime
            end = self.end_datetime

        start_filter = QueryFilter(field="usage_start", operation="gte", parameter=start.date())
        end_filter = QueryFilter(field="usage_end", operation="lte", parameter=end.date())
        return start_filter, end_filter
Ejemplo n.º 23
0
    def test_delete_filter(self):
        """Test the delete() method works with QueryFilters."""
        qf1 = QueryFilter(table=self.fake.word(),
                          field=self.fake.word(),
                          parameter=self.fake.word())
        qf2 = QueryFilter(table=self.fake.word(),
                          field=self.fake.word(),
                          parameter=self.fake.word())
        qf_coll = QueryFilterCollection([qf1, qf2])

        qf_coll.delete(qf1)
        self.assertEqual([qf2], qf_coll._filters)
        self.assertNotIn(qf1, qf_coll)
Ejemplo n.º 24
0
    def _get_search_filter(self, filters):
        """Populate the query filter collection for search filters.

        Args:
            filters (QueryFilterCollection): collection of query filters
        Returns:
            (QueryFilterCollection): populated collection of query filters

        """
        # define filter parameters using API query params.
        fields = self._mapper._provider_map.get("filters")
        access_filters = QueryFilterCollection()
        for q_param, filt in fields.items():
            access = self.parameters.get_access(q_param, list())
            group_by = self.parameters.get_group_by(q_param, list())
            filter_ = self.parameters.get_filter(q_param, list())
            list_ = list(set(group_by + filter_))  # uniquify the list
            if list_ and not ReportQueryHandler.has_wildcard(list_):
                if isinstance(filt, list):
                    for _filt in filt:
                        for item in list_:
                            q_filter = QueryFilter(parameter=item, **_filt)
                            filters.add(q_filter)
                else:
                    list_ = self._build_custom_filter_list(
                        q_param, filt.get("custom"), list_)
                    for item in list_:
                        q_filter = QueryFilter(parameter=item, **filt)
                        filters.add(q_filter)
            if access:
                access_filt = copy.deepcopy(filt)
                self.set_access_filters(access, access_filt, access_filters)

        # Update filters with tag filters
        filters = self._set_tag_filters(filters)
        filters = self._set_operator_specified_tag_filters(filters, "and")
        filters = self._set_operator_specified_tag_filters(filters, "or")

        # Update filters that specifiy and or or in the query parameter
        and_composed_filters = self._set_operator_specified_filters("and")
        or_composed_filters = self._set_operator_specified_filters("or")
        multi_field_or_composed_filters = self._set_or_filters()
        composed_filters = filters.compose()
        composed_filters = composed_filters & and_composed_filters & or_composed_filters
        if access_filters:
            composed_access_filters = access_filters.compose()
            composed_filters = composed_filters & composed_access_filters
        if multi_field_or_composed_filters:
            composed_filters = composed_filters & multi_field_or_composed_filters
        LOG.debug(f"_get_search_filter: {composed_filters}")
        return composed_filters
Ejemplo n.º 25
0
    def test_indexing(self):
        """Test that __getitem__() allows array slicing."""
        qf1 = QueryFilter(table=self.fake.word(),
                          field=self.fake.word(),
                          parameter=self.fake.word())
        qf2 = QueryFilter(table=self.fake.word(),
                          field=self.fake.word(),
                          parameter=self.fake.word())
        qf_coll = QueryFilterCollection([qf1, qf2])

        self.assertEqual(qf_coll[0], qf1)
        self.assertEqual(qf_coll[1], qf2)
        self.assertEqual(qf_coll[-1], qf2)
        self.assertEqual(qf_coll[-2], qf1)
Ejemplo n.º 26
0
    def _get_time_based_filters(self, delta=False):
        if delta:
            date_delta = self._get_date_delta()
            start = self.start_datetime - date_delta
            end = self.end_datetime - date_delta
        else:
            start = self.start_datetime
            end = self.end_datetime

        start_filter = QueryFilter(field='usage_start__date', operation='gte',
                                   parameter=start)
        end_filter = QueryFilter(field='usage_end__date', operation='lte',
                                 parameter=end)
        return start_filter, end_filter
Ejemplo n.º 27
0
    def _get_filter(self, delta=False):  # noqa: C901
        """Create dictionary for filter parameters.

        Args:
            delta (Boolean): Construct timeframe for delta
        Returns:
            (Dict): query filter dictionary

        """
        filters = QueryFilterCollection()
        if not self.parameters.get_filter("value"):
            for source in self.data_sources:
                start_filter, end_filter = self._get_time_based_filters(
                    source, delta)
                filters.add(query_filter=start_filter)
                filters.add(query_filter=end_filter)

        for filter_key in self.SUPPORTED_FILTERS:
            if self.parameters.get_filter("value") and filter_key == "enabled":
                continue
            filter_value = self.parameters.get_filter(filter_key)
            if filter_value and not TagQueryHandler.has_wildcard(filter_value):
                filter_obj = self.FILTER_MAP.get(filter_key)
                if isinstance(filter_value, bool):
                    filters.add(QueryFilter(**filter_obj))
                elif isinstance(filter_obj, list):
                    for _filt in filter_obj:
                        for item in filter_value:
                            q_filter = QueryFilter(parameter=item, **_filt)
                            filters.add(q_filter)
                else:
                    for item in filter_value:
                        q_filter = QueryFilter(parameter=item, **filter_obj)
                        filters.add(q_filter)
            access = self.parameters.get_access(filter_key)
            filt = self.FILTER_MAP.get(filter_key, [])
            if access and filt:
                filt = self.FILTER_MAP.get(filter_key)
                q_filter = QueryFilter(parameter=access, **filt)
                filters.add(q_filter)

        # Update filters that specifiy and or or in the query parameter
        and_composed_filters = self._set_operator_specified_filters("and")
        or_composed_filters = self._set_operator_specified_filters("or")

        composed_filters = filters.compose()
        composed_filters = composed_filters & and_composed_filters & or_composed_filters

        LOG.debug(f"_get_filter: {composed_filters}")
        return composed_filters
Ejemplo n.º 28
0
    def set_access_filters(self, access, filt, filters):
        """
        Sets the access filters to ensure RBAC restrictions given the users access,
        the current filter and the filter collection
        Args:
            access (list) the list containing the users relevant access
            filt (list or dict) contains the filters that need
            filters (QueryFilterCollection) the filter collection to add the new filters to
        returns:
            None
        """
        for _filt in filt if isinstance(filt, list) else [filt]:
            check_field_type = None
            try:
                if hasattr(self, "query_table"):
                    # Reports APIs
                    check_field_type = self.query_table._meta.get_field(
                        _filt.get("field", "")).get_internal_type()
                elif hasattr(self, "data_sources"):
                    # Tags APIs
                    check_field_type = (
                        self.data_sources[0].get("db_table")._meta.get_field(
                            _filt.get("field", "")).get_internal_type())
            except FieldDoesNotExist:
                pass

            _filt[
                "operation"] = "contains" if check_field_type == "ArrayField" else "in"
            q_filter = QueryFilter(parameter=access, **_filt)
            filters.add(q_filter)
Ejemplo n.º 29
0
 def _create_accounts_mapping(self):
     """Returns a mapping of org ids to accounts."""
     account_mapping = {}
     with tenant_context(self.tenant):
         for source in self.data_sources:
             # Grab columns for this query
             account_info = source.get("account_alias_column")
             # Create filters & Query
             filters = QueryFilterCollection()
             no_org_units = QueryFilter(field=f"{account_info}", operation="isnull", parameter=False)
             filters.add(no_org_units)
             composed_filters = filters.compose()
             account_query = source.get("db_table").objects
             account_query = account_query.filter(composed_filters)
             account_query = account_query.exclude(deleted_timestamp__lte=self.start_datetime)
             account_query = account_query.exclude(created_timestamp__gt=self.end_datetime)
             if self.access:
                 accounts_to_filter = self.access.get("aws.account", {}).get("read", [])
                 if accounts_to_filter and "*" not in accounts_to_filter:
                     account_query = account_query.filter(account_alias__account_id__in=accounts_to_filter)
             account_query = account_query.order_by(f"{account_info}", "-created_timestamp")
             account_query = account_query.distinct(f"{account_info}")
             account_query = account_query.annotate(
                 alias=Coalesce(F(f"{account_info}__account_alias"), F(f"{account_info}__account_id"))
             )
             for account in account_query:
                 org_id = account.org_unit_id
                 alias = account.alias
                 if account_mapping.get(org_id):
                     account_list = account_mapping[org_id]
                     account_list.append(alias)
                     account_mapping[org_id] = account_list
                 else:
                     account_mapping[org_id] = [alias]
     return account_mapping
Ejemplo n.º 30
0
    def _get_filter(self, delta=False):  # noqa: C901
        """Create dictionary for filter parameters.

        Args:
            delta (Boolean): Construct timeframe for delta
        Returns:
            (Dict): query filter dictionary

        """
        filters = QueryFilterCollection()

        for filter_key in self.SUPPORTED_FILTERS:
            filter_value = self.parameters.get_filter(filter_key)
            if filter_value and not OrgQueryHandler.has_wildcard(filter_value):
                filter_obj = self.FILTER_MAP.get(filter_key)
                for item in filter_value:
                    q_filter = QueryFilter(parameter=item, **filter_obj)
                    filters.add(q_filter)

        # Update filters that specifiy and or or in the query parameter
        and_composed_filters = self._set_operator_specified_filters("and")
        or_composed_filters = self._set_operator_specified_filters("or")
        composed_filters = filters.compose()
        filter_list = [composed_filters, and_composed_filters, or_composed_filters]
        final_filters = None
        for filter_option in filter_list:
            if filter_option:
                if final_filters is not None:
                    final_filters & filter_option
                else:
                    final_filters = filter_option

        LOG.debug(f"_get_filter: {final_filters}")
        return final_filters