Beispiel #1
0
    def parse(self, data: Dict[str, Any],
              context: Dict[str, Any]) -> LinkCollection:
        """Parse this field and return a LinkCollection

       Args:
           data: dictionary of data to parse
           context: context dict containing data from higher level parsing code.

        Returns:
            LinkCollection
        """
        value = data.get(self.source_key)
        if value is None:
            if self.default_value is not None:
                return LinkCollection(simple_links=[
                    SimpleLink(pred=self.alti_key, obj=self.default_value)
                ], )
            if self.optional:
                return LinkCollection()
            raise ScalarFieldSourceKeyNotFoundException(
                f"Expected key '{self.source_key}' in data, present keys: {', '.join(data.keys())}"
            )
        if isinstance(value, SCALAR_TYPES):
            return LinkCollection(
                simple_links=[SimpleLink(pred=self.alti_key, obj=value)], )
        raise ScalarFieldValueNotAScalarException(
            (f"Expected data for key '{self.source_key}' to be one "
             f"of {SCALAR_TYPES}, is {type(value)}: {value}"))
    def parse(self, data: Dict[str, Any],
              context: Dict[str, Any]) -> LinkCollection:
        """Parse this field and return a LinkCollection.

        Args:
            data: data to parse
            context: contains data from higher level parsing code.

        Returns:
            LinkCollection
        """
        if isinstance(self._resource_spec_class, str):
            resource_spec_class: Type[
                ResourceSpec] = ResourceSpec.get_by_class_name(
                    self._resource_spec_class)
        else:
            resource_spec_class = self._resource_spec_class
        if not self.alti_key:
            self.alti_key = resource_spec_class.type_name
        short_resource_id = data.get(self.source_key)
        if not short_resource_id:
            if self.optional:
                return LinkCollection()
            raise ResourceLinkFieldSourceKeyNotFoundException(
                f"Expected key '{self.source_key}' with non-empty/zero value in {data}"
            )
        if self.value_is_id:
            resource_id = short_resource_id
        else:
            resource_id = resource_spec_class.generate_id(
                short_resource_id, context)
        return LinkCollection(transient_resource_links=[
            TransientResourceLink(pred=self.alti_key, obj=resource_id)
        ], )
    def parse(self, data: Dict[str, Any],
              context: Dict[str, Any]) -> LinkCollection:
        """Parse this field and return a LinkCollection

       Args:
           data: dictionary of data to parse
           context: context dict containing data from higher level parsing code.

        Returns:
            LinkCollection

        Raises:
            ListFieldSourceKeyNotFoundException if self.source_key is not in data.
            ListFieldValueNotAListException if the data does not appear to represent a list.
        """
        if self.source_key not in data:
            if self.optional:
                return LinkCollection()
            raise ListFieldSourceKeyNotFoundException(
                f"Expected key '{self.source_key}' in data, present keys: {', '.join(data.keys())}"
            )
        sub_datas = data.get(self.source_key, [])
        if not isinstance(sub_datas, list):
            if self.allow_scalar and isinstance(sub_datas, SCALAR_TYPES):
                sub_datas = [sub_datas]
            else:
                raise ListFieldValueNotAListException((
                    f"Key '{self.source_key}' value had unexpected type, value: {sub_datas} "
                    f"type: {type(sub_datas)}"))
        link_collection = LinkCollection()
        updated_context = deepcopy(context)
        updated_context.update({"parent_alti_key": self.alti_key})
        for sub_data in sub_datas:
            link_collection += self.sub_field.parse(sub_data, updated_context)
        return link_collection
Beispiel #4
0
 def test_graph_content(self):
     expected_resources = (
         Resource(
             resource_id="123",
             type="test:a",
             link_collection=LinkCollection(
                 simple_links=(SimpleLink(pred="has-foo", obj="goo"),),
             ),
         ),
         Resource(resource_id="456", type="test:a", link_collection=LinkCollection(),),
         Resource(
             resource_id="abc",
             type="test:b",
             link_collection=LinkCollection(
                 simple_links=(SimpleLink(pred="has-a", obj="123"),),
             ),
         ),
         Resource(
             resource_id="def",
             type="test:b",
             link_collection=LinkCollection(simple_links=(SimpleLink(pred="name", obj="sue"),),),
         ),
     )
     expected_errors = ["test err 1", "test err 2"]
     self.assertEqual(self.validated_graph_set.resources, expected_resources)
     self.assertEqual(self.validated_graph_set.errors, expected_errors)
    def test_scan(self):
        scan_accessor = TestScanAccessor()
        graph_spec = GraphSpec(
            name="test-name",
            version="1",
            resource_spec_classes=(TestResourceSpecA, TestResourceSpecB),
            scan_accessor=scan_accessor,
        )
        resources = graph_spec.scan()

        expected_resources = [
            Resource(resource_id="123",
                     type="a",
                     link_collection=LinkCollection()),
            Resource(resource_id="456",
                     type="a",
                     link_collection=LinkCollection()),
            Resource(resource_id="abc",
                     type="b",
                     link_collection=LinkCollection()),
            Resource(resource_id="def",
                     type="b",
                     link_collection=LinkCollection()),
        ]
        self.assertEqual(resources, expected_resources)
    def parse(self, data: Dict[str, Any],
              context: Dict[str, Any]) -> LinkCollection:
        """Parse this field and return a LinkCollection.

        Args:
            data: dictionary of data to parse
            context: context dict containing data from higher level parsing code.

        Returns:
            LinkCollection

        Raises:
            DictFieldSourceKeyNotFoundException if self.source_key is not in data.
            DictFieldValueNotADictException if the data does not appear to represent a dict.
        """
        parent_alti_key = self.get_parent_alti_key(data, context)
        if not isinstance(data, dict):
            raise Exception(f"{type(data)} {data} was expected to be a dict.")
        updated_context = deepcopy(context)
        updated_context.update({"parent_alti_key": parent_alti_key})
        multi_link_object_link_collection = LinkCollection()
        for field in self.fields:
            multi_link_object_link_collection += field.parse(data, context)
        return LinkCollection(multi_links=[
            MultiLink(pred=parent_alti_key,
                      obj=multi_link_object_link_collection)
        ])
    def test_valid_dicts_input_with_alti_key(self):
        input_str = '{"People": [{"Name": "Bob", "Age": 49}, {"Name": "Sue", "Age": 42}]}'
        field = ListField(
            "People", EmbeddedDictField(ScalarField("Name"), ScalarField("Age")), alti_key="person"
        )

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(
            multi_links=(
                MultiLink(
                    pred="person",
                    obj=LinkCollection(
                        simple_links=(
                            SimpleLink(pred="name", obj="Bob"),
                            SimpleLink(pred="age", obj=49),
                        ),
                    ),
                ),
                MultiLink(
                    pred="person",
                    obj=LinkCollection(
                        simple_links=(
                            SimpleLink(pred="name", obj="Sue"),
                            SimpleLink(pred="age", obj=42),
                        ),
                    ),
                ),
            ),
        )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #8
0
 def setUp(self):
     resource_a1 = Resource(
         resource_id="123",
         type="test:a",
         link_collection=LinkCollection(simple_links=[SimpleLink(pred="has-foo", obj="goo")]),
     )
     resource_a2 = Resource(resource_id="456", type="test:a", link_collection=LinkCollection(),)
     resource_b1 = Resource(
         resource_id="abc",
         type="test:b",
         link_collection=LinkCollection(simple_links=[SimpleLink(pred="has-a", obj="123")]),
     )
     resource_b2 = Resource(
         resource_id="def",
         type="test:b",
         link_collection=LinkCollection(simple_links=[SimpleLink(pred="name", obj="sue")]),
     )
     resources = (resource_a1, resource_a2, resource_b1, resource_b2)
     self.validated_graph_set = ValidatedGraphSet(
         name="test-name",
         version="1",
         start_time=1234,
         end_time=4567,
         resources=resources,
         errors=["test err 1", "test err 2"],
     )
 def scan(cls: Type["TestResourceSpecB"],
          scan_accessor: Any) -> List[Resource]:
     resources = [
         Resource(resource_id="abc",
                  type=cls.type_name,
                  link_collection=LinkCollection()),
         Resource(resource_id="def",
                  type=cls.type_name,
                  link_collection=LinkCollection()),
     ]
     return resources
Beispiel #10
0
    def test_scan(self):
        account_id = "123456789012"
        region_name = "us-east-1"

        session = boto3.Session()

        ec2_client = session.client("ec2", region_name=region_name)
        list_resp = ec2_client.describe_vpcs()
        present_vpcs = list_resp["Vpcs"]
        self.assertEqual(len(present_vpcs), 1)
        present_vpc_id = present_vpcs[0]["VpcId"]
        present_vpc_arn = f"arn:aws:ec2:us-east-1:123456789012:vpc/{present_vpc_id}"

        create_resp = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")
        created_vpc_id = create_resp["Vpc"]["VpcId"]
        created_vpc_arn = f"arn:aws:ec2:us-east-1:123456789012:vpc/{created_vpc_id}"

        scan_accessor = AWSAccessor(session=session, account_id=account_id, region_name=region_name)
        resources = VPCResourceSpec.scan(scan_accessor=scan_accessor)

        expected_resources = [
            Resource(
                resource_id=present_vpc_arn,
                type="aws:ec2:vpc",
                link_collection=LinkCollection(
                    simple_links=(
                        SimpleLink(pred="is_default", obj=True),
                        SimpleLink(pred="cidr_block", obj="172.31.0.0/16"),
                        SimpleLink(pred="state", obj="available"),
                    ),
                    resource_links=(
                        ResourceLink(pred="account", obj="arn:aws::::account/123456789012"),
                        ResourceLink(pred="region", obj="arn:aws:::123456789012:region/us-east-1"),
                    ),
                ),
            ),
            Resource(
                resource_id=created_vpc_arn,
                type="aws:ec2:vpc",
                link_collection=LinkCollection(
                    simple_links=(
                        SimpleLink(pred="is_default", obj=False),
                        SimpleLink(pred="cidr_block", obj="10.0.0.0/16"),
                        SimpleLink(pred="state", obj="available"),
                    ),
                    resource_links=(
                        ResourceLink(pred="account", obj="arn:aws::::account/123456789012"),
                        ResourceLink(pred="region", obj="arn:aws:::123456789012:region/us-east-1"),
                    ),
                ),
            ),
        ]
        self.assertEqual(resources, expected_resources)
    def test_optional(self):
        input_str = '{"Biota": {"Plants": ["tree", "fern"]}}'
        field = DictField(
            "Biota", AnonymousListField("Animals", EmbeddedScalarField(), optional=True)
        )

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(
            multi_links=(MultiLink(pred="biota", obj=LinkCollection()),),
        )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #12
0
 def test_unknown_type_name(self):
     resources = [
         Resource(resource_id="xyz", type="test:a", link_collection=LinkCollection()),
         Resource(resource_id="xyz", type="test:c", link_collection=LinkCollection()),
     ]
     with self.assertRaises(ResourceSpecClassNotFoundException):
         ValidatedGraphSet(
             name="test-name",
             version="1",
             start_time=1234,
             end_time=4567,
             resources=resources,
             errors=[],
         )
Beispiel #13
0
 def test_invalid_resources_dupes_same_class_conflicting_types_no_allow_clobber(self):
     resources = [
         Resource(resource_id="123", type="test:a", link_collection=LinkCollection()),
         Resource(resource_id="123", type="test:b", link_collection=LinkCollection()),
     ]
     with self.assertRaises(UnmergableDuplicateResourceIdsFoundException):
         ValidatedGraphSet(
             name="test-name",
             version="1",
             start_time=1234,
             end_time=4567,
             resources=resources,
             errors=[],
         )
Beispiel #14
0
    def testToJson(self):
        pred = "test-multi-pred"
        obj = LinkCollection(simple_links=(
            SimpleLink(pred="test-simple-pred-1", obj="test-simple-obj-1"),
            SimpleLink(pred="test-simple-pred-1", obj="test-simple-obj-2"),
            SimpleLink(pred="test-simple-pred-2", obj="test-simple-obj-3"),
        ), )
        link = MultiLink(pred=pred, obj=obj)
        link_dict = link.dict(exclude_unset=True)

        expected_link_dict = {
            "pred": "test-multi-pred",
            "obj": {
                "simple_links": (
                    {
                        "pred": "test-simple-pred-1",
                        "obj": "test-simple-obj-1"
                    },
                    {
                        "pred": "test-simple-pred-1",
                        "obj": "test-simple-obj-2"
                    },
                    {
                        "pred": "test-simple-pred-2",
                        "obj": "test-simple-obj-3"
                    },
                ),
            },
        }
        self.assertDictEqual(expected_link_dict, link_dict)
    def parse(self, data: str, context: Dict[str, Any]) -> LinkCollection:
        """Parse this field and return a LinkCollection.

        Args:
            data: data to parse
            context: contains data from higher level parsing code.

        Returns:
            LinkCollection
        """
        if isinstance(self._resource_spec_class, str):
            resource_spec_class: Type[
                ResourceSpec] = ResourceSpec.get_by_class_name(
                    self._resource_spec_class)
        else:
            resource_spec_class = self._resource_spec_class
        if not self.alti_key:
            self.alti_key = resource_spec_class.type_name

        short_resource_id = data
        if self.value_is_id:
            resource_id = short_resource_id
        else:
            resource_id = resource_spec_class.generate_id(
                short_resource_id, context)
        return LinkCollection(
            resource_links=[ResourceLink(pred=self.alti_key,
                                         obj=resource_id)], )
Beispiel #16
0
 def testToRdf(self):
     pred = "test-multi-pred"
     obj = LinkCollection(simple_links=(
         SimpleLink(pred="test-simple-pred-1", obj="test-simple-obj-1"),
         SimpleLink(pred="test-simple-pred-2", obj="test-simple-obj-2"),
         SimpleLink(pred="test-simple-pred-3", obj="test-simple-obj-3"),
     ), )
     link = MultiLink(pred=pred, obj=obj)
     bnode = BNode()
     graph = Graph()
     namespace = Namespace("test:")
     node_cache = NodeCache()
     link.to_rdf(subj=bnode,
                 namespace=namespace,
                 graph=graph,
                 node_cache=node_cache)
     results = graph.query(
         "select ?p ?o where {?s a <test:test-multi-pred> ; ?p ?o} order by ?p ?o"
     )
     result_tuples = []
     for result in results:
         self.assertEqual(2, len(result))
         result_tuples.append((str(result[0]), str(result[1])))
     expected_result_tuples = [
         ("http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
          "test:test-multi-pred"),
         ("test:test-simple-pred-1", "test-simple-obj-1"),
         ("test:test-simple-pred-2", "test-simple-obj-2"),
         ("test:test-simple-pred-3", "test-simple-obj-3"),
     ]
     self.assertEqual(result_tuples, expected_result_tuples)
    def test_allow_scalar(self):
        input_str = '{"Biota": {"Plants": "tree"}}'
        field = DictField(
            "Biota", AnonymousListField("Plants", EmbeddedScalarField(), allow_scalar=True)
        )
        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(
            multi_links=(
                MultiLink(
                    pred="biota",
                    obj=LinkCollection(simple_links=(SimpleLink(pred="biota", obj="tree"),),),
                ),
            )
        )
        self.assertEqual(expected_link_collection, link_collection)
    def test_optional(self):
        input_str = '{"NoTagsHere": []}'
        field = TagsField(optional=True)

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        self.assertCountEqual(link_collection, LinkCollection())
    def test_optional(self):
        input_str = "{}"
        field = ListField("People", EmbeddedScalarField(), alti_key="person", optional=True)

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        self.assertEqual(link_collection, LinkCollection())
Beispiel #20
0
    def test_key_absent_with_optional(self):
        input_str = "{}"
        field = ScalarField("FieldName", optional=True)

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        self.assertEqual(link_collection, LinkCollection())
 def test_parse(self):
     schema = Schema(ScalarField("Key1"), ScalarField("Key2"))
     data = {"Key1": "Value1", "Key2": "Value2"}
     link_collection = schema.parse(data, {})
     expected_link_collection = LinkCollection(simple_links=(
         SimpleLink(pred="key1", obj="Value1"),
         SimpleLink(pred="key2", obj="Value2"),
     ))
     self.assertEqual(link_collection, expected_link_collection)
    def test_valid_dicts_input(self):
        input_str = (
            '{"Biota": {"People": [{"Name": "Bob", "Age": 49}, {"Name": "Sue", "Age": 42}]}}'
        )
        field = DictField(
            "Biota",
            AnonymousListField(
                "People", EmbeddedDictField(ScalarField("Name"), ScalarField("Age"))
            ),
        )

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(
            multi_links=(
                MultiLink(
                    pred="biota",
                    obj=LinkCollection(
                        multi_links=(
                            MultiLink(
                                pred="biota",
                                obj=LinkCollection(
                                    simple_links=(
                                        SimpleLink(pred="name", obj="Bob"),
                                        SimpleLink(pred="age", obj=49),
                                    ),
                                ),
                            ),
                            MultiLink(
                                pred="biota",
                                obj=LinkCollection(
                                    simple_links=(
                                        SimpleLink(pred="name", obj="Sue"),
                                        SimpleLink(pred="age", obj=42),
                                    ),
                                ),
                            ),
                        ),
                    ),
                ),
            )
        )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #23
0
    def test_valid_input_with_alti_key(self):
        input_str = '{"FieldName": "Value"}'
        field = ScalarField("FieldName", alti_key="alti_field_name")

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(simple_links=(SimpleLink(
            pred="alti_field_name", obj="Value"), ), )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #24
0
    def test_key_absent_with_default(self):
        input_str = "{}"
        field = ScalarField("FieldName", default_value="DefaultValue")

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(simple_links=(SimpleLink(
            pred="field_name", obj="DefaultValue"), ), )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #25
0
    def test_key_present_with_optional(self):
        input_str = '{"FieldName": "Value"}'
        field = ScalarField("FieldName", optional=True)

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(simple_links=(SimpleLink(
            pred="field_name", obj="Value"), ), )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #26
0
    def test_scan(self):
        account_id = "123456789012"
        region_name = "us-east-1"
        session = boto3.Session()
        client = session.client("iam")

        oidc_url = "https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
        oidc_client_ids = ["sts.amazonaws.com"]
        oidc_thumbprints = ["9999999999999999999999999999999999999999"]

        _ = client.create_open_id_connect_provider(
            Url=oidc_url,
            ClientIDList=oidc_client_ids,
            ThumbprintList=oidc_thumbprints,
        )

        scan_accessor = AWSAccessor(session=session,
                                    account_id=account_id,
                                    region_name=region_name)
        resources = IAMOIDCProviderResourceSpec.scan(
            scan_accessor=scan_accessor)

        expected_resources = [
            Resource(
                resource_id=
                "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E",
                type="aws:iam:oidc-provider",
                link_collection=LinkCollection(
                    simple_links=(
                        SimpleLink(
                            pred="url",
                            obj=
                            "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E",
                        ),
                        SimpleLink(
                            pred="create_date",
                            obj=resources[0].link_collection.simple_links[1].
                            obj,
                        ),
                        SimpleLink(pred="client_id", obj="sts.amazonaws.com"),
                        SimpleLink(
                            pred="thumbprint",
                            obj="9999999999999999999999999999999999999999"),
                    ),
                    multi_links=None,
                    tag_links=None,
                    resource_links=(ResourceLink(
                        pred="account",
                        obj="arn:aws::::account/123456789012"), ),
                    transient_resource_links=None,
                ),
            )
        ]

        self.assertEqual(resources, expected_resources)
Beispiel #27
0
    def test_valid_input(self):
        input_data = "foo"
        parent_alti_key = "parent_alti_key"
        field = EmbeddedScalarField()

        link_collection = field.parse(
            data=input_data, context={"parent_alti_key": parent_alti_key})

        expected_link_collection = LinkCollection(simple_links=(SimpleLink(
            pred="parent_alti_key", obj="foo"), ), )
        self.assertEqual(link_collection, expected_link_collection)
    def test_allow_scalar(self):
        input_str = '{"People": "bob"}'
        field = ListField("People", EmbeddedScalarField(), alti_key="person", allow_scalar=True)

        input_data = json.loads(input_str)
        link_collection = field.parse(data=input_data, context={})

        expected_link_collection = LinkCollection(
            simple_links=(SimpleLink(pred="person", obj="bob"),),
        )
        self.assertEqual(link_collection, expected_link_collection)
Beispiel #29
0
 def test_orphaned_ref(self):
     resource_a1 = Resource(
         resource_id="123",
         type="test:a",
         link_collection=LinkCollection(simple_links=[SimpleLink(pred="has-foo", obj="goo")]),
     )
     resource_b1 = Resource(
         resource_id="abc",
         type="test:b",
         link_collection=LinkCollection(resource_links=[ResourceLink(pred="has-a", obj="456")]),
     )
     resources = [resource_a1, resource_b1]
     graph_set = GraphSet(
         name="test-name",
         version="1",
         start_time=1234,
         end_time=4567,
         resources=resources,
         errors=["test err 1", "test err 2"],
     )
     with self.assertRaises(GraphSetOrphanedReferencesException):
         ValidatedGraphSet.from_graph_set(graph_set)
    def parse(self, data: Dict[str, Any],
              context: Dict[str, Any]) -> LinkCollection:
        """Parse this field and return a list of Links.

       Args:
           data: dictionary of data to parse
           context: context dict containing data from higher level parsing code.

        Returns:
            List of TagLink objects, one for each tag.
        """
        links: List[TagLink] = []
        tag_dicts = data.get("Tags")
        if tag_dicts:
            for tag_dict in tag_dicts:
                links.append(
                    TagLink(pred=tag_dict["Key"], obj=tag_dict["Value"]))
            return LinkCollection(tag_links=links)
        if self.optional:
            return LinkCollection()
        raise TagsFieldMissingTagsKeyException(
            f"Expected key 'Tags' in {data}")