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())
Beispiel #2
0
    def test_optional(self):
        input_str = '{"NoTagsHere": []}'
        field = TagsField(optional=True)
        expected_output_data = []

        input_data = json.loads(input_str)
        links = field.parse(data=input_data, context={})
        output_data = [link.to_dict() for link in links]
        self.assertCountEqual(output_data, expected_output_data)
Beispiel #3
0
    def test_invalid_input(self):
        input_str = (
            '{"Mags": [{"Key": "tag1", "Value": "value1"}, {"Key": "tag2", "Value": "value2"}]}'
        )
        field = TagsField(optional=False)

        input_data = json.loads(input_str)
        with self.assertRaises(TagsFieldMissingTagsKeyException):
            field.parse(data=input_data, context={})
Beispiel #4
0
    def test_valid_input(self):
        input_str = (
            '{"Tags": [{"Key": "tag1", "Value": "value1"}, {"Key": "tag2", "Value": "value2"}]}'
        )
        field = TagsField()
        expected_output_data = [
            {"pred": "tag1", "obj": "value1", "type": "tag"},
            {"pred": "tag2", "obj": "value2", "type": "tag"},
        ]

        input_data = json.loads(input_str)
        links = field.parse(data=input_data, context={})
        output_data = [link.to_dict() for link in links]
        self.assertCountEqual(output_data, expected_output_data)
Beispiel #5
0
class VpcEndpointResourceSpec(EC2ResourceSpec):
    """Resource for VPC Endpoints"""

    type_name = "vpc-endpoint"
    schema = Schema(
        ScalarField("VpcEndpointType"),
        ScalarField("ServiceName"),
        ScalarField("State"),
        ResourceLinkField("VpcId", VPCResourceSpec),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["VpcEndpointResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'vpc_endpoint_1_arn': {vpc_endpoint_1_dict},
             'vpc_endpoint_1_arn': {vpc_endpoint_2_dict},
             ...}

        Where the dicts represent results from describe_vpc_endpoints."""
        endpoints = {}
        paginator = client.get_paginator("describe_vpc_endpoints")
        for resp in paginator.paginate():
            for endpoint in resp.get("VpcEndpoints", []):
                resource_arn = cls.generate_arn(account_id, region, endpoint["VpcEndpointId"])
                endpoints[resource_arn] = endpoint
        return ListFromAWSResult(resources=endpoints)
Beispiel #6
0
class SubnetResourceSpec(EC2ResourceSpec):
    """Resource for Subnets"""

    type_name = "subnet"
    schema = Schema(
        ScalarField("CidrBlock"),
        ScalarField("FirstIp"),
        ScalarField("LastIp"),
        ScalarField("State"),
        TagsField(),
        ResourceLinkField("VpcId", VPCResourceSpec),
    )

    @classmethod
    def list_from_aws(
        cls: Type["SubnetResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        subnets = {}
        resp = client.describe_subnets()
        for subnet in resp.get("Subnets", []):
            resource_arn = cls.generate_arn(
                account_id=account_id, region=region, resource_id=subnet["SubnetId"]
            )
            cidr = subnet["CidrBlock"]
            ipv4_network = ipaddress.IPv4Network(cidr, strict=False)
            first_ip, last_ip = int(ipv4_network[0]), int(ipv4_network[-1])
            subnet["FirstIp"] = first_ip
            subnet["LastIp"] = last_ip
            subnets[resource_arn] = subnet
        return ListFromAWSResult(resources=subnets)
class VPCResourceSpec(EC2ResourceSpec):
    """Resource for VPCs"""

    type_name = "vpc"
    schema = Schema(ScalarField("IsDefault"), ScalarField("CidrBlock"),
                    ScalarField("State"), TagsField())

    @classmethod
    def list_from_aws(cls: Type["VPCResourceSpec"], client: BaseClient,
                      account_id: str, region: str) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'vpc_1_arn': {vpc_1_dict},
             'vpc_2_arn': {vpc_2_dict},
             ...}

        Where the dicts represent results from describe_vpcs."""
        vpcs = {}
        paginator = client.get_paginator("describe_vpcs")
        for resp in paginator.paginate():
            for vpc in resp.get("Vpcs", []):
                resource_arn = cls.generate_arn(account_id=account_id,
                                                region=region,
                                                resource_id=vpc["VpcId"])
                vpcs[resource_arn] = vpc
        return ListFromAWSResult(resources=vpcs)
class EBSSnapshotResourceSpec(EC2ResourceSpec):
    """Resource for EBSSnapshots"""

    type_name = "snapshot"
    schema = Schema(
        ScalarField("VolumeSize"),
        ScalarField("Encrypted"),
        TransientResourceLinkField("KmsKeyId",
                                   KMSKeyResourceSpec,
                                   optional=True,
                                   value_is_id=True),
        TransientResourceLinkField("VolumeId", EBSVolumeResourceSpec),
        TagsField(),
    )

    @classmethod
    def list_from_aws(cls: Type["EBSSnapshotResourceSpec"], client: BaseClient,
                      account_id: str, region: str) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'snapshot_1_arn': {snapshot_1_dict},
             'snapshot_2_arn': {snapshot_2_dict},
             ...}

        Where the dicts represent results from describe_snapshots."""
        snapshots = {}
        paginator = client.get_paginator("describe_snapshots")
        for resp in paginator.paginate(OwnerIds=["self"]):
            for snapshot in resp.get("Snapshots", []):
                resource_arn = cls.generate_arn(
                    account_id=account_id,
                    region=region,
                    resource_id=snapshot["SnapshotId"])
                snapshots[resource_arn] = snapshot
        return ListFromAWSResult(resources=snapshots)
Beispiel #9
0
class EC2ImageResourceSpec(EC2ResourceSpec):
    """Resource for EC2Images (AMIs)"""

    type_name = "image"
    schema = Schema(
        ScalarField("Name", optional=True),
        ScalarField("Description", optional=True),
        ScalarField("Public"),
        TagsField(),
    )

    @classmethod
    def list_from_aws(cls: Type["EC2ImageResourceSpec"], client: BaseClient,
                      account_id: str, region: str) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'image_1_arn': {image_1_dict},
             'image_2_arn': {image_2_dict},
             ...}

        Where the dicts represent results from describe_images."""
        images = {}
        resp = client.describe_images(Owners=["self"])
        for image in resp["Images"]:
            image_id = image["ImageId"]
            resource_arn = cls.generate_arn(account_id=account_id,
                                            region=region,
                                            resource_id=image_id)
            images[resource_arn] = image
        return ListFromAWSResult(resources=images)
Beispiel #10
0
class EC2InstanceResourceSpec(EC2ResourceSpec):
    """Resource for EC2Instances"""

    type_name = "instance"
    schema = Schema(
        ScalarField("Name", optional=True),
        TransientResourceLinkField("ImageId", EC2ImageResourceSpec),
        ScalarField("KeyName", optional=True),
        AnonymousDictField("Placement", ScalarField("AvailabilityZone"), ScalarField("Tenancy")),
        ScalarField("InstanceType"),
        ScalarField("LaunchTime"),
        AnonymousDictField("State", ScalarField("Name", "state")),
        ScalarField("Platform", optional=True),
        ScalarField("PrivateIpAddress", optional=True),
        ScalarField("PrivateDnsName", optional=True),
        ScalarField("PublicIpAddress", optional=True),
        ScalarField("PublicDnsName", optional=True),
        ResourceLinkField("VpcId", VPCResourceSpec, optional=True),
        ResourceLinkField("SubnetId", SubnetResourceSpec, optional=True),
        AnonymousListField(
            "SecurityGroups",
            AnonymousEmbeddedDictField(ResourceLinkField("GroupId", SecurityGroupResourceSpec)),
        ),
        AnonymousDictField(
            "IamInstanceProfile",
            TransientResourceLinkField(
                "Arn", InstanceProfileResourceSpec, alti_key="instance_profile", value_is_id=True
            ),
            optional=True,
        ),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["EC2InstanceResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'instance_1_arn': {instance_1_dict},
             'instance_2_arn': {instance_2_dict},
             ...}

        Where the dicts represent results from describe_instances."""
        paginator = client.get_paginator("describe_instances")
        instances = {}
        for resp in paginator.paginate():
            for reservation in resp.get("Reservations", []):
                for instance in reservation.get("Instances", []):
                    resource_arn = cls.generate_arn(
                        account_id=account_id, region=region, resource_id=instance["InstanceId"]
                    )
                    instances[resource_arn] = instance
                    for tag in instance.get("Tags", []):
                        if tag["Key"].lower() == "name":
                            instance["Name"] = tag["Value"]
                            break
        return ListFromAWSResult(resources=instances)
class TransitGatewayResourceSpec(EC2ResourceSpec):
    """Resource for TransitGateways"""

    # type_name = "transit-gateway"
    type_name = "transit_gateway"
    schema = Schema(
        ScalarField("OwnerId"),
        ScalarField("State"),
        ListField(
            "VPCAttachments",
            EmbeddedDictField(
                ScalarField("CreationTime"),
                ScalarField("State"),
                ResourceLinkField("ResourceId", VPCResourceSpec),
            ),
            optional=True,
            alti_key="vpc_attachment",
        ),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["TransitGatewayResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'tgw_1_arn': {tgw_1_dict},
             'tgw_2_arn': {tgw_2_dict},
             ...}

        Where the dicts represent results from describe_transit_gateways."""
        tgws = {}
        paginator = client.get_paginator("describe_transit_gateways")
        tgw_filters = [{"Name": "owner-id", "Values": [account_id]}]
        for resp in paginator.paginate(Filters=tgw_filters):
            for tgw in resp["TransitGateways"]:
                resource_arn = tgw["TransitGatewayArn"]
                vpc_attachments: List[Dict[str, Any]] = []
                vpc_attachments_paginator = client.get_paginator(
                    "describe_transit_gateway_attachments"
                )
                vpc_filters = [
                    {"Name": "transit-gateway-id", "Values": [tgw["TransitGatewayId"]]},
                    {"Name": "resource-type", "Values": ["vpc"]},
                ]
                for vpc_attachments_resp in vpc_attachments_paginator.paginate(Filters=vpc_filters):
                    vpc_attachments += vpc_attachments_resp["TransitGatewayAttachments"]
                tgw["VPCAttachments"] = vpc_attachments
                tgws[resource_arn] = tgw
        return ListFromAWSResult(resources=tgws)
    def test_valid_input(self):
        input_str = (
            '{"Tags": [{"Key": "tag1", "Value": "value1"}, {"Key": "tag2", "Value": "value2"}]}'
        )
        field = TagsField()
        expected_output_data = [
            {
                "pred": "tag1",
                "obj": "value1",
                "type": "tag"
            },
            {
                "pred": "tag2",
                "obj": "value2",
                "type": "tag"
            },
        ]

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

        expected_link_collection = LinkCollection(tag_links=(TagLink(
            pred="tag1", obj="value1"), TagLink(pred="tag2", obj="value2")), )
        self.assertEqual(link_collection, expected_link_collection)
class EBSVolumeResourceSpec(EC2ResourceSpec):
    """Resource for EBSVolumes"""

    type_name = "volume"
    schema = Schema(
        ScalarField("AvailabilityZone"),
        ScalarField("CreateTime"),
        ScalarField("Size"),
        ScalarField("State"),
        ScalarField("VolumeType"),
        ScalarField("Encrypted"),
        ListField(
            "Attachments",
            EmbeddedDictField(
                ScalarField("AttachTime"),
                ScalarField("State"),
                ScalarField("DeleteOnTermination"),
                ResourceLinkField("InstanceId", EC2InstanceResourceSpec),
            ),
            optional=True,
            alti_key="attachment",
        ),
        TransientResourceLinkField("KmsKeyId",
                                   KMSKeyResourceSpec,
                                   optional=True,
                                   value_is_id=True),
        TagsField(),
    )

    @classmethod
    def list_from_aws(cls: Type["EBSVolumeResourceSpec"], client: BaseClient,
                      account_id: str, region: str) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'volume_1_arn': {volume_1_dict},
             'volume_2_arn': {volume_2_dict},
             ...}

        Where the dicts represent results from describe_volumes."""
        volumes = {}
        paginator = client.get_paginator("describe_volumes")
        for resp in paginator.paginate():
            for volume in resp.get("Volumes", []):
                resource_arn = cls.generate_arn(account_id=account_id,
                                                region=region,
                                                resource_id=volume["VolumeId"])
                volumes[resource_arn] = volume
        return ListFromAWSResult(resources=volumes)
class InternetGatewayResourceSpec(EC2ResourceSpec):
    """Resource for InternetGateways"""

    # type_name = "internet-gateway"
    type_name = "internet_gateway"
    schema = Schema(
        ScalarField("OwnerId"),
        ListField(
            "Attachments",
            EmbeddedDictField(
                ScalarField("State"),
                ResourceLinkField("VpcId", VPCResourceSpec),
            ),
            optional=True,
            alti_key="attachment",
        ),
        TagsField(),
    )

    @classmethod
    def list_from_aws(cls: Type["InternetGatewayResourceSpec"],
                      client: BaseClient, account_id: str,
                      region: str) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'igw_1_arn': {igw_1_dict},
             'igw_2_arn': {igw_2_dict},
             ...}

        Where the dicts represent results from describe_internet_gateways."""
        igws = {}
        paginator = client.get_paginator("describe_internet_gateways")
        for resp in paginator.paginate():
            for igw in resp["InternetGateways"]:
                resource_arn = cls.generate_arn(
                    resource_id=igw["InternetGatewayId"],
                    account_id=account_id,
                    region=region)
                igws[resource_arn] = igw
        return ListFromAWSResult(resources=igws)
Beispiel #15
0
class VpcEndpointServiceResourceSpec(EC2ResourceSpec):
    """Resource for VPC Endpoint Services"""

    # type_name = "vpc-endpoint-service"
    type_name = "vpc_endpoint_service"
    schema = Schema(
        AnonymousListField("ServiceType", ScalarField("ServiceType")),
        ScalarField("ServiceName"),
        ScalarField("ServiceState"),
        ScalarField("AcceptanceRequired"),
        ListField("AvailabilityZones", EmbeddedScalarField()),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["VpcEndpointServiceResourceSpec"],
        client: BaseClient,
        account_id: str,
        region: str,
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'vpc_endpoint_svc_1_arn': {vpc_endpoint_svc_1_dict},
             'vpc_endpoint_svc_2_arn': {vpc_endpoint_svc_2_dict},
             ...}

        Where the dicts represent results from describe_vpc_endpoint_service_configurations."""
        services = {}
        paginator = client.get_paginator(
            "describe_vpc_endpoint_service_configurations")
        for resp in paginator.paginate():
            for service in resp.get("ServiceConfigurations", []):
                resource_arn = cls.generate_arn(
                    account_id=account_id,
                    region=region,
                    resource_id=service["ServiceId"])
                services[resource_arn] = service
        return ListFromAWSResult(resources=services)
Beispiel #16
0
class RDSInstanceResourceSpec(RDSResourceSpec):
    """Resource for RDS"""

    type_name = "db"
    schema = Schema(
        TagsField(),
        ScalarField("DBInstanceIdentifier"),
        ScalarField("DBInstanceClass"),
        ScalarField("Engine"),
        ScalarField("DBInstanceStatus"),
        ScalarField("DBName", optional=True),
        AnonymousDictField(
            "Endpoint",
            ScalarField("Address", alti_key="endpoint_address", optional=True),
            ScalarField("Port", alti_key="endpoint_port"),
            ScalarField("HostedZoneId",
                        alti_key="endpoint_hosted_zone",
                        optional=True),
            optional=True,
        ),
        AnonymousDictField(
            "ListenerEndpoint",
            ScalarField("Address", alti_key="listener_address"),
            ScalarField("Port", alti_key="listener_port"),
            ScalarField("HostedZoneId",
                        alti_key="listener_hosted_zone",
                        optional=True),
            optional=True,
        ),
        ScalarField("InstanceCreateTime", optional=True),
        ScalarField("BackupRetentionPeriod"),
        AnonymousListField(
            "VpcSecurityGroups",
            AnonymousEmbeddedDictField(
                TransientResourceLinkField("VpcSecurityGroupId",
                                           SecurityGroupResourceSpec,
                                           optional=True)),
        ),
        ScalarField("AvailabilityZone", optional=True),
        AnonymousDictField("DBSubnetGroup",
                           TransientResourceLinkField("VpcId",
                                                      VPCResourceSpec),
                           optional=True),
        ScalarField("MultiAZ"),
        ScalarField("PubliclyAccessible"),
        ListField("StatusInfos",
                  EmbeddedDictField(ScalarField("Status")),
                  optional=True),
        ScalarField("StorageType"),
        ScalarField("StorageEncrypted"),
        TransientResourceLinkField("KmsKeyId",
                                   KMSKeyResourceSpec,
                                   optional=True,
                                   value_is_id=True),
        ScalarField("DbiResourceId"),
        ScalarField("Timezone", optional=True),
        ScalarField("IAMDatabaseAuthenticationEnabled"),
        ScalarField("PerformanceInsightsEnabled", optional=True),
        ScalarField("PerformanceInsightsRetentionPeriod", optional=True),
        ScalarField("DeletionProtection"),
        ListField(
            "Backup",
            EmbeddedDictField(
                AnonymousDictField(
                    "RestoreWindow",
                    ScalarField("EarliestTime",
                                alti_key="earliest_restore_time",
                                optional=True),
                    optional=True,
                ),
                AnonymousDictField(
                    "RestoreWindow",
                    ScalarField("LatestTime",
                                alti_key="latest_restore_time",
                                optional=True),
                    optional=True,
                ),
                ScalarField("AllocatedStorage"),
                ScalarField("Status"),
                ScalarField("AvailabilityZone", optional=True),
                ScalarField("Engine"),
                ScalarField("EngineVersion"),
                ScalarField("Encrypted"),
                ScalarField("StorageType"),
                TransientResourceLinkField("KmsKeyId",
                                           KMSKeyResourceSpec,
                                           optional=True,
                                           value_is_id=True),
            ),
            optional=True,
        ),
    )

    @classmethod
    def list_from_aws(cls: Type["RDSInstanceResourceSpec"], client: BaseClient,
                      account_id: str, region: str) -> ListFromAWSResult:
        logger = Logger()
        dbinstances = {}
        paginator = client.get_paginator("describe_db_instances")
        for resp in paginator.paginate():
            for db in resp.get("DBInstances", []):
                resource_arn = db["DBInstanceArn"]
                db["Tags"] = client.list_tags_for_resource(
                    ResourceName=resource_arn).get("TagList", [])
                db["Backup"] = []
                dbinstances[resource_arn] = db

        backup_paginator = client.get_paginator(
            "describe_db_instance_automated_backups")
        for resp in backup_paginator.paginate():
            for backup in resp.get("DBInstanceAutomatedBackups", []):
                if backup["DBInstanceArn"] in dbinstances:
                    dbinstances[backup["DBInstanceArn"]]["Backup"].append(
                        backup)
                else:
                    logger.info(
                        event=AWSLogEvents.ScanAWSResourcesNonFatalError,
                        msg=
                        (f'Unable to find matching DB Instance {backup["DBInstanceArn"]} '
                         "(Possible Deletion)"),
                    )
        return ListFromAWSResult(resources=dbinstances)
Beispiel #17
0
class S3BucketResourceSpec(S3ResourceSpec):
    """Resource for S3 Buckets"""

    type_name = "bucket"
    scan_granularity = ScanGranularity.ACCOUNT
    schema = Schema(
        ScalarField("Name"),
        ScalarField("CreationDate"),
        AnonymousDictField(
            "ServerSideEncryption",
            ListField(
                "Rules",
                EmbeddedDictField(
                    AnonymousDictField(
                        "ApplyServerSideEncryptionByDefault",
                        ScalarField("SSEAlgorithm", "algorithm"),
                    ),
                    AnonymousDictField(
                        "ApplyServerSideEncryptionByDefault",
                        ResourceLinkField("KMSMasterKeyID", KMSKeyResourceSpec, optional=True),
                    ),
                ),
                alti_key="server_side_default_encryption_rule",
            ),
        ),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["S3BucketResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'bucket_1_arn': {bucket_1_dict},
             'bucket_2_arn': {bucket_2_dict},
             ...}

        Where the dicts represent results from list_buckets."""
        logger = Logger()
        buckets = {}
        buckets_resp = client.list_buckets()
        for bucket in buckets_resp.get("Buckets", []):
            bucket_name = bucket["Name"]
            try:
                try:
                    bucket_region = get_s3_bucket_region(client, bucket_name)
                except S3BucketAccessDeniedException as s3ade:
                    logger.warn(
                        event=AWSLogEvents.ScanAWSResourcesNonFatalError,
                        msg=f"Unable to determine region for {bucket_name}: {s3ade}",
                    )
                    continue
                try:
                    bucket["Tags"] = get_s3_bucket_tags(client, bucket_name)
                except S3BucketAccessDeniedException as s3ade:
                    bucket["Tags"] = []
                    logger.warn(
                        event=AWSLogEvents.ScanAWSResourcesNonFatalError,
                        msg=f"Unable to determine tags for {bucket_name}: {s3ade}",
                    )
                try:
                    bucket["ServerSideEncryption"] = get_s3_bucket_encryption(client, bucket_name)
                except S3BucketAccessDeniedException as s3ade:
                    bucket["ServerSideEncryption"] = {"Rules": []}
                    logger.warn(
                        event=AWSLogEvents.ScanAWSResourcesNonFatalError,
                        msg=f"Unable to determine encryption status for {bucket_name}: {s3ade}",
                    )
                resource_arn = cls.generate_arn(
                    account_id=account_id, region=bucket_region, resource_id=bucket_name
                )
                buckets[resource_arn] = bucket
            except S3BucketDoesNotExistException as s3bdnee:
                logger.warn(
                    event=AWSLogEvents.ScanAWSResourcesNonFatalError,
                    msg=f"{bucket_name}: No longer exists: {s3bdnee}",
                )
        return ListFromAWSResult(resources=buckets)
class VPCPeeringConnectionResourceSpec(EC2ResourceSpec):
    """Resource for VPC Peering Connections."""

    # type_name = "vpc-peering-connection"
    type_name = "vpc_peering_connection"
    schema = Schema(
        TransientResourceLinkField("AccepterVpc",
                                   VPCResourceSpec,
                                   value_is_id=True,
                                   alti_key="accepter_vpc"),
        TransientResourceLinkField("RequesterVpc",
                                   VPCResourceSpec,
                                   value_is_id=True,
                                   alti_key="requester_vpc"),
        ScalarField("Status"),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["VPCPeeringConnectionResourceSpec"],
        client: BaseClient,
        account_id: str,
        region: str,
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'vpc_peering_connection_1_arn': {vpc_peering_connection_1_dict},
             'vpc_peering_connection_2_arn': {vpc_peering_connection_2_dict},
             ...}

        Where the dicts represent results from describe_vpc_peering_connections."""
        vpc_peering_connections = {}
        paginator = client.get_paginator("describe_vpc_peering_connections")
        for resp in paginator.paginate():
            for vpc_pc in resp["VpcPeeringConnections"]:
                resource_arn = cls.generate_arn(
                    resource_id=vpc_pc["VpcPeeringConnectionId"],
                    account_id=account_id,
                    region=region,
                )
                accepter_info = vpc_pc["AccepterVpcInfo"]
                accepter_account_id = accepter_info["OwnerId"]
                accepter_vpc_id = accepter_info["VpcId"]
                accepter_region = accepter_info["Region"]
                accepter_vpc_arn = VPCResourceSpec.generate_arn(
                    resource_id=accepter_vpc_id,
                    account_id=accepter_account_id,
                    region=accepter_region,
                )
                requester_info = vpc_pc["RequesterVpcInfo"]
                requester_account_id = requester_info["OwnerId"]
                requester_vpc_id = requester_info["VpcId"]
                requester_region = requester_info["Region"]
                requester_vpc_arn = VPCResourceSpec.generate_arn(
                    resource_id=requester_vpc_id,
                    account_id=requester_account_id,
                    region=requester_region,
                )
                vpc_peering_connection = {
                    "AccepterVpc": accepter_vpc_arn,
                    "RequesterVpc": requester_vpc_arn,
                    "Status": vpc_pc["Status"]["Code"],
                }
                vpc_peering_connections[resource_arn] = vpc_peering_connection
        return ListFromAWSResult(resources=vpc_peering_connections)
Beispiel #19
0
class SecurityGroupResourceSpec(EC2ResourceSpec):
    """Resource for SecurityGroups"""

    type_name = "security-group"
    schema = Schema(
        ScalarField("GroupName", "name"),
        ListField(
            "IpPermissions",
            EmbeddedDictField(
                ScalarField("IpProtocol"),
                ScalarField("FromPort", default_value=0),
                ScalarField("ToPort", default_value=65535),
                ListField(
                    "IpRanges",
                    EmbeddedDictField(
                        ScalarField("CidrIp"), ScalarField("FirstIp"), ScalarField("LastIp")
                    ),
                    alti_key="ip_range",
                    optional=True,
                ),
                ListField(
                    "Ipv6Ranges",
                    EmbeddedDictField(
                        ScalarField("CidrIpv6"), ScalarField("FirstIp"), ScalarField("LastIp")
                    ),
                    alti_key="ipv6_range",
                    optional=True,
                ),
                ListField(
                    "PrefixListIds", EmbeddedDictField(ScalarField("PrefixListId")), optional=True
                ),
                ListField(
                    "UserIdGroupPairs",
                    EmbeddedDictField(
                        ResourceLinkField("GroupId", "SecurityGroupResourceSpec"),
                        ScalarField("UserId", alti_key="account_id", optional=True),
                        ScalarField("PeeringStatus", optional=True),
                        ScalarField("VpcId", optional=True),
                        ScalarField("VpcPeeringConnectionId", optional=True),
                    ),
                    alti_key="user_id_group_pairs",
                ),
            ),
            alti_key="ingress_rule",
        ),
        ListField(
            "IpPermissionsEgress",
            EmbeddedDictField(
                ScalarField("IpProtocol"),
                ScalarField("FromPort", default_value=0),
                ScalarField("ToPort", default_value=65535),
                ListField(
                    "IpRanges",
                    EmbeddedDictField(
                        ScalarField("CidrIp"), ScalarField("FirstIp"), ScalarField("LastIp")
                    ),
                    alti_key="ip_range",
                    optional=True,
                ),
                ListField(
                    "Ipv6Ranges",
                    EmbeddedDictField(
                        ScalarField("CidrIpv6"), ScalarField("FirstIp"), ScalarField("LastIp")
                    ),
                    alti_key="ipv6_range",
                    optional=True,
                ),
                ListField(
                    "PrefixListIds", EmbeddedDictField(ScalarField("PrefixListId")), optional=True
                ),
                ListField(
                    "UserIdGroupPairs",
                    EmbeddedDictField(
                        ResourceLinkField("GroupId", "SecurityGroupResourceSpec"),
                        ScalarField("UserId", alti_key="account_id", optional=True),
                        ScalarField("PeeringStatus", optional=True),
                        ScalarField("VpcId", optional=True),
                        ScalarField("VpcPeeringConnectionId", optional=True),
                    ),
                    alti_key="user_id_group_pairs",
                ),
            ),
            alti_key="egress_rule",
        ),
        TagsField(),
    )

    @classmethod
    def list_from_aws(
        cls: Type["SecurityGroupResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        """Return a dict of dicts of the format:

            {'security_group_1_arn': {security_group_1_dict},
             'security_group_2_arn': {security_group_2_dict},
             ...}

        Where the dicts represent results from describe_subnets."""
        security_groups = {}
        paginator = client.get_paginator("describe_security_groups")
        for resp in paginator.paginate():
            for security_group in resp.get("SecurityGroups", []):
                resource_arn = cls.generate_arn(
                    account_id=account_id, region=region, resource_id=security_group["GroupId"]
                )
                for ingress_rule in security_group.get("IpPermissions", []):
                    for ip_range in ingress_rule.get("IpRanges", []):
                        cidr = ip_range["CidrIp"]
                        ipv4_network = ipaddress.IPv4Network(cidr, strict=False)
                        first_ip, last_ip = int(ipv4_network[0]), int(ipv4_network[-1])
                        ip_range["FirstIp"] = first_ip
                        ip_range["LastIp"] = last_ip
                    for ip_range in ingress_rule.get("Ipv6Ranges", []):
                        cidr = ip_range["CidrIpv6"]
                        ipv6_network = ipaddress.IPv6Network(cidr, strict=False)
                        first_ip, last_ip = int(ipv6_network[0]), int(ipv6_network[-1])
                        ip_range["FirstIp"] = first_ip
                        ip_range["LastIp"] = last_ip
                for egress_rule in security_group.get("IpPermissionsEgress", []):
                    for ip_range in egress_rule.get("IpRanges", []):
                        cidr = ip_range["CidrIp"]
                        ipv4_network = ipaddress.IPv4Network(cidr, strict=False)
                        first_ip, last_ip = int(ipv4_network[0]), int(ipv4_network[-1])
                        ip_range["FirstIp"] = first_ip
                        ip_range["LastIp"] = last_ip
                    for ip_range in egress_rule.get("Ipv6Ranges", []):
                        cidr = ip_range["CidrIpv6"]
                        ipv6_network = ipaddress.IPv6Network(cidr, strict=False)
                        first_ip, last_ip = int(ipv6_network[0]), int(ipv6_network[-1])
                        ip_range["FirstIp"] = first_ip
                        ip_range["LastIp"] = last_ip
                security_groups[resource_arn] = security_group
        return ListFromAWSResult(resources=security_groups)