def batch_get_aggregate_resource_config( self, aggregator_name, resource_identifiers ): """Returns the configuration of an item in the AWS Config format of the resource for the current regional backend. As far a moto goes -- the only real difference between this function and the `batch_get_resource_config` function is that this will require a Config Aggregator be set up a priori and can search based on resource regions. Note: moto will IGNORE the resource account ID in the search query. """ if not self.config_aggregators.get(aggregator_name): raise NoSuchConfigurationAggregatorException() # Can't have more than 100 items if len(resource_identifiers) > 100: raise TooManyResourceKeys( ["com.amazonaws.starling.dove.AggregateResourceIdentifier@12345"] * len(resource_identifiers) ) found = [] not_found = [] for identifier in resource_identifiers: resource_type = identifier["ResourceType"] resource_region = identifier["SourceRegion"] resource_id = identifier["ResourceId"] resource_name = identifier.get("ResourceName", None) # Does the resource type exist? if not RESOURCE_MAP.get(resource_type): not_found.append(identifier) continue # Get the item: item = RESOURCE_MAP[resource_type].get_config_resource( resource_id, resource_name=resource_name, resource_region=resource_region, ) if not item: not_found.append(identifier) continue item["accountId"] = DEFAULT_ACCOUNT_ID # The 'tags' field is not included in aggregate results for some reason... item.pop("tags", None) found.append(item) return { "BaseConfigurationItems": found, "UnprocessedResourceIdentifiers": not_found, }
def list_aggregate_discovered_resources(self, aggregator_name, resource_type, filters, limit, next_token): """This will query against the mocked AWS Config listing function that must exist for the resource backend. As far a moto goes -- the only real difference between this function and the `list_discovered_resources` function is that this will require a Config Aggregator be set up a priori and can search based on resource regions. :param aggregator_name: :param resource_type: :param filters: :param limit: :param next_token: :return: """ if not self.config_aggregators.get(aggregator_name): raise NoSuchConfigurationAggregatorException() identifiers = [] new_token = None filters = filters or {} limit = limit or DEFAULT_PAGE_SIZE if limit > DEFAULT_PAGE_SIZE: raise InvalidLimit(limit) # If the resource type exists and the backend region is implemented in moto, then # call upon the resource type's Config Query class to retrieve the list of resources that match the criteria: if RESOURCE_MAP.get(resource_type, {}): # We only care about a filter's Region, Resource Name, and Resource ID: resource_region = filters.get('Region') resource_id = [filters['ResourceId'] ] if filters.get('ResourceId') else None resource_name = filters.get('ResourceName') identifiers, new_token = \ RESOURCE_MAP[resource_type].list_config_service_resources(resource_id, resource_name, limit, next_token, resource_region=resource_region) result = { 'ResourceIdentifiers': [{ 'SourceAccountId': DEFAULT_ACCOUNT_ID, 'SourceRegion': identifier['region'], 'ResourceType': identifier['type'], 'ResourceId': identifier['id'], 'ResourceName': identifier['name'] } for identifier in identifiers] } if new_token: result['NextToken'] = new_token return result
def describe_configuration_aggregators(self, names, token, limit): limit = DEFAULT_PAGE_SIZE if not limit or limit < 0 else limit agg_list = [] result = {'ConfigurationAggregators': []} if names: for name in names: if not self.config_aggregators.get(name): raise NoSuchConfigurationAggregatorException( number=len(names)) agg_list.append(name) else: agg_list = list(self.config_aggregators.keys()) # Empty? if not agg_list: return result # Sort by name: sorted_aggregators = sorted(agg_list) # Get the start: if not token: start = 0 else: # Tokens for this moto feature are just the next names of the items in the list: if not self.config_aggregators.get(token): raise InvalidNextTokenException() start = sorted_aggregators.index(token) # Get the list of items to collect: agg_list = sorted_aggregators[start:(start + limit)] result['ConfigurationAggregators'] = [ self.config_aggregators[agg].to_dict() for agg in agg_list ] if len(sorted_aggregators) > (start + limit): result['NextToken'] = sorted_aggregators[start + limit] return result
def delete_configuration_aggregator(self, config_aggregator): if not self.config_aggregators.get(config_aggregator): raise NoSuchConfigurationAggregatorException() del self.config_aggregators[config_aggregator]
def list_aggregate_discovered_resources(self, aggregator_name, resource_type, filters, limit, next_token): """This will query against the mocked AWS Config listing function that must exist for the resource backend. As far a moto goes -- the only real difference between this function and the `list_discovered_resources` function is that this will require a Config Aggregator be set up a priori and can search based on resource regions. :param aggregator_name: :param resource_type: :param filters: :param limit: :param next_token: :return: """ if not self.config_aggregators.get(aggregator_name): raise NoSuchConfigurationAggregatorException() identifiers = [] new_token = None filters = filters or {} limit = limit or DEFAULT_PAGE_SIZE if limit > DEFAULT_PAGE_SIZE: raise InvalidLimitException(limit) # If the resource type exists and the backend region is implemented in moto, then # call upon the resource type's Config Query class to retrieve the list of resources that match the criteria: if RESOURCE_MAP.get(resource_type, {}): # We only care about a filter's Region, Resource Name, and Resource ID: resource_region = filters.get("Region") resource_id = [filters["ResourceId"] ] if filters.get("ResourceId") else None resource_name = filters.get("ResourceName") identifiers, new_token = RESOURCE_MAP[ resource_type].list_config_service_resources( resource_id, resource_name, limit, next_token, resource_region=resource_region, aggregator=self.config_aggregators.get( aggregator_name).__dict__, ) resource_identifiers = [] for identifier in identifiers: item = { "SourceAccountId": DEFAULT_ACCOUNT_ID, "SourceRegion": identifier["region"], "ResourceType": identifier["type"], "ResourceId": identifier["id"], } if identifier.get("name"): item["ResourceName"] = identifier["name"] resource_identifiers.append(item) result = {"ResourceIdentifiers": resource_identifiers} if new_token: result["NextToken"] = new_token return result