def api_resource():
    random_suffix = (''.join(
        random.choice(string.ascii_lowercase) for _ in range(6)))
    api_resource_name = test_resource_values['API_NAME'] + f'-{random_suffix}'
    test_resource_values['API_NAME'] = api_resource_name
    api_ref, api_data = helper.api_ref_and_data(
        api_resource_name=api_resource_name,
        replacement_values=test_resource_values)
    if k8s.get_resource_exists(api_ref):
        raise Exception(
            f"expected {api_resource_name} to not exist. Did previous test cleanup?"
        )
    logging.debug(
        f"http api resource. name: {api_resource_name}, data: {api_data}")

    k8s.create_custom_resource(api_ref, api_data)
    cr = k8s.wait_resource_consumed_by_controller(api_ref)

    assert cr is not None
    assert k8s.get_resource_exists(api_ref)

    api_id = cr['status']['apiID']
    test_resource_values['API_ID'] = api_id

    yield api_ref, cr

    k8s.delete_custom_resource(api_ref)
def route_resource(integration_resource, authorizer_resource):
    random_suffix = (''.join(
        random.choice(string.ascii_lowercase) for _ in range(6)))
    route_resource_name = test_resource_values[
        'ROUTE_NAME'] + f'-{random_suffix}'
    test_resource_values['ROUTE_NAME'] = route_resource_name
    route_ref, route_data = helper.route_ref_and_data(
        route_resource_name=route_resource_name,
        replacement_values=test_resource_values)
    if k8s.get_resource_exists(route_ref):
        raise Exception(
            f"expected {route_resource_name} to not exist. Did previous test cleanup?"
        )
    logging.debug(
        f"apigatewayv2 route resource. name: {route_resource_name}, data: {route_data}"
    )

    k8s.create_custom_resource(route_ref, route_data)
    cr = k8s.wait_resource_consumed_by_controller(route_ref)

    assert cr is not None
    assert k8s.get_resource_exists(route_ref)

    route_id = cr['status']['routeID']
    test_resource_values['ROUTE_ID'] = route_id

    yield route_ref, cr

    k8s.delete_custom_resource(route_ref)
def stage_resource(route_resource):
    random_suffix = (''.join(
        random.choice(string.ascii_lowercase) for _ in range(6)))
    stage_resource_name = test_resource_values[
        'STAGE_NAME'] + f'-{random_suffix}'
    test_resource_values['STAGE_NAME'] = stage_resource_name
    stage_ref, stage_data = helper.stage_ref_and_data(
        stage_resource_name=stage_resource_name,
        replacement_values=test_resource_values)
    if k8s.get_resource_exists(stage_ref):
        raise Exception(
            f"expected {stage_resource_name} to not exist. Did previous test cleanup?"
        )
    logging.debug(
        f"apigatewayv2 stage resource. name: {stage_resource_name}, data: {stage_data}"
    )

    k8s.create_custom_resource(stage_ref, stage_data)
    cr = k8s.wait_resource_consumed_by_controller(stage_ref)

    assert cr is not None
    assert k8s.get_resource_exists(stage_ref)

    yield stage_ref, cr

    k8s.delete_custom_resource(stage_ref)
def integration_resource(api_resource):
    random_suffix = (''.join(
        random.choice(string.ascii_lowercase) for _ in range(6)))
    integration_resource_name = test_resource_values[
        'INTEGRATION_NAME'] + f'-{random_suffix}'
    test_resource_values['INTEGRATION_NAME'] = integration_resource_name
    integration_ref, integration_data = helper.integration_ref_and_data(
        integration_resource_name=integration_resource_name,
        replacement_values=test_resource_values)
    if k8s.get_resource_exists(integration_ref):
        raise Exception(
            f"expected {integration_resource_name} to not exist. Did previous test cleanup?"
        )
    logging.debug(
        f"apigatewayv2 integration resource. name: {integration_resource_name}, data: {integration_data}"
    )

    k8s.create_custom_resource(integration_ref, integration_data)
    cr = k8s.wait_resource_consumed_by_controller(integration_ref)

    assert cr is not None
    assert k8s.get_resource_exists(integration_ref)

    integration_id = cr['status']['integrationID']
    test_resource_values['INTEGRATION_ID'] = integration_id

    yield integration_ref, cr

    k8s.delete_custom_resource(integration_ref)
    def test_crud_authorizer(self, api_resource):
        api_ref, api_cr = api_resource
        api_id = api_cr['status']['apiID']
        test_data = REPLACEMENT_VALUES.copy()
        authorizer_name = random_suffix_name("ack-test-authorizer", 25)
        test_data['AUTHORIZER_NAME'] = authorizer_name
        test_data['AUTHORIZER_TITLE'] = authorizer_name
        test_data['API_ID'] = api_id
        test_data['AUTHORIZER_URI'] = f'arn:aws:apigateway:{get_region()}:lambda:path/2015-03-31/functions/{get_bootstrap_resources().AuthorizerFunctionArn}/invocations'
        authorizer_ref, authorizer_data = helper.authorizer_ref_and_data(authorizer_resource_name=authorizer_name,
                                                                         replacement_values=test_data)
        logging.debug(f"http api authorizer resource. name: {authorizer_name}, data: {authorizer_data}")

        # test create
        k8s.create_custom_resource(authorizer_ref, authorizer_data)
        time.sleep(CREATE_WAIT_AFTER_SECONDS)
        assert k8s.wait_on_condition(authorizer_ref, "ACK.ResourceSynced", "True", wait_periods=10)

        cr = k8s.get_resource(authorizer_ref)
        assert cr is not None

        authorizer_id = cr['status']['authorizerID']

        # Let's check that the HTTP Api integration appears in Amazon API Gateway
        apigw_validator.assert_authorizer_is_present(api_id=api_id, authorizer_id=authorizer_id)

        apigw_validator.assert_authorizer_name(
            api_id=api_id,
            authorizer_id=authorizer_id,
            expected_authorizer_name=authorizer_name
        )

        # test update
        updated_authorizer_title = 'updated-' + authorizer_name
        test_data['AUTHORIZER_TITLE'] = updated_authorizer_title
        updated_authorizer_resource_data = load_apigatewayv2_resource(
            "authorizer",
            additional_replacements=test_data,
        )
        logging.debug(f"updated http api authorizer resource: {updated_authorizer_resource_data}")

        # Update the k8s resource
        k8s.patch_custom_resource(authorizer_ref, updated_authorizer_resource_data)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        condition.assert_synced(authorizer_ref)
        # Let's check that the HTTP Api authorizer appears in Amazon API Gateway with updated title
        apigw_validator.assert_authorizer_name(
            api_id=api_id,
            authorizer_id=authorizer_id,
            expected_authorizer_name=updated_authorizer_title
        )

        # test delete
        k8s.delete_custom_resource(authorizer_ref)
        time.sleep(DELETE_WAIT_AFTER_SECONDS)
        assert not k8s.get_resource_exists(authorizer_ref)
        # HTTP Api authorizer should no longer appear in Amazon API Gateway
        apigw_validator.assert_authorizer_is_deleted(api_id=api_id, authorizer_id=authorizer_id)
    def test_crud_stage(self, api_resource):
        api_ref, api_cr = api_resource
        api_id = api_cr['status']['apiID']
        test_data = REPLACEMENT_VALUES.copy()
        random_suffix = (''.join(
            random.choice(string.ascii_lowercase) for _ in range(6)))
        stage_name = "ack-test-stage-" + random_suffix
        test_data['STAGE_NAME'] = stage_name
        test_data['API_ID'] = api_id
        stage_ref, stage_data = helper.stage_ref_and_data(
            stage_resource_name=stage_name, replacement_values=test_data)
        logging.debug(
            f"http api stage resource. name: {stage_name}, data: {stage_data}")

        # test create
        k8s.create_custom_resource(stage_ref, stage_data)
        cr = k8s.wait_resource_consumed_by_controller(stage_ref)

        assert cr is not None
        assert k8s.get_resource_exists(stage_ref)

        # Let's check that the HTTP Api integration appears in Amazon API Gateway
        apigw_validator.assert_stage_is_present(api_id=api_id,
                                                stage_name=stage_name)

        stage_description = test_data['STAGE_DESCRIPTION']
        apigw_validator.assert_stage_description(
            api_id=api_id,
            stage_name=stage_name,
            expected_description=stage_description)

        # test update
        updated_description = 'updated' + stage_description
        test_data['STAGE_DESCRIPTION'] = updated_description
        updated_stage_resource_data = load_apigatewayv2_resource(
            "stage",
            additional_replacements=test_data,
        )
        logging.debug(
            f"updated http api stage resource: {updated_stage_resource_data}")

        # Update the k8s resource
        k8s.patch_custom_resource(stage_ref, updated_stage_resource_data)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        # Let's check that the HTTP Api stage appears in Amazon API Gateway with updated description
        apigw_validator.assert_stage_description(
            api_id=api_id,
            stage_name=stage_name,
            expected_description=updated_description)

        # test delete
        k8s.delete_custom_resource(stage_ref)
        time.sleep(DELETE_WAIT_AFTER_SECONDS)
        assert not k8s.get_resource_exists(stage_ref)
        # HTTP Api stage should no longer appear in Amazon API Gateway
        apigw_validator.assert_stage_is_deleted(api_id=api_id,
                                                stage_name=stage_name)
    def test_smoke(self, lambda_client):
        resource_name = random_suffix_name("lambda-csc", 24)

        resources = get_bootstrap_resources()
        logging.debug(resources)

        replacements = REPLACEMENT_VALUES.copy()
        replacements["AWS_REGION"] = get_region()
        replacements["CODE_SIGNING_CONFIG_NAME"] = resource_name
        replacements["SIGNING_PROFILE_VERSION_ARN"] = resources.SigningProfileVersionArn

        # Load Lambda CR
        resource_data = load_lambda_resource(
            "code_signing_config",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
            resource_name, namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        codeSigningConfigARN = cr['status']['ackResourceMetadata']['arn']

        time.sleep(CREATE_WAIT_AFTER_SECONDS)

        # Check Lambda code signing config exists
        exists = self.code_signing_config_exists(lambda_client, codeSigningConfigARN)
        assert exists

        # Update cr
        cr["spec"]["description"] = "new description"

        # Patch k8s resource
        k8s.patch_custom_resource(ref, cr)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        # Check code signing config  description
        csc = self.get_code_signing_config(lambda_client, codeSigningConfigARN)
        assert csc is not None
        assert csc["Description"] == "new description"

        # Delete k8s resource
        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # Check Lambda code signing config doesn't exist
        exists = self.code_signing_config_exists(lambda_client, codeSigningConfigARN)
        assert not exists
Пример #8
0
    def test_smoke(self, lambda_client, lambda_function):
        (_, function_resource) = lambda_function
        lambda_function_name = function_resource["spec"]["name"]

        resource_name = random_suffix_name("lambda-alias", 24)

        replacements = REPLACEMENT_VALUES.copy()
        replacements["AWS_REGION"] = get_region()
        replacements["ALIAS_NAME"] = resource_name
        replacements["FUNCTION_NAME"] = lambda_function_name
        replacements["FUNCTION_VERSION"] = "$LATEST"

        # Load alias CR
        resource_data = load_lambda_resource(
            "alias",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
            resource_name, namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        time.sleep(CREATE_WAIT_AFTER_SECONDS)

        # Check alias exists
        alias = self.alias_exist(lambda_client, resource_name, lambda_function_name)
        assert alias is not None

        # Update cr
        cr["spec"]["description"] = ""

        # Patch k8s resource
        k8s.patch_custom_resource(ref, cr)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        # Check alias description
        alias = self.get_alias(lambda_client, resource_name, lambda_function_name)
        assert alias is not None
        assert alias["Description"] == ""

        # Delete k8s resource
        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # Check alias doesn't exist
        exists = self.get_alias(lambda_client, resource_name, lambda_function_name)
        assert not exists
    def test_create_delete_2az(self, rds_client):
        resource_name = "my-db-subnet-group"
        resource_desc = "my-db-subnet-group description"

        br_resources = get_bootstrap_resources()

        replacements = REPLACEMENT_VALUES.copy()
        replacements["DB_SUBNET_GROUP_NAME"] = resource_name
        replacements["DB_SUBNET_GROUP_DESC"] = resource_desc
        replacements["SUBNET_AZ1"] = br_resources.SubnetAZ1
        replacements["SUBNET_AZ2"] = br_resources.SubnetAZ2

        resource_data = load_rds_resource(
            "db_subnet_group_2az",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create the k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
            resource_name, namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        # Let's check that the DB subnet group appears in RDS
        aws_res = rds_client.describe_db_subnet_groups(DBSubnetGroupName=resource_name)
        assert aws_res is not None
        assert len(aws_res['DBSubnetGroups']) == 1

        now = datetime.datetime.now()
        timeout = now + datetime.timedelta(seconds=CREATE_TIMEOUT_SECONDS)

        # TODO(jaypipes): Move this into generic AWS-side waiter
        while aws_res['DBSubnetGroups'][0]['SubnetGroupStatus'] != "Complete":
            if datetime.datetime.now() >= timeout:
                raise Exception("failed to find DB subnet group in Complete status before timeout")
            time.sleep(CREATE_INTERVAL_SLEEP_SECONDS)
            aws_res = rds_client.describe_db_subnet_groups(DBSubnetGroupName=resource_name)
            assert aws_res is not None
            assert len(aws_res['DBSubnetGroups']) == 1

        # Delete the k8s resource on teardown of the module
        k8s.delete_custom_resource(ref)

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # DB subnet group should no longer appear in RDS
        try:
            aws_res = rds_client.describe_db_subnet_groups(DBSubnetGroupName=resource_name)
            assert False
        except rds_client.exceptions.DBSubnetGroupNotFoundFault:
            pass
Пример #10
0
    def test_repository_lifecycle_policy(self, ecr_client):
        resource_name = random_suffix_name("ecr-repository", 24)

        replacements = REPLACEMENT_VALUES.copy()
        replacements["REPOSITORY_NAME"] = resource_name
        # Load ECR CR
        resource_data = load_ecr_resource(
            "repository_lifecycle_policy",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP,
            CRD_VERSION,
            RESOURCE_PLURAL,
            resource_name,
            namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        time.sleep(CREATE_WAIT_AFTER_SECONDS)

        # Check ECR repository exists
        repo = self.get_repository(ecr_client, resource_name)
        assert repo is not None

        # Check ECR repository lifecycle policy exists
        lifecycle_policy = self.get_lifecycle_policy(ecr_client, resource_name,
                                                     repo["registryId"])
        assert lifecycle_policy == LIFECYCLE_POLICY_FILTERING_ON_IMAGE_AGE

        # Remove lifecycle policy
        cr["spec"]["lifecyclePolicy"] = ""

        # Patch k8s resource
        k8s.patch_custom_resource(ref, cr)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        lifecycle_policy = self.get_lifecycle_policy(ecr_client, resource_name,
                                                     repo["registryId"])
        assert lifecycle_policy == ""

        # Delete k8s resource
        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted is True

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # Check ECR repository doesn't exists
        exists = self.repository_exists(ecr_client, resource_name)
        assert not exists
    def test_crud_integration(self, api_resource):
        api_ref, api_cr = api_resource
        api_id = api_cr['status']['apiID']
        test_data = REPLACEMENT_VALUES.copy()
        integration_name = random_suffix_name("ack-test-integration", 25)
        test_data['INTEGRATION_NAME'] = integration_name
        test_data['API_ID'] = api_id
        integration_ref, integration_data = helper.integration_ref_and_data(integration_resource_name=integration_name,
                                                                            replacement_values=test_data)
        logging.debug(f"http api integration resource. name: {integration_name}, data: {integration_data}")

        # test create
        k8s.create_custom_resource(integration_ref, integration_data)
        time.sleep(CREATE_WAIT_AFTER_SECONDS)
        assert k8s.wait_on_condition(integration_ref, "ACK.ResourceSynced", "True", wait_periods=10)

        cr = k8s.get_resource(integration_ref)
        assert cr is not None

        integration_id = cr['status']['integrationID']

        # Let's check that the HTTP Api integration appears in Amazon API Gateway
        apigw_validator.assert_integration_is_present(api_id=api_id, integration_id=integration_id)

        apigw_validator.assert_integration_uri(
            api_id=api_id,
            integration_id=integration_id,
            expected_uri=test_data['INTEGRATION_URI']
        )

        # test update
        updated_uri = 'https://httpbin.org/post'
        test_data['INTEGRATION_URI'] = updated_uri
        updated_integration_resource_data = load_apigatewayv2_resource(
            "integration",
            additional_replacements=test_data,
        )
        logging.debug(f"updated http api integration resource: {updated_integration_resource_data}")

        # Update the k8s resource
        k8s.patch_custom_resource(integration_ref, updated_integration_resource_data)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        condition.assert_synced(integration_ref)
        # Let's check that the HTTP Api integration appears in Amazon API Gateway with updated uri
        apigw_validator.assert_integration_uri(
            api_id=api_id,
            integration_id=integration_id,
            expected_uri=updated_uri
        )

        # test delete
        k8s.delete_custom_resource(integration_ref)
        time.sleep(DELETE_WAIT_AFTER_SECONDS)
        assert not k8s.get_resource_exists(integration_ref)
        # HTTP Api integration should no longer appear in Amazon API Gateway
        apigw_validator.assert_integration_is_deleted(api_id=api_id, integration_id=integration_id)
    def test_crud_stage(self, api_resource):
        api_ref, api_cr = api_resource
        api_id = api_cr['status']['apiID']
        test_data = REPLACEMENT_VALUES.copy()
        stage_name = random_suffix_name("ack-test-stage", 25)
        test_data['STAGE_NAME'] = stage_name
        test_data['API_ID'] = api_id
        stage_ref, stage_data = helper.stage_ref_and_data(stage_resource_name=stage_name,
                                                          replacement_values=test_data)
        logging.debug(f"http api stage resource. name: {stage_name}, data: {stage_data}")

        # test create
        k8s.create_custom_resource(stage_ref, stage_data)
        time.sleep(CREATE_WAIT_AFTER_SECONDS)
        assert k8s.wait_on_condition(stage_ref, "ACK.ResourceSynced", "True", wait_periods=10)

        cr = k8s.get_resource(stage_ref)
        assert cr is not None

        # Let's check that the HTTP Api integration appears in Amazon API Gateway
        apigw_validator.assert_stage_is_present(api_id=api_id, stage_name=stage_name)

        stage_description = test_data['STAGE_DESCRIPTION']
        apigw_validator.assert_stage_description(
            api_id=api_id,
            stage_name=stage_name,
            expected_description=stage_description
        )

        # test update
        updated_description = 'updated' + stage_description
        test_data['STAGE_DESCRIPTION'] = updated_description
        updated_stage_resource_data = load_apigatewayv2_resource(
            "stage",
            additional_replacements=test_data,
        )
        logging.debug(f"updated http api stage resource: {updated_stage_resource_data}")

        # Update the k8s resource
        k8s.patch_custom_resource(stage_ref, updated_stage_resource_data)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        condition.assert_synced(stage_ref)
        # Let's check that the HTTP Api stage appears in Amazon API Gateway with updated description
        apigw_validator.assert_stage_description(
            api_id=api_id,
            stage_name=stage_name,
            expected_description=updated_description
        )

        # test delete
        k8s.delete_custom_resource(stage_ref)
        time.sleep(DELETE_WAIT_AFTER_SECONDS)
        assert not k8s.get_resource_exists(stage_ref)
        # HTTP Api stage should no longer appear in Amazon API Gateway
        apigw_validator.assert_stage_is_deleted(api_id=api_id, stage_name=stage_name)
Пример #13
0
    def test_basic_repository(self, ecr_client):
        resource_name = random_suffix_name("ecr-repository", 24)

        replacements = REPLACEMENT_VALUES.copy()
        replacements["REPOSITORY_NAME"] = resource_name
        # Load ECR CR
        resource_data = load_ecr_resource(
            "repository",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP,
            CRD_VERSION,
            RESOURCE_PLURAL,
            resource_name,
            namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        time.sleep(CREATE_WAIT_AFTER_SECONDS)

        # Check ECR repository exists
        exists = self.repository_exists(ecr_client, resource_name)
        assert exists

        # Update CR
        cr["spec"]["imageScanningConfiguration"]["scanOnPush"] = True

        # Patch k8s resource
        k8s.patch_custom_resource(ref, cr)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        # Check repository scanOnPush scanning configuration
        repo = self.get_repository(ecr_client, resource_name)
        assert repo is not None
        assert repo["imageScanningConfiguration"]["scanOnPush"] is True

        # Delete k8s resource
        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted is True

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # Check ECR repository doesn't exists
        exists = self.repository_exists(ecr_client, resource_name)
        assert not exists
    def test_crud_httpapi_using_import(self):
        test_data = REPLACEMENT_VALUES.copy()
        api_name = random_suffix_name("ack-test-importapi", 25)
        test_data['IMPORT_API_NAME'] = api_name
        test_data['IMPORT_API_TITLE'] = api_name
        api_ref, api_data = helper.import_api_ref_and_data(api_resource_name=api_name,
                                                           replacement_values=test_data)
        logging.debug(f"imported http api resource. name: {api_name}, data: {api_data}")

        # test create
        k8s.create_custom_resource(api_ref, api_data)
        time.sleep(CREATE_API_WAIT_AFTER_SECONDS)
        assert k8s.wait_on_condition(api_ref, "ACK.ResourceSynced", "True", wait_periods=10)

        cr = k8s.get_resource(api_ref)
        assert cr is not None

        api_id = cr['status']['apiID']

        # Let's check that the imported HTTP Api appears in Amazon API Gateway
        apigw_validator.assert_api_is_present(api_id=api_id)

        apigw_validator.assert_api_name(
            api_id=api_id,
            expected_api_name=api_name
        )

        # test update
        updated_api_title = 'updated-' + api_name
        test_data['IMPORT_API_TITLE'] = updated_api_title
        updated_api_resource_data = load_apigatewayv2_resource(
            "import_api",
            additional_replacements=test_data,
        )
        logging.debug(f"updated import http api resource: {updated_api_resource_data}")

        # Update the k8s resource
        k8s.patch_custom_resource(api_ref, updated_api_resource_data)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        condition.assert_synced(api_ref)
        # Let's check that the HTTP Api appears in Amazon API Gateway with updated title
        apigw_validator.assert_api_name(
            api_id=api_id,
            expected_api_name=updated_api_title
        )

        # test delete
        k8s.delete_custom_resource(api_ref)
        time.sleep(DELETE_WAIT_AFTER_SECONDS)
        assert not k8s.get_resource_exists(api_ref)
        # HTTP Api should no longer appear in Amazon API Gateway
        apigw_validator.assert_api_is_deleted(api_id=api_id)
    def test_smoke(self, dynamodb_client, dynamodb_table):
        (_, table_resource) = dynamodb_table
        resource_name = random_suffix_name("backup", 32)
        table_name = table_resource["spec"]["tableName"]

        replacements = REPLACEMENT_VALUES.copy()
        replacements["TABLE_NAME"] = table_name
        replacements["BACKUP_NAME"] = resource_name

        # Load Backup CR
        resource_data = load_dynamodb_resource(
            "backup",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP,
            CRD_VERSION,
            RESOURCE_PLURAL,
            resource_name,
            namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        wait_for_cr_status(
            ref,
            "backupStatus",
            "AVAILABLE",
            10,
            5,
        )

        backupArn = k8s.get_resource_arn(cr)
        # Check DynamoDB Backup exists
        exists = self.backup_exists(dynamodb_client, backupArn)
        assert exists

        # Delete k8s resource
        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted is True

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # Check DynamoDB Backup doesn't exists
        exists = self.backup_exists(dynamodb_client, backupArn)
        assert not exists
    def test_crud_httpapi_using_import(self):
        test_data = REPLACEMENT_VALUES.copy()
        random_suffix = (''.join(
            random.choice(string.ascii_lowercase) for _ in range(6)))
        api_name = "ack-test-importapi-" + random_suffix
        test_data['API_NAME'] = api_name
        test_data['API_TITLE'] = api_name
        api_ref, api_data = helper.import_api_ref_and_data(
            api_resource_name=api_name, replacement_values=test_data)
        logging.debug(
            f"imported http api resource. name: {api_name}, data: {api_data}")

        # test create
        k8s.create_custom_resource(api_ref, api_data)
        cr = k8s.wait_resource_consumed_by_controller(api_ref)

        assert cr is not None
        assert k8s.get_resource_exists(api_ref)

        api_id = cr['status']['apiID']

        # Let's check that the imported HTTP Api appears in Amazon API Gateway
        apigw_validator.assert_api_is_present(api_id=api_id)

        apigw_validator.assert_api_name(api_id=api_id,
                                        expected_api_name=api_name)

        # test update
        updated_api_title = 'updated-' + api_name
        test_data['API_TITLE'] = updated_api_title
        updated_api_resource_data = load_apigatewayv2_resource(
            "import_api",
            additional_replacements=test_data,
        )
        logging.debug(
            f"updated import http api resource: {updated_api_resource_data}")

        # Update the k8s resource
        k8s.patch_custom_resource(api_ref, updated_api_resource_data)
        time.sleep(UPDATE_WAIT_AFTER_SECONDS)

        # Let's check that the HTTP Api appears in Amazon API Gateway with updated title
        apigw_validator.assert_api_name(api_id=api_id,
                                        expected_api_name=updated_api_title)

        # test delete
        k8s.delete_custom_resource(api_ref)
        time.sleep(DELETE_WAIT_AFTER_SECONDS)
        assert not k8s.get_resource_exists(api_ref)
        # HTTP Api should no longer appear in Amazon API Gateway
        apigw_validator.assert_api_is_deleted(api_id=api_id)
Пример #17
0
    def test_create_delete(self, dynamodb_client):
        resource_name = random_suffix_name("table", 32)

        replacements = REPLACEMENT_VALUES.copy()
        replacements["TABLE_NAME"] = resource_name

        # Load Table CR
        resource_data = load_dynamodb_resource(
            "table_forums",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP,
            CRD_VERSION,
            RESOURCE_PLURAL,
            resource_name,
            namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        wait_for_cr_status(
            ref,
            "tableStatus",
            "ACTIVE",
            10,
            5,
        )

        # Check DynamoDB Table exists
        exists = self.table_exists(dynamodb_client, resource_name)
        assert exists

        # Delete k8s resource
        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted is True

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # Check DynamoDB Table doesn't exists
        exists = self.table_exists(dynamodb_client, resource_name)
        assert not exists
Пример #18
0
    def test_smoke(self, dynamodb_client, dynamodb_table):
        (_, table_resource) = dynamodb_table

        # Global Tables must have the same name as dynamodb Tables
        global_table_name = table_resource["spec"]["tableName"]

        replacements = REPLACEMENT_VALUES.copy()
        replacements["REGION_NAME"] = get_region()
        replacements["TABLE_NAME"] = global_table_name
        replacements["GLOBAL_TABLE_NAME"] = global_table_name

        # Load GLobal Table CR
        resource_data = load_dynamodb_resource(
            "global_table",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
            global_table_name, namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        wait_for_cr_status(
            ref,
            "globalTableStatus",
            "ACTIVE",
            10,
            5,
        )

        # Check DynamoDB Global Table exists
        exists = self.global_table_exists(dynamodb_client, global_table_name)
        assert exists

        _, deleted = k8s.delete_custom_resource(ref)
        assert deleted is True        

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        exists = self.global_table_exists(dynamodb_client, global_table_name)
        assert not exists
    def test_create_delete_simple(self, rds_client):
        resource_name = "my-db-security-group"
        resource_desc = "my-db-security-group description"

        br_resources = get_bootstrap_resources()

        replacements = REPLACEMENT_VALUES.copy()
        replacements["DB_SECURITY_GROUP_NAME"] = resource_name
        replacements["DB_SECURITY_GROUP_DESC"] = resource_desc

        resource_data = load_rds_resource(
            "db_security_group_simple",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create the k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP,
            CRD_VERSION,
            RESOURCE_PLURAL,
            resource_name,
            namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        # Let's check that the DB security group appears in RDS
        aws_res = rds_client.describe_db_security_groups(
            DBSecurityGroupName=resource_name)
        assert aws_res is not None
        assert len(aws_res['DBSecurityGroups']) == 1

        # Delete the k8s resource on teardown of the module
        k8s.delete_custom_resource(ref)

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # DB security group should no longer appear in RDS
        try:
            aws_res = rds_client.describe_db_security_groups(
                DBSecurityGroupName=resource_name)
            assert False
        except rds_client.exceptions.DBSecurityGroupNotFoundFault:
            pass
Пример #20
0
    def test_create_delete_aurora_mysql5_7(self, rds_client):
        resource_name = "aurora-mysql-5-7"
        resource_desc = "Parameters for Aurora MySQL 5.7-compatible"

        replacements = REPLACEMENT_VALUES.copy()
        replacements["DB_CLUSTER_PARAMETER_GROUP_NAME"] = resource_name
        replacements["DB_CLUSTER_PARAMETER_GROUP_DESC"] = resource_desc

        resource_data = load_rds_resource(
            "db_cluster_parameter_group_aurora_mysql5.7",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create the k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
            resource_name, namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        # Let's check that the DB cluster parameter group appears in RDS
        aws_res = rds_client.describe_db_cluster_parameter_groups(
            DBClusterParameterGroupName=resource_name,
        )
        assert aws_res is not None
        assert len(aws_res['DBClusterParameterGroups']) == 1

        # Delete the k8s resource on teardown of the module
        k8s.delete_custom_resource(ref)

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # DB cluster parameter group should no longer appear in RDS
        try:
            aws_res = rds_client.describe_db_cluster_parameter_groups(
                DBClusterParameterGroupName=resource_name,
            )
            assert False
        # NOTE(jaypipes): RDS DescribeDBClusterParameterGroups returns
        # DBParameterGroupNotFoundFault, *not* DBClusterParameterGroupNotFound.
        except rds_client.exceptions.DBParameterGroupNotFoundFault:
            pass
Пример #21
0
    def test_create_delete_postgres13_standard(self, rds_client):
        resource_name = "pg13-standard"
        resource_desc = "Parameters for PostgreSQL 13"

        replacements = REPLACEMENT_VALUES.copy()
        replacements["DB_PARAMETER_GROUP_NAME"] = resource_name
        replacements["DB_PARAMETER_GROUP_DESC"] = resource_desc

        resource_data = load_rds_resource(
            "db_parameter_group_postgres13_standard",
            additional_replacements=replacements,
        )
        logging.debug(resource_data)

        # Create the k8s resource
        ref = k8s.CustomResourceReference(
            CRD_GROUP,
            CRD_VERSION,
            RESOURCE_PLURAL,
            resource_name,
            namespace="default",
        )
        k8s.create_custom_resource(ref, resource_data)
        cr = k8s.wait_resource_consumed_by_controller(ref)

        assert cr is not None
        assert k8s.get_resource_exists(ref)

        # Let's check that the DB parameter group appears in RDS
        aws_res = rds_client.describe_db_parameter_groups(
            DBParameterGroupName=resource_name)
        assert aws_res is not None
        assert len(aws_res['DBParameterGroups']) == 1

        # Delete the k8s resource on teardown of the module
        k8s.delete_custom_resource(ref)

        time.sleep(DELETE_WAIT_AFTER_SECONDS)

        # DB parameter group should no longer appear in RDS
        try:
            aws_res = rds_client.describe_db_parameter_groups(
                DBParameterGroupName=resource_name)
            assert False
        except rds_client.exceptions.DBParameterGroupNotFoundFault:
            pass
def stage_resource(route_resource):
    stage_resource_name = random_suffix_name(test_resource_values['STAGE_NAME'], 10)
    test_resource_values['STAGE_NAME'] = stage_resource_name
    stage_ref, stage_data = helper.stage_ref_and_data(stage_resource_name=stage_resource_name,
                                                      replacement_values=test_resource_values)
    logging.debug(f"apigatewayv2 stage resource. name: {stage_resource_name}, data: {stage_data}")

    k8s.create_custom_resource(stage_ref, stage_data)
    time.sleep(CREATE_WAIT_AFTER_SECONDS)
    assert k8s.wait_on_condition(stage_ref, "ACK.ResourceSynced", "True", wait_periods=10)

    cr = k8s.get_resource(stage_ref)
    assert cr is not None

    yield stage_ref, cr

    k8s.delete_custom_resource(stage_ref)
def authorizer_resource(api_resource):
    random_suffix = (''.join(
        random.choice(string.ascii_lowercase) for _ in range(6)))
    authorizer_resource_name = test_resource_values[
        'AUTHORIZER_NAME'] + f'-{random_suffix}'
    test_resource_values['AUTHORIZER_NAME'] = authorizer_resource_name
    authorizer_uri = f'arn:aws:apigateway:{get_region()}:lambda:path/2015-03-31/functions/{get_bootstrap_resources().AuthorizerFunctionArn}/invocations'
    test_resource_values["AUTHORIZER_URI"] = authorizer_uri
    authorizer_ref, authorizer_data = helper.authorizer_ref_and_data(
        authorizer_resource_name=authorizer_resource_name,
        replacement_values=test_resource_values)
    if k8s.get_resource_exists(authorizer_ref):
        raise Exception(
            f"expected {authorizer_resource_name} to not exist. Did previous test cleanup?"
        )
    logging.debug(
        f"apigatewayv2 authorizer resource. name: {authorizer_resource_name}, data: {authorizer_data}"
    )

    k8s.create_custom_resource(authorizer_ref, authorizer_data)
    cr = k8s.wait_resource_consumed_by_controller(authorizer_ref)

    assert cr is not None
    assert k8s.get_resource_exists(authorizer_ref)

    authorizer_id = cr['status']['authorizerID']
    test_resource_values['AUTHORIZER_ID'] = authorizer_id

    # add permissions for apigateway to invoke authorizer lambda
    authorizer_arn = "arn:aws:execute-api:{region}:{account}:{api_id}/authorizers/{authorizer_id}".format(
        region=get_region(),
        account=get_account_id(),
        api_id=test_resource_values['API_ID'],
        authorizer_id=authorizer_id)
    lambda_client = boto3.client("lambda")
    lambda_client.add_permission(
        FunctionName=get_bootstrap_resources().AuthorizerFunctionName,
        StatementId=
        f'apigatewayv2-authorizer-invoke-permissions-{random_suffix}',
        Action='lambda:InvokeFunction',
        Principal='apigateway.amazonaws.com',
        SourceArn=authorizer_arn)

    yield authorizer_ref, cr

    k8s.delete_custom_resource(authorizer_ref)
def route_resource(integration_resource, authorizer_resource):
    route_resource_name = random_suffix_name(test_resource_values['ROUTE_NAME'], 25)
    test_resource_values['ROUTE_NAME'] = route_resource_name
    route_ref, route_data = helper.route_ref_and_data(route_resource_name=route_resource_name,
                                                      replacement_values=test_resource_values)

    k8s.create_custom_resource(route_ref, route_data)
    time.sleep(CREATE_WAIT_AFTER_SECONDS)
    assert k8s.wait_on_condition(route_ref, "ACK.ResourceSynced", "True", wait_periods=10)

    cr = k8s.get_resource(route_ref)
    assert cr is not None

    route_id = cr['status']['routeID']
    test_resource_values['ROUTE_ID'] = route_id

    yield route_ref, cr

    k8s.delete_custom_resource(route_ref)
Пример #25
0
def lambda_function():
    resource_name = random_suffix_name("lambda-function", 24)
    resources = get_bootstrap_resources()

    replacements = REPLACEMENT_VALUES.copy()
    replacements["FUNCTION_NAME"] = resource_name
    replacements["BUCKET_NAME"] = resources.FunctionsBucketName
    replacements["LAMBDA_ROLE"] = resources.LambdaESMRoleARN
    replacements["LAMBDA_FILE_NAME"] = resources.LambdaFunctionFileZip
    replacements["RESERVED_CONCURRENT_EXECUTIONS"] = "0"
    replacements["CODE_SIGNING_CONFIG_ARN"] = ""
    replacements["AWS_REGION"] = get_region()

    # Load function CR
    resource_data = load_lambda_resource(
        "function",
        additional_replacements=replacements,
    )
    logging.debug(resource_data)

    # Create k8s resource
    function_reference = k8s.CustomResourceReference(
        CRD_GROUP,
        CRD_VERSION,
        "functions",
        resource_name,
        namespace="default",
    )

    # Create lambda function
    k8s.create_custom_resource(function_reference, resource_data)
    function_resource = k8s.wait_resource_consumed_by_controller(
        function_reference)

    assert function_resource is not None
    assert k8s.get_resource_exists(function_reference)

    time.sleep(CREATE_WAIT_AFTER_SECONDS)

    yield (function_reference, function_resource)

    _, deleted = k8s.delete_custom_resource(function_reference)
    assert deleted
    def _make_replication_group(yaml_name, input_dict, rg_name):
        rg = load_elasticache_resource(
            yaml_name, additional_replacements=input_dict)
        logging.debug(rg)

        reference = k8s.CustomResourceReference(
            CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL, rg_name, namespace="default")
        _ = k8s.create_custom_resource(reference, rg)
        resource = k8s.wait_resource_consumed_by_controller(reference, wait_periods=10)
        assert resource is not None
        return (reference, resource)
def api_resource():
    api_resource_name = random_suffix_name(test_resource_values['API_NAME'], 20)
    test_resource_values['API_NAME'] = api_resource_name
    api_ref, api_data = helper.api_ref_and_data(api_resource_name=api_resource_name,
                                                replacement_values=test_resource_values)
    if k8s.get_resource_exists(api_ref):
        raise Exception(f"expected {api_resource_name} to not exist. Did previous test cleanup?")
    logging.debug(f"http api resource. name: {api_resource_name}, data: {api_data}")

    k8s.create_custom_resource(api_ref, api_data)
    time.sleep(CREATE_API_WAIT_AFTER_SECONDS)
    assert k8s.wait_on_condition(api_ref, "ACK.ResourceSynced", "True", wait_periods=10)

    cr = k8s.get_resource(api_ref)
    assert cr is not None

    api_id = cr['status']['apiID']
    test_resource_values['API_ID'] = api_id

    yield api_ref, cr

    k8s.delete_custom_resource(api_ref)
def dynamodb_table():
    resource_name = random_suffix_name("table", 32)

    replacements = REPLACEMENT_VALUES.copy()
    replacements["TABLE_NAME"] = resource_name

    # load resource
    resource_data = load_dynamodb_resource(
        "table_forums",
        additional_replacements=replacements,
    )

    table_reference = k8s.CustomResourceReference(
        CRD_GROUP,
        CRD_VERSION,
        "tables",
        resource_name,
        namespace="default",
    )

    # Create table
    k8s.create_custom_resource(table_reference, resource_data)
    table_resource = k8s.wait_resource_consumed_by_controller(table_reference)

    assert table_resource is not None
    assert k8s.get_resource_exists(table_reference)

    wait_for_cr_status(
        table_reference,
        "tableStatus",
        "ACTIVE",
        10,
        30,
    )

    yield (table_reference, table_resource)

    _, deleted = k8s.delete_custom_resource(table_reference)
    assert deleted
def code_signing_config():
    resource_name = random_suffix_name("lambda-csc", 24)

    resources = get_bootstrap_resources()
    logging.debug(resources)

    replacements = REPLACEMENT_VALUES.copy()
    replacements["AWS_REGION"] = get_region()
    replacements["CODE_SIGNING_CONFIG_NAME"] = resource_name
    replacements[
        "SIGNING_PROFILE_VERSION_ARN"] = resources.SigningProfileVersionArn

    # Load Lambda CR
    resource_data = load_lambda_resource(
        "code_signing_config",
        additional_replacements=replacements,
    )
    logging.debug(resource_data)

    # Create k8s resource
    ref = k8s.CustomResourceReference(
        CRD_GROUP,
        CRD_VERSION,
        "codesigningconfigs",
        resource_name,
        namespace="default",
    )
    k8s.create_custom_resource(ref, resource_data)
    cr = k8s.wait_resource_consumed_by_controller(ref)

    assert cr is not None
    assert k8s.get_resource_exists(ref)

    time.sleep(CREATE_WAIT_AFTER_SECONDS)

    yield (ref, cr)

    _, deleted = k8s.delete_custom_resource(ref)
    assert deleted
def integration_resource(api_resource):
    integration_resource_name = random_suffix_name(test_resource_values['INTEGRATION_NAME'], 25)
    test_resource_values['INTEGRATION_NAME'] = integration_resource_name
    integration_ref, integration_data = helper.integration_ref_and_data(
        integration_resource_name=integration_resource_name,
        replacement_values=test_resource_values)
    if k8s.get_resource_exists(integration_ref):
        raise Exception(f"expected {integration_resource_name} to not exist. Did previous test cleanup?")
    logging.debug(f"apigatewayv2 integration resource. name: {integration_resource_name}, data: {integration_data}")

    k8s.create_custom_resource(integration_ref, integration_data)
    time.sleep(CREATE_WAIT_AFTER_SECONDS)
    assert k8s.wait_on_condition(integration_ref, "ACK.ResourceSynced", "True", wait_periods=10)

    cr = k8s.get_resource(integration_ref)
    assert cr is not None

    integration_id = cr['status']['integrationID']
    test_resource_values['INTEGRATION_ID'] = integration_id

    yield integration_ref, cr

    k8s.delete_custom_resource(integration_ref)