def check_references_from_others(self, rpsl_obj: RPSLObject) -> ValidatorResult: """ Check for any references to this object in the DB. Used for validating deletions. Checks self._preload_deleted, because a reference from an object that is also about to be deleted, is acceptable. """ result = ValidatorResult() if not rpsl_obj.references_strong_inbound(): return result query = RPSLDatabaseQuery().sources([rpsl_obj.source()]) query = query.lookup_attrs_in(rpsl_obj.references_strong_inbound(), [rpsl_obj.pk()]) query_results = self.database_handler.execute_query(query) for query_result in query_results: reference_to_be_deleted = ( query_result['object_class'], query_result['rpsl_pk'], query_result['source']) in self._preloaded_deleted if not reference_to_be_deleted: result.error_messages.add( f'Object {rpsl_obj.pk()} to be deleted, but still referenced ' f'by {query_result["object_class"]} {query_result["rpsl_pk"]}' ) return result
def resolve_rpsl_objects(_, info: GraphQLResolveInfo, **kwargs): """ Resolve a `rpslObjects` query. This query has a considerable number of parameters, each of which is applied to an RPSL database query. """ low_specificity_kwargs = { 'object_class', 'rpki_status', 'scope_filter_status', 'sources', 'sql_trace' } # A query is sufficiently specific if it has other fields than listed above, # except that rpki_status is sufficient if it is exclusively selecting on # valid or invalid. low_specificity = all([ not (set(kwargs.keys()) - low_specificity_kwargs), kwargs.get('rpki_status', []) not in [[RPKIStatus.valid], [RPKIStatus.invalid]], ]) if low_specificity: raise ValueError('Your query must be more specific.') if kwargs.get('sql_trace'): info.context['sql_trace'] = True query = RPSLDatabaseQuery( column_names=_columns_for_graphql_selection(info), ordered_by_sources=False, enable_ordering=False) if 'record_limit' in kwargs: query.limit(kwargs['record_limit']) if 'rpsl_pk' in kwargs: query.rpsl_pks(kwargs['rpsl_pk']) if 'object_class' in kwargs: query.object_classes(kwargs['object_class']) if 'asn' in kwargs: query.asns_first(kwargs['asn']) if 'text_search' in kwargs: query.text_search(kwargs['text_search']) if 'rpki_status' in kwargs: query.rpki_status(kwargs['rpki_status']) else: query.rpki_status([RPKIStatus.not_found, RPKIStatus.valid]) if 'scope_filter_status' in kwargs: query.scopefilter_status(kwargs['scope_filter_status']) else: query.scopefilter_status([ScopeFilterStatus.in_scope]) all_valid_sources = set(get_setting('sources', {}).keys()) if get_setting('rpki.roa_source'): all_valid_sources.add(RPKI_IRR_PSEUDO_SOURCE) sources_default = set(get_setting('sources_default', [])) if 'sources' in kwargs: query.sources(kwargs['sources']) elif sources_default and sources_default != all_valid_sources: query.sources(list(sources_default)) # All other parameters are generic lookup fields, like `members` for attr, value in kwargs.items(): attr = attr.replace('_', '-') if attr in lookup_fields: query.lookup_attrs_in([attr], value) ip_filters = [ 'ip_exact', 'ip_less_specific', 'ip_more_specific', 'ip_less_specific_one_level', 'ip_any' ] for ip_filter in ip_filters: if ip_filter in kwargs: getattr(query, ip_filter)(IP(kwargs[ip_filter])) return _rpsl_db_query_to_graphql_out(query, info)