示例#1
0
def dedupe_resources(resources: Iterable[Resource]) -> Tuple[Resource, ...]:
    """Resolve any duplicate resource ids.  In general duplicate resource ids can
    have their Resource objects merged if they are of the same type and all fields
    are identical or additive only across the resources or if one of the Resources
    allows a special merge via its ResourceSpec class' `allow_clobber` attribute."""
    resource_ids_resources: DefaultDict[str,
                                        List[Resource]] = defaultdict(list)
    for resource in resources:
        resource_ids_resources[resource.resource_id].append(resource)
    merged_resources: List[Resource] = []
    for resource_id, candidate_resources in resource_ids_resources.items():
        if len(candidate_resources) > 1:
            merged_resource = ResourceSpec.merge_resources(
                resource_id=resource_id, resources=candidate_resources)
            merged_resources.append(merged_resource)
    for merged_resource in merged_resources:
        resource_ids_resources[merged_resource.resource_id] = [merged_resource]
    # at this point all values in resource_ids_resources should be single-value lists.
    # validate that and build a list of deduped_resources from those single-values
    deduped_resources = []
    for resource_id, resource_list in resource_ids_resources.items():
        if len(resource_list) != 1:
            raise Exception(
                f"More than one resource found for {resource_id}: {resource_list}"
            )
        deduped_resources.append(resource_list[0])
    return tuple(deduped_resources)
    def test(self):
        account_id = "012345678901"
        errors = ["foo", "boo"]
        unscanned_account_resource = UnscannedAccountResourceSpec.create_resource(
            account_id=account_id, errors=errors)
        resource = ResourceSpec.merge_resources("foo",
                                                [unscanned_account_resource])

        self.assertEqual(resource.resource_id, "foo")
        self.assertEqual(resource.type, "aws:unscanned-account")
        self.assertEqual(len(resource.link_collection.simple_links), 2)
        self.assertEqual(
            resource.link_collection.simple_links[0],
            SimpleLink(pred="account_id", obj="012345678901"),
        )
        self.assertEqual(resource.link_collection.simple_links[1].pred,
                         "error")
        self.assertTrue(
            resource.link_collection.simple_links[1].obj.startswith(
                "foo\nboo - "))
示例#3
0
    def test(self):
        account_id = "012345678901"
        errors = ["foo", "boo"]
        unscanned_account_resource = UnscannedAccountResourceSpec.create_resource(
            account_id=account_id, errors=errors)
        resource = ResourceSpec.merge_resources("foo",
                                                [unscanned_account_resource])

        resource_dict = resource.to_dict()
        self.assertEqual(resource_dict["type"], "aws:unscanned-account")
        self.assertEqual(len(resource_dict["links"]), 2)
        self.assertEqual(resource_dict["links"][0], {
            'pred': 'account_id',
            'obj': '012345678901',
            'type': 'simple'
        })
        self.assertEqual(resource_dict["links"][1]["pred"], "error")
        self.assertEqual(resource_dict["links"][1]["type"], "simple")
        self.assertTrue(
            resource_dict["links"][1]["obj"].startswith("foo\nboo - "))
示例#4
0
 def _resolve_duplicates(self) -> None:
     """Resolve any duplicate resource ids.  In general duplicate resource ids can
     have their Resource objects merged if they are of the same type and all fields
     are identical or additive only across the resources or if one of the Resources
     allows a special merge via its ResourceSpec class' `allow_clobber` attribute."""
     resource_ids_resources: DefaultDict[str,
                                         List[Resource]] = defaultdict(list)
     for resource in self.resources:
         resource_ids_resources[resource.resource_id].append(resource)
     merged_resources: List[Resource] = []
     for resource_id, resources in resource_ids_resources.items():
         if len(resources) > 1:
             merged_resource = ResourceSpec.merge_resources(
                 resource_id=resource_id, resources=resources)
             merged_resources.append(merged_resource)
     for merged_resource in merged_resources:
         self.resources = [
             resource for resource in self.resources
             if resource.resource_id != merged_resource.resource_id
         ]
         self.resources.append(merged_resource)