Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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)
Example #6
0
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