Пример #1
0
def test_generate_azure_w_endpoints(azure_config: types.MachConfig, tf_mock):
    config = azure_config
    config.sites[0].endpoints = [
        types.Endpoint(key="public", url="api.mach-example.com")
    ]
    data = tf.generate(parse.parse_config(config))

    # 'public' endpoint not used in component yet; no resources created
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_resource_group.main",
    ]

    config.components[0].endpoints = {
        "main": "public",
    }
    data = tf.generate(parse.parse_config(config))

    # Frontdoor instance need to be created since a component now uses it
    expected_resources = [
        "azurerm_app_service_plan.functionapps",
        "azurerm_dns_cname_record.public",
        "azurerm_frontdoor.app-service",
        "azurerm_frontdoor_custom_https_configuration.public",
        "azurerm_resource_group.main",
    ]
    assert tf.get_resource_ids(data) == expected_resources

    config.sites[0].endpoints.append(
        types.Endpoint(key="private", url="private-api.mach-example.com"))
    data = tf.generate(parse.parse_config(config))

    # We've added an extra endpoint definition, but hasn't been used.
    # List of resources should be the same as previous check
    assert tf.get_resource_ids(data) == expected_resources

    config.components.append(
        types.ComponentConfig(
            name="logger",
            source="some-source//terraform",
            version="1.0",
            endpoints={
                "main": "private",
            },
        ))
    config.sites[0].components.append(types.Component(name="logger", ))
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_dns_cname_record.private",
        "azurerm_dns_cname_record.public",
        "azurerm_frontdoor.app-service",
        "azurerm_frontdoor_custom_https_configuration.private",
        "azurerm_frontdoor_custom_https_configuration.public",
        "azurerm_resource_group.main",
    ]
Пример #2
0
def test_parse_w_variables(config: types.MachConfig, encrypted):
    config.sites[0].components[0].variables = {
        "my-value": r"${var.site1.my-value}"
    }
    config.variables_encrypted = encrypted
    with pytest.raises(Exception):
        config = parse.parse_config(config)

    config.variables = {"site1": {"my-value": "foo"}}
    config = parse.parse_config(config)

    if encrypted:
        assert (config.sites[0].components[0].variables["my-value"] ==
                'data.sops_external.variables.data["site1.my-value"]')
    else:
        assert config.sites[0].components[0].variables["my-value"] == "foo"
Пример #3
0
def test_validate_aws_default_endpoint(config: types.MachConfig):
    """It must be possible for a component to use the default API Gateway endpoint."""
    config.components[0].endpoints = {
        "main": "public",
    }
    config = parse.parse_config(config)

    with pytest.raises(ValidationError) as e:
        validate.validate_config(config)

    assert str(e.value) == "Missing required endpoints public"

    config.components[0].endpoints = {
        "main": "default",
    }
    config = parse.parse_config(config)
    validate.validate_config(config)
Пример #4
0
def test_generate_azure_service_plans(azure_config: types.MachConfig, tf_mock):
    config = azure_config
    config.components[0].azure = None
    config.sites[0].components.append(
        types.Component(
            name="payment",
        )
    )
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "azurerm_resource_group.main",
    ]

    config.sites[0].components[0].azure.service_plan = "default"
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_resource_group.main",
    ]

    config.general_config.azure.service_plans["premium"] = types.ServicePlan(
        kind="Linux",
        tier="PremiumV2",
        size="P2v2",
    )
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_resource_group.main",
    ]

    config.sites[0].components[0].azure.service_plan = "premium"
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps_premium",
        "azurerm_resource_group.main",
    ]

    config.sites[0].components[1].azure.service_plan = "default"
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_app_service_plan.functionapps_premium",
        "azurerm_resource_group.main",
    ]
Пример #5
0
def test_generate_aws_w_default_endpoint(config: types.MachConfig, tf_mock):
    """When endpoint 'default' is used, no custom domain has to be set."""
    data = tf.generate(parse.parse_config(config))

    # 'public' endpoint not used in component yet; no resources created
    assert "resource" not in data

    config.components[0].endpoints = {
        "main": "default",
    }
    data = tf.generate(parse.parse_config(config))

    # API gateway items need to be created since a component now uses it
    expected_resources = [
        "aws_apigatewayv2_api.default_gateway",
        "aws_apigatewayv2_route.default_application",
        "aws_apigatewayv2_stage.default_default",
    ]
    assert tf.get_resource_ids(data) == expected_resources
Пример #6
0
def test_parse_azure_service_plans(azure_config: types.MachConfig):
    config = azure_config
    # Sanity check
    assert not config.general_config.azure.service_plans
    config = parse.parse_config(config)

    assert "default" in config.general_config.azure.service_plans
    assert config.general_config.azure.service_plans[
        "default"] == types.ServicePlan(kind="FunctionApp",
                                        tier="Dynamic",
                                        size="Y1")
Пример #7
0
def test_generate_azure_w_default_endpoint(azure_config: types.MachConfig,
                                           tf_mock):
    """When endpoint 'default' is used, no custom domain has to be set."""
    config = azure_config
    data = tf.generate(parse.parse_config(config))

    # 'public' endpoint not used in component yet; no resources created
    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_resource_group.main",
    ]

    config.components[0].endpoints = {
        "main": "default",
    }
    data = tf.generate(parse.parse_config(config))

    assert tf.get_resource_ids(data) == [
        "azurerm_app_service_plan.functionapps",
        "azurerm_frontdoor.app-service",
        "azurerm_resource_group.main",
    ]
Пример #8
0
def test_validate_component_endpoint(config: types.MachConfig):
    """An endpoint defined on a component must exist for all sites that use that component."""
    config.components[0].endpoints = {
        "main": "public",
    }
    config = parse.parse_config(config)

    with pytest.raises(ValidationError):
        validate.validate_config(config)

    config.sites[0].endpoints = [
        types.Endpoint(
            key="public",
            url="api.mach-example.com",
        ),
        types.Endpoint(
            key="services",
            url="services.mach-example.com",
        ),
    ]
    validate.validate_config(config)

    new_site = types.Site(
        identifier="unittest-nl",
        components=[],
        aws=types.SiteAWSSettings(
            account_id=1234567890,
            region="eu-central-1",
        ),
    )
    config.sites.append(new_site)
    validate.validate_config(config)

    new_site.components.append(types.Component(name="api-extensions", ))
    config = parse.parse_config(config)

    with pytest.raises(ValidationError):
        validate.validate_config(config)
Пример #9
0
def test_parse_endpoints(config: types.MachConfig):
    config.sites[0].endpoints = [
        types.Endpoint(
            key="public",
            url="api.mach-example.com",
        ),
        types.Endpoint(
            key="services",
            url="services.mach-example.com",
        ),
    ]

    config = parse.parse_config(config)
    for endpoint in config.sites[0].endpoints:
        assert endpoint.zone == "mach-example.com"
Пример #10
0
def test_aws_endpoint_with_cdn_generates_one_us_east_provider(
        config: types.MachConfig, tf_mock):
    config.sites[0].endpoints = [
        types.Endpoint(key="public",
                       url="api.mach-example.com",
                       aws=AWSEndpoint(enable_cdn=True))
    ]
    config.components[0].endpoints = {
        "main": "public",
    }

    data = tf.generate(parse.parse_config(config))

    assert data["provider"]["aws"] == {
        "alias": ["mach-cf-us-east-1"],
        "region": ["us-east-1"],
    }
Пример #11
0
def test_generate_aws_w_endpoints(config: types.MachConfig, tf_mock):
    config.sites[0].endpoints = [
        types.Endpoint(key="public", url="api.mach-example.com")
    ]
    data = tf.generate(parse.parse_config(config))

    # 'public' endpoint not used in component yet; no resources created
    assert "resource" not in data

    config.components[0].endpoints = {
        "main": "public",
    }
    data = tf.generate(parse.parse_config(config))

    # API gateway items need to be created since a component now uses it
    expected_resources = [
        "aws_acm_certificate.public",
        "aws_apigatewayv2_api.public_gateway",
        "aws_apigatewayv2_api_mapping.public",
        "aws_apigatewayv2_domain_name.public",
        "aws_apigatewayv2_route.public_application",
        "aws_apigatewayv2_stage.public_default",
        "aws_route53_record.public",
        "aws_route53_record.public_acm_validation",
    ]
    expected_data_sources = [
        "aws_route53_zone.mach_examplecom",
    ]
    assert tf.get_resource_ids(data) == expected_resources
    assert tf.get_data_ids(data) == expected_data_sources

    config.sites[0].endpoints.append(
        types.Endpoint(key="private", url="private-api.mach-services.io"))
    data = tf.generate(parse.parse_config(config))

    # We've added an extra endpoint definition, but hasn't been used.
    # List of resources should be the same as previous check
    assert tf.get_resource_ids(data) == expected_resources
    assert tf.get_data_ids(data) == expected_data_sources

    config.components.append(
        types.ComponentConfig(
            name="logger",
            source="some-source//terraform",
            version="1.0",
            endpoints={
                "main": "private",
            },
        ))
    config.sites[0].components.append(types.Component(name="logger", ))
    data = tf.generate(parse.parse_config(config))
    assert tf.get_resource_ids(data) == [
        "aws_acm_certificate.private",
        "aws_acm_certificate.public",
        "aws_apigatewayv2_api.private_gateway",
        "aws_apigatewayv2_api.public_gateway",
        "aws_apigatewayv2_api_mapping.private",
        "aws_apigatewayv2_api_mapping.public",
        "aws_apigatewayv2_domain_name.private",
        "aws_apigatewayv2_domain_name.public",
        "aws_apigatewayv2_route.private_application",
        "aws_apigatewayv2_route.public_application",
        "aws_apigatewayv2_stage.private_default",
        "aws_apigatewayv2_stage.public_default",
        "aws_route53_record.private",
        "aws_route53_record.private_acm_validation",
        "aws_route53_record.public",
        "aws_route53_record.public_acm_validation",
    ]
    assert tf.get_data_ids(data) == [
        "aws_route53_zone.mach_examplecom",
        "aws_route53_zone.mach_servicesio",
    ]
Пример #12
0
def parsed_config(config):
    return parse.parse_config(config)
Пример #13
0
def parsed_azure_config(azure_config):
    return parse.parse_config(azure_config)
Пример #14
0
def test_generate_w_stores(config: types.MachConfig, tf_mock):
    config.sites[0].commercetools = types.CommercetoolsSettings(
        project_key="ct-unit-test",
        client_id="a96e59be-24da-4f41-a6cf-d61d7b6e1766",
        client_secret="98c32de8-1a6c-45a9-a718-d3cce5201799",
        scopes="manage_project:ct-unit-test",
        project_settings=types.CommercetoolsProjectSettings(
            languages=["nl-NL"],
            countries=["NL"],
            currencies=["EUR"],
        ),
        stores=[
            types.CommercetoolsStore(
                name={
                    "en-GB": "Default store",
                },
                key="main-store",
            ),
            types.CommercetoolsStore(
                name={
                    "en-GB": "Some other store",
                },
                key="other-store",
            ),
            types.CommercetoolsStore(
                name={
                    "en-GB": "Forgotten store",
                },
                key="forgotten-store",
            ),
        ],
    )
    config.components[0].integrations = ["aws", "commercetools"]
    data = tf.generate(parse.parse_config(config))

    assert len(data.resource.commercetools_store) == 3
    assert "main-store" in data.resource.commercetools_store
    assert "other-store" in data.resource.commercetools_store
    assert "forgotten-store" in data.resource.commercetools_store

    assert len(data.module["api-extensions"].ct_stores) == 3

    for store_key, store in data.module["api-extensions"].ct_stores.items():
        assert store["key"] == store_key
        assert not store["variables"]
        assert not store["secrets"]

    config.sites[0].components[0].store_variables = {
        "main-store": {
            "FOO": "BAR",
            "EXTRA": "VALUES",
        },
        "other-store": {
            "FOO": "SOMETHING ELSE",
        },
    }
    config.sites[0].components[0].store_secrets = {
        "main-store": {
            "PAYMENT_KEY": "TLrlDf6XhKkXFGGHeQGY",
        },
    }

    data = tf.generate(parse.parse_config(config))
    main_store = data.module["api-extensions"].ct_stores["main-store"]
    other_store = data.module["api-extensions"].ct_stores["other-store"]
    assert len(main_store.variables) == 2
    assert len(other_store.variables) == 1
    assert len(main_store.secrets) == 1
    assert not other_store.secrets
Пример #15
0
def test_commercetools_frontend_credentials(config: types.MachConfig, tf_mock):
    config.sites[0].commercetools = types.CommercetoolsSettings(
        project_key="ct-unit-test",
        client_id="a96e59be-24da-4f41-a6cf-d61d7b6e1766",
        client_secret="98c32de8-1a6c-45a9-a718-d3cce5201799",
        scopes="manage_project:ct-unit-test",
        project_settings=types.CommercetoolsProjectSettings(
            languages=["nl-NL"],
            countries=["NL"],
            currencies=["EUR"],
        ),
        stores=[
            types.CommercetoolsStore(
                name={
                    "en-GB": "Default store",
                },
                key="main-store",
            ),
            types.CommercetoolsStore(
                name={
                    "en-GB": "Some other store",
                },
                key="other-store",
            ),
            types.CommercetoolsStore(
                name={
                    "en-GB": "Forgotten store",
                },
                key="forgotten-store",
            ),
        ],
    )
    data = tf.generate(parse.parse_config(config))
    assert list(data.resource.commercetools_api_client.keys()) == [
        "frontend_credentials_main-store",
        "frontend_credentials_other-store",
        "frontend_credentials_forgotten-store",
    ]

    assert data.resource.commercetools_api_client[
        "frontend_credentials_main-store"].scope == [
            "create_anonymous_token:ct-unit-test",
            "manage_my_profile:ct-unit-test",
            "manage_my_profile:ct-unit-test:main-store",
            "manage_my_orders:ct-unit-test",
            "manage_my_orders:ct-unit-test:main-store",
            "manage_my_shopping_lists:ct-unit-test",
            "manage_my_payments:ct-unit-test",
            "view_products:ct-unit-test",
            "view_project_settings:ct-unit-test",
        ]

    config.sites[0].commercetools.frontend.create_credentials = False
    data = tf.generate(parse.parse_config(config))
    assert "commercetools_api_client" not in data.resource

    config.sites[0].commercetools.frontend.create_credentials = True
    config.sites[0].commercetools.frontend.permission_scopes = [
        "manage_my_profile",
        "manage_my_orders",
        "view_products",
        "manage_my_payments",
        "create_anonymous_token",
        "view_stores",
    ]

    data = tf.generate(parse.parse_config(config))
    assert data.resource.commercetools_api_client[
        "frontend_credentials_main-store"].scope == [
            "manage_my_profile:ct-unit-test",
            "manage_my_profile:ct-unit-test:main-store",
            "manage_my_orders:ct-unit-test",
            "manage_my_orders:ct-unit-test:main-store",
            "view_products:ct-unit-test",
            "manage_my_payments:ct-unit-test",
            "create_anonymous_token:ct-unit-test",
            "view_stores:ct-unit-test",
        ]
Пример #16
0
def test_site(config: types.MachConfig):
    config.components.append(
        types.ComponentConfig(
            name="private-api",
            source="some-private-source/terraform",
            version="1.0",
        ))
    config.sites[0].components.append(types.Component(name="private-api"))

    config.sites[0].endpoints = [
        types.Endpoint(
            key="public",
            url="api.example.com",
        ),
        types.Endpoint(
            key="private",
            url="private-api.example.com",
        ),
    ]
    config = parse.parse_config(config)
    site = config.sites[0]

    assert site.used_endpoints == []
    config.components[0].endpoints = {
        "main": "public",
    }
    config = parse.parse_config(config)
    assert site.used_endpoints == [
        types.Endpoint(key="public",
                       url="api.example.com",
                       components=[site.components[0]])
    ]

    config.components[1].endpoints = {
        "main": "public",
    }
    config = parse.parse_config(config)
    assert site.used_endpoints == [
        types.Endpoint(
            key="public",
            url="api.example.com",
            components=[site.components[0], site.components[1]],
        )
    ]

    config.components[1].endpoints = {
        "main": "private",
    }
    config = parse.parse_config(config)
    assert site.used_endpoints == [
        types.Endpoint(
            key="public",
            url="api.example.com",
            components=[
                site.components[0],
            ],
        ),
        types.Endpoint(
            key="private",
            url="private-api.example.com",
            components=[site.components[1]],
        ),
    ]