def add_aws_destination_to_sources(dst): """ Given a destination, check if it can be added as sources, and include it if not already a source We identify qualified destinations based on the sync_as_source attributed of the plugin. The destination sync_as_source_name reveals the name of the suitable source-plugin. We rely on account numbers to avoid duplicates. :return: true for success and false for not adding the destination as source """ # a set of all accounts numbers available as sources src_accounts = set() sources = get_all() for src in sources: src_accounts.add(get_plugin_option("accountNumber", src.options)) # check destination_plugin = plugins.get(dst.plugin_name) account_number = get_plugin_option("accountNumber", dst.options) if (account_number is not None and destination_plugin.sync_as_source is not None and destination_plugin.sync_as_source and (account_number not in src_accounts)): src_options = copy.deepcopy( plugins.get(destination_plugin.sync_as_source_name).options) set_plugin_option("accountNumber", account_number, src_options) create( label=dst.label, plugin_name=destination_plugin.sync_as_source_name, options=src_options, description=dst.description, ) return True return False
def add_aws_destination_to_sources(dst): """ Given a destination check, if it can be added as sources, and included it if not already a source We identify qualified destinations based on the sync_as_source attributed of the plugin. The destination sync_as_source_name reveals the name of the suitable source-plugin. We rely on account numbers to avoid duplicates. :return: true for success and false for not adding the destination as source """ # a set of all accounts numbers available as sources src_accounts = set() sources = get_all() for src in sources: src_accounts.add(get_plugin_option('accountNumber', src.options)) # check destination_plugin = plugins.get(dst.plugin_name) account_number = get_plugin_option('accountNumber', dst.options) if account_number is not None and \ destination_plugin.sync_as_source is not None and \ destination_plugin.sync_as_source and \ (account_number not in src_accounts): src_options = copy.deepcopy(plugins.get(destination_plugin.sync_as_source_name).options) set_plugin_option('accountNumber', account_number, src_options) create(label=dst.label, plugin_name=destination_plugin.sync_as_source_name, options=src_options, description=dst.description) return True return False
def add_aws_destination_to_sources(dst): """ Given a destination, check if it can be added as sources, and include it if not already a source We identify qualified destinations based on the sync_as_source attributed of the plugin. The destination sync_as_source_name reveals the name of the suitable source-plugin. We rely on account numbers to avoid duplicates. :return: true for success and false for not adding the destination as source """ # check that destination can be synced to a source destination_plugin = plugins.get(dst.plugin_name) if destination_plugin.sync_as_source is None or not destination_plugin.sync_as_source: return False account_number = get_plugin_option("accountNumber", dst.options) if account_number is None: return False path = get_plugin_option("path", dst.options) if path is None: return False # a set of all (account number, path) available as sources src_account_paths = set() sources = get_all() for src in sources: src_account_paths.add((get_plugin_option("accountNumber", src.options), get_plugin_option("path", src.options))) if (account_number, path) not in src_account_paths: src_options = copy.deepcopy( plugins.get(destination_plugin.sync_as_source_name).options) set_plugin_option("accountNumber", account_number, src_options) set_plugin_option("path", path, src_options) # Set the right endpointType for cloudfront sources. if get_plugin_option( "endpointType", src_options) is not None and path == "/cloudfront/": set_plugin_option("endpointType", "cloudfront", src_options) create( label=dst.label, plugin_name=destination_plugin.sync_as_source_name, options=src_options, description=dst.description, ) return True return False
def test_get_all_elb_and_elbv2s(app, aws_credentials): from copy import deepcopy from lemur.plugins.lemur_aws.elb import get_load_balancer_arn_from_endpoint from lemur.plugins.base import plugins from lemur.plugins.utils import set_plugin_option acm_client = boto3.client("acm", region_name="us-east-1") acm_request_response = acm_client.request_certificate( DomainName="test.example.com", DomainValidationOptions=[ { "DomainName": "test.example.com", "ValidationDomain": "test.example.com" }, ], ) arn1 = acm_request_response["CertificateArn"] cert_name1 = arn1.split("/")[-1] acm_request_response = acm_client.request_certificate( DomainName="test2.example.com", DomainValidationOptions=[ { "DomainName": "test2.example.com", "ValidationDomain": "test2.example.com" }, ], ) arn2 = acm_request_response["CertificateArn"] cert_name2 = arn2.split("/")[-1] client = boto3.client("elb", region_name="us-east-1") client.create_load_balancer( LoadBalancerName="example-lb", Listeners=[{ "Protocol": "string", "LoadBalancerPort": 443, "InstanceProtocol": "tcp", "InstancePort": 5443, "SSLCertificateId": arn1, }], ) ec2 = boto3.resource("ec2", region_name="us-east-1") elbv2 = boto3.client("elbv2", region_name="us-east-1") vpc = ec2.create_vpc(CidrBlock="10.0.1.0/24") subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.1.128/25", AvailabilityZone="us-east-1b") elbv2.create_load_balancer( Name="test-lbv2", Subnets=[ subnet1.id, ], ) lb_arn = get_load_balancer_arn_from_endpoint("test-lbv2", account_number="123456789012", region="us-east-1") target_group_arn = elbv2.create_target_group( Name="a-target", Protocol="HTTPS", Port=443, VpcId=vpc.id).get("TargetGroups")[0]["TargetGroupArn"] listener = elbv2.create_listener( LoadBalancerArn=lb_arn, Protocol="HTTPS", Port=1443, Certificates=[{ "CertificateArn": arn2 }], DefaultActions=[{ "Type": "forward", "TargetGroupArn": target_group_arn }], ) aws_source = plugins.get("aws-source") options = deepcopy(aws_source.options) set_plugin_option("accountNumber", "123456789012", options) set_plugin_option("endpointType", "elb", options) set_plugin_option("regions", "us-east-1", options) elbs = aws_source.get_endpoints(options) elb_map = {} for elb in elbs: elb_map[elb["name"]] = elb assert elb_map["example-lb"]["certificate_name"] == cert_name1 assert elb_map["example-lb"]["registry_type"] == "acm" assert elb_map["example-lb"]["port"] == 443 assert elb_map["test-lbv2"]["certificate_name"] == cert_name2 assert elb_map["test-lbv2"]["registry_type"] == "acm" assert elb_map["test-lbv2"]["port"] == 1443
def enable_cloudfront(source_label): """ Given the label of a legacy AWS source (without path or endpointType options), set up the source for CloudFront: #. Update the source options to the newest template, inheriting the existing values. #. Set ``path`` to "/" and ``endpointType`` to "elb" to restrict the source to discovering ELBs and related certs only. #. Create a new source (and destination) for the same accountNumber with ``path`` as "/cloudfront/" and ``endpointType`` as "cloudfront" :param source_strings: :return: """ class ValidationError(Exception): pass try: source = source_service.get_by_label(source_label) if not source: raise ValidationError( f"Unable to find source with label: {source_label}") if source.plugin_name != "aws-source": raise ValidationError( f"Source '{source_label}' is not an AWS source") for opt_name in ["endpointType", "path"]: if get_plugin_option(opt_name, source.options) is not None: raise ValidationError( f"Source '{source_label}' already sets option '{opt_name}'" ) cloudfront_label = f"{source_label}-cloudfront" cloudfront_source = source_service.get_by_label(cloudfront_label) if cloudfront_source: raise ValidationError( f"A source named '{cloudfront_label}' already exists") p = plugins.get(source.plugin_name) new_options = deepcopy(p.options) for old_opt in source.options: name = old_opt["name"] value = get_plugin_option(name, source.options) set_plugin_option(name, value, new_options) set_plugin_option("path", "/", new_options) set_plugin_option("endpointType", "elb", new_options) source_service.update(source.id, source.label, source.plugin_name, new_options, source.description) cloudfront_options = deepcopy(new_options) set_plugin_option("path", "/cloudfront/", cloudfront_options) set_plugin_option("endpointType", "cloudfront", cloudfront_options) source_service.create( cloudfront_label, source.plugin_name, cloudfront_options, f"CloudFront certificates and distributions for {source_label}") print( f"[+] Limited source {source_label} to discover ELBs and ELB certificates.\n" ) print( f"[+] Created source {cloudfront_label} to discover CloudFront distributions and certificates.\n" ) except ValidationError as e: print(f"[+] Error: {str(e)}") sys.exit(1)
def test_get_all_elb_and_elbv2s(app, aws_credentials): from copy import deepcopy from lemur.plugins.lemur_aws.elb import get_load_balancer_arn_from_endpoint from lemur.plugins.base import plugins from lemur.plugins.utils import set_plugin_option cert_arn_prefix = "arn:aws:iam::123456789012:server-certificate/" cert_arn = cert_arn_prefix + "plugin-test.example.com-R3-20211023-20220121" cert_arn_v2 = cert_arn_prefix + "plugin-test-v2.example.com-R3-20211023-20220121" client = boto3.client("elb", region_name="us-east-1") client.create_load_balancer( LoadBalancerName="example-lb", Listeners=[{ "Protocol": "string", "LoadBalancerPort": 443, "InstanceProtocol": "tcp", "InstancePort": 5443, "SSLCertificateId": cert_arn, }], ) ec2 = boto3.resource("ec2", region_name="us-east-1") elbv2 = boto3.client("elbv2", region_name="us-east-1") vpc = ec2.create_vpc(CidrBlock="10.0.1.0/24") subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.1.128/25", AvailabilityZone="us-east-1b") elbv2.create_load_balancer( Name="test-lbv2", Subnets=[ subnet1.id, ], ) lb_arn = get_load_balancer_arn_from_endpoint("test-lbv2", account_number="123456789012", region="us-east-1") target_group_arn = elbv2.create_target_group( Name="a-target", Protocol="HTTPS", Port=443, VpcId=vpc.id).get("TargetGroups")[0]["TargetGroupArn"] listener = elbv2.create_listener( LoadBalancerArn=lb_arn, Protocol="HTTPS", Port=1443, Certificates=[{ "CertificateArn": cert_arn_v2 }], DefaultActions=[{ "Type": "forward", "TargetGroupArn": target_group_arn }], ) aws_source = plugins.get("aws-source") options = deepcopy(aws_source.options) set_plugin_option("accountNumber", "123456789012", options) set_plugin_option("endpointType", "elb", options) set_plugin_option("regions", "us-east-1", options) elbs = aws_source.get_endpoints(options) elb_map = {} for elb in elbs: elb_map[elb["name"]] = elb assert elb_map["example-lb"][ "certificate_name"] == "plugin-test.example.com-R3-20211023-20220121" assert elb_map["example-lb"]["registry_type"] == "iam" assert elb_map["example-lb"]["port"] == 443 assert elb_map["test-lbv2"][ "certificate_name"] == "plugin-test-v2.example.com-R3-20211023-20220121" assert elb_map["test-lbv2"]["registry_type"] == "iam" assert elb_map["test-lbv2"]["port"] == 1443