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)
Example #2
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)
Example #3
0
class RDSSnapshotResourceSpec(RDSResourceSpec):
    """Resource for RDS Snapshot"""

    type_name = "snapshot"
    schema = Schema(
        ScalarField("DBSnapshotIdentifier"),
        ScalarField("SnapshotCreateTime", optional=True),
        ScalarField("Engine"),
        ScalarField("AllocatedStorage"),
        ScalarField("Status"),
        TransientResourceLinkField("VpcId", VPCResourceSpec, optional=True),
        ScalarField("InstanceCreateTime"),
        ScalarField("SnapshotType"),
        ScalarField("PercentProgress"),
        ScalarField("Region", optional=True),
        ScalarField("Encrypted"),
        TransientResourceLinkField("KmsKeyID", KMSKeyResourceSpec, optional=True),
        ScalarField("Timezone", optional=True),
        ScalarField("IAMDatabaseAuthenticationEnabled"),
        TransientResourceLinkField("DBInstanceArn", RDSInstanceResourceSpec, value_is_id=True),
    )

    @classmethod
    def generate_instance_arn(
        cls: Type["RDSSnapshotResourceSpec"], account_id: str, region: str, resource_id: str
    ) -> str:
        """Generate an ARN for this resource, e.g. arn:aws:rds:<region>:<account>:db:<name>
        """
        return ":".join(
            (
                "arn",
                cls.provider_name,
                cls.service_name,
                region,
                account_id,
                cls.type_name,
                resource_id,
            )
        )

    @classmethod
    def list_from_aws(
        cls: Type["RDSSnapshotResourceSpec"], client: BaseClient, account_id: str, region: str
    ) -> ListFromAWSResult:
        dbinstances = {}
        paginator = client.get_paginator("describe_db_snapshots")
        for resp in paginator.paginate():
            for db in resp.get("DBSnapshots", []):
                resource_arn = db["DBSnapshotArn"]
                db["DBInstanceArn"] = cls.generate_instance_arn(
                    account_id, region, db["DBInstanceIdentifier"]
                )
                dbinstances[resource_arn] = db
        return ListFromAWSResult(resources=dbinstances)
Example #4
0
class LambdaFunctionResourceSpec(LambdaResourceSpec):
    """Resource for Lambda Functions"""

    type_name = "function"
    schema = Schema(
        ScalarField("FunctionName"),
        ScalarField("Runtime", optional=True),
        AnonymousDictField(
            "VpcConfig",
            TransientResourceLinkField("VpcId", VPCResourceSpec,
                                       optional=True),
            optional=True,
        ),
    )

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

            {'function_1_arn': {function_1_dict},
             'function_2_arn': {function_2_dict},
             ...}

        Where the dicts represent results from list_functions."""
        functions = {}
        paginator = client.get_paginator("list_functions")
        for resp in paginator.paginate():
            for function in resp.get("Functions", []):
                resource_arn = function["FunctionArn"]
                functions[resource_arn] = function
        return ListFromAWSResult(resources=functions)
Example #5
0
class TargetGroupResourceSpec(ElasticLoadBalancingResourceSpec):
    """Resource for target group"""

    type_name = "targetgroup"
    schema = Schema(
        ScalarField("TargetGroupName"),
        ScalarField("Protocol", optional=True),
        ScalarField("Port", optional=True),
        TransientResourceLinkField("VpcId", VPCResourceSpec, optional=True),
        ScalarField("HealthCheckProtocol", optional=True),
        ScalarField("HealthCheckPort", optional=True),
        ScalarField("HealthCheckEnabled"),
        ListField(
            "LoadBalancerArns",
            EmbeddedResourceLinkField(LoadBalancerResourceSpec,
                                      value_is_id=True),
        ),
        ScalarField("TargetType"),
        ListField(
            "TargetHealthDescriptions",
            EmbeddedDictField(
                AnonymousDictField(
                    "Target",
                    ScalarField("Id", alti_key="target_id"),
                    ScalarField("Port", alti_key="target_port", optional=True),
                    ScalarField("AvailabilityZone",
                                alti_key="target_az",
                                optional=True),
                ),
                ScalarField("HealthCheckPort", optional=True),
                AnonymousDictField(
                    "TargetHealth",
                    ScalarField("State"),
                    ScalarField("Reason", optional=True),
                    ScalarField("Description", optional=True),
                    optional=True,
                ),
            ),
        ),
    )

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

            {'target_group_1_arn': {target_group_1_dict},
             'target_group_2_arn': {target_group_2_dict},
             ...}

        Where the dicts represent results from describe_target_groups."""
        paginator = client.get_paginator("describe_target_groups")
        resources = {}
        for resp in paginator.paginate():
            for resource in resp.get("TargetGroups", []):
                resource_arn = resource["TargetGroupArn"]
                resource["TargetHealthDescriptions"] = get_target_group_health(
                    client, resource_arn)
                resources[resource_arn] = resource
        return ListFromAWSResult(resources=resources)
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 FlowLogResourceSpec(EC2ResourceSpec):
    """Resource for VPC Flow Logs"""

    # type_name = "flow-log"
    type_name = "flow_log"
    schema = Schema(
        ScalarField("CreationTime"),
        ScalarField("DeliverLogsErrorMessage", optional=True),
        ScalarField("DeliverLogsPermissionArn", optional=True),
        ScalarField("DeliverLogsStatus", optional=True),
        ScalarField("FlowLogStatus"),
        ScalarField("LogGroupName", optional=True),
        TransientResourceLinkField("ResourceId",
                                   VPCResourceSpec,
                                   optional=True),
        ScalarField("TrafficType"),
        ScalarField("LogDestinationType"),
        ScalarField("LogDestination", optional=True),
        ScalarField("LogFormat"),
    )

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

            {'fl_1_arn': {fl_1_dict},
             'fl_2_arn': {fl_2_dict},
             ...}

        Where the dicts represent results from describe_flow_logs."""
        flow_logs = {}
        paginator = client.get_paginator("describe_flow_logs")
        for resp in paginator.paginate():
            for flow_log in resp.get("FlowLogs", []):
                resource_arn = cls.generate_arn(
                    account_id=account_id,
                    region=region,
                    resource_id=flow_log["FlowLogId"])
                flow_logs[resource_arn] = flow_log
        return ListFromAWSResult(resources=flow_logs)
Example #8
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)
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)
class DetectorResourceSpec(GuardDutyResourceSpec):
    """Resource for GuardDuty Detectors"""

    type_name = "detector"
    schema = Schema(
        ScalarField("CreatedAt"),
        ScalarField("FindingPublishingFrequency"),
        ScalarField("ServiceRole"),
        ScalarField("Status"),
        ScalarField("UpdatedAt"),
        ListField(
            "Members",
            EmbeddedDictField(
                TransientResourceLinkField("DetectorArn",
                                           "DetectorResourceSpec",
                                           value_is_id=True),
                ScalarField("Email"),
                ScalarField("RelationshipStatus"),
                ScalarField("InvitedAt"),
                ScalarField("UpdatedAt"),
            ),
            alti_key="member",
        ),
        AnonymousDictField(
            "Master",
            ScalarField("AccountId", alti_key="master_account_id"),
            ScalarField("RelationshipStatus",
                        alti_key="master_relationship_status"),
            # ScalarField("InvitedAt", alti_key="master_invited_at"),
            ScalarField("InvitedAt",
                        alti_key="master_invited_at",
                        optional=True),
            optional=True,
        ),
    )

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

            {'detector_1_arn': {detector_1_dict},
             'detector_2_arn': {detector_2_dict},
             ...}

        Where the dicts represent results from list_detectors and list_members, get_detector for
        each listed detector."""
        list_detectors_paginator = client.get_paginator("list_detectors")
        detectors: Dict[str, Dict[str, Any]] = {}
        for list_detectors_resp in list_detectors_paginator.paginate():
            detector_ids = list_detectors_resp["DetectorIds"]
            for detector_id in detector_ids:
                resource_arn = cls.generate_arn(account_id=account_id,
                                                region=region,
                                                resource_id=detector_id)
                try:
                    detectors[resource_arn] = cls.get_detector(
                        client, detector_id, region)
                except ClientError as c_e:
                    error_code = getattr(c_e, "response",
                                         {}).get("Error", {}).get("Code", {})
                    if error_code != "BadRequestException":
                        raise c_e
        return ListFromAWSResult(resources=detectors)

    @classmethod
    def get_detector(cls: Type["DetectorResourceSpec"], client: BaseClient,
                     detector_id: str, region: str) -> Dict[str, Any]:
        detector_resp = client.get_detector(DetectorId=detector_id)
        detector = {
            key: detector_resp[key]
            for key in (
                "CreatedAt",
                "FindingPublishingFrequency",
                "ServiceRole",
                "Status",
                "UpdatedAt",
            )
        }
        detector["Members"] = cls.get_detector_members(client, detector_id,
                                                       region)
        master_account_resp = client.get_master_account(DetectorId=detector_id)
        master_account_dict = master_account_resp.get("Master")
        if master_account_dict:
            detector["Master"] = {
                # key: master_account_dict[key]
                key: master_account_dict.get(key)
                for key in (
                    "AccountId",
                    "RelationshipStatus",
                    "InvitedAt",
                )
            }
        return detector

    @classmethod
    def get_detector_members(cls: Type["DetectorResourceSpec"],
                             client: BaseClient, detector_id: str,
                             region: str) -> List[Dict[str, Any]]:
        member_resps: List[Dict[str, Any]] = []
        list_members_paginator = client.get_paginator("list_members")
        for list_members_resp in list_members_paginator.paginate(
                DetectorId=detector_id):
            member_resps += list_members_resp.get("Members", [])
        members = []
        if member_resps:
            for member_resp in member_resps:
                member_account_id = member_resp["AccountId"]
                member_detector_id = member_resp["DetectorId"]
                # member_email = member_resp["Email"]
                member_email = member_resp.get("Email", "[NONE]")
                member_relationship_status = member_resp["RelationshipStatus"]
                # member_invited_at = member_resp["InvitedAt"]
                member_invited_at = member_resp.get("InvitedAt", "[NONE]")
                member_updated_at = member_resp["UpdatedAt"]
                member_detector_arn = cls.generate_arn(
                    account_id=member_account_id,
                    region=region,
                    resource_id=member_detector_id,
                )
                member = {
                    "DetectorArn": member_detector_arn,
                    "Email": member_email,
                    "RelationshipStatus": member_relationship_status,
                    "InvitedAt": member_invited_at,
                    "UpdatedAt": member_updated_at,
                }
                members.append(member)
        return members
class ClassicLoadBalancerResourceSpec(ELBV1ResourceSpec):
    """Resource for classic load balancer"""

    type_name = "loadbalancer"
    schema = Schema(
        ScalarField("DNSName"),
        ScalarField("CreatedTime"),
        ScalarField("LoadBalancerName"),
        ScalarField("Scheme"),
        ResourceLinkField("VPCId", VPCResourceSpec, optional=True),
        ListField("Subnets",
                  EmbeddedResourceLinkField(SubnetResourceSpec),
                  optional=True),
        ListField("SecurityGroups",
                  EmbeddedResourceLinkField(SecurityGroupResourceSpec),
                  optional=True),
        ScalarField("Type"),
        ScalarField("AccessLogsEnabled"),
        TransientResourceLinkField(
            "AccessLogsS3Bucket",
            S3BucketResourceSpec,
            alti_key="access_logs_s3_bucket",
            optional=True,
        ),
        ScalarField("AccessLogsS3Prefix", optional=True),
    )

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

            {'lb_1_arn': {lb_1_dict},
             'lb_2_arn': {lb_2_dict},
             ...}

        Where the dicts represent results from describe_load_balancers."""
        paginator = client.get_paginator("describe_load_balancers")
        load_balancers = {}
        for resp in paginator.paginate():
            for lb in resp["LoadBalancerDescriptions"]:
                lb_name = lb["LoadBalancerName"]
                resource_arn = cls.generate_arn(account_id=account_id,
                                                region=region,
                                                resource_id=lb_name)
                try:
                    lb_attrs = cls.get_lb_attrs(client, lb_name)
                    lb.update(lb_attrs)
                    lb["Type"] = "classic"
                    load_balancers[resource_arn] = lb
                except ClientError as c_e:
                    if (getattr(c_e, "response", {}).get("Error", {}).get(
                            "Code", {}) != "LoadBalancerNotFound"):
                        raise c_e
        return ListFromAWSResult(resources=load_balancers)

    @classmethod
    def get_lb_attrs(
        cls: Type["ClassicLoadBalancerResourceSpec"],
        client: BaseClient,
        lb_name: str,
    ) -> Dict[str, str]:
        """Get lb attributes that Altimeter graphs."""
        lb_attrs = {}
        resp = client.describe_load_balancer_attributes(
            LoadBalancerName=lb_name)
        access_log_attrs = resp["LoadBalancerAttributes"]["AccessLog"]
        lb_attrs["AccessLogsEnabled"] = access_log_attrs["Enabled"]
        if "S3BucketName" in access_log_attrs:
            lb_attrs["AccessLogsS3Bucket"] = access_log_attrs["S3BucketName"]
        if "S3BucketPrefix" in access_log_attrs:
            lb_attrs["AccessLogsS3Prefix"] = access_log_attrs["S3BucketPrefix"]
        return lb_attrs
Example #12
0
class LoadBalancerResourceSpec(ELBV2ResourceSpec):
    """Resource for load balancer"""

    type_name = "loadbalancer"
    schema = Schema(
        ScalarField("DNSName"),
        ScalarField("CreatedTime"),
        ScalarField("LoadBalancerName"),
        ScalarField("Scheme"),
        ResourceLinkField("VpcId", VPCResourceSpec, optional=True),
        AnonymousDictField("State",
                           ScalarField("Code",
                                       alti_key="load_balancer_state")),
        ScalarField("Type"),
        ListField(
            "AvailabilityZones",
            EmbeddedDictField(
                ScalarField("ZoneName"),
                ResourceLinkField("SubnetId",
                                  SubnetResourceSpec,
                                  optional=True),
                ListField(
                    "LoadBalancerAddresses",
                    EmbeddedDictField(
                        ScalarField("IpAddress", optional=True),
                        ScalarField("AllocationId", optional=True),
                    ),
                    optional=True,
                ),
            ),
        ),
        ListField("SecurityGroups",
                  EmbeddedResourceLinkField(SecurityGroupResourceSpec),
                  optional=True),
        ScalarField("IpAddressType"),
        ScalarField("AccessLogsEnabled"),
        TransientResourceLinkField(
            "AccessLogsS3Bucket",
            S3BucketResourceSpec,
            alti_key="access_logs_s3_bucket",
            optional=True,
        ),
        ScalarField("AccessLogsS3Prefix", optional=True),
    )

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

            {'lb_1_arn': {lb_1_dict},
             'lb_2_arn': {lb_2_dict},
             ...}

        Where the dicts represent results from describe_load_balancers."""
        paginator = client.get_paginator("describe_load_balancers")
        load_balancers = {}
        for resp in paginator.paginate():
            for lb in resp.get("LoadBalancers", []):
                resource_arn = lb["LoadBalancerArn"]
                try:
                    lb_attrs = cls.get_lb_attrs(client, resource_arn)
                    lb.update(lb_attrs)
                    load_balancers[resource_arn] = lb
                except ClientError as c_e:
                    if (getattr(c_e, "response", {}).get("Error", {}).get(
                            "Code", {}) != "LoadBalancerNotFound"):
                        raise c_e
        return ListFromAWSResult(resources=load_balancers)

    @classmethod
    def get_lb_attrs(
        cls: Type["LoadBalancerResourceSpec"],
        client: BaseClient,
        lb_arn: str,
    ) -> Dict[str, str]:
        """Get lb attributes that Altimeter graphs."""
        lb_attrs = {}
        resp = client.describe_load_balancer_attributes(LoadBalancerArn=lb_arn)
        for attr in resp["Attributes"]:
            if attr["Key"] == "access_logs.s3.enabled":
                lb_attrs["AccessLogsEnabled"] = attr["Value"]
            elif attr["Key"] == "access_logs.s3.bucket":
                if attr["Value"]:
                    lb_attrs["AccessLogsS3Bucket"] = attr["Value"]
            elif attr["Key"] == "access_logs.s3.prefix":
                if attr["Value"]:
                    lb_attrs["AccessLogsS3Prefix"] = attr["Value"]
        return lb_attrs