Skip to content

Commit

Permalink
feat: enrich image lambda functions
Browse files Browse the repository at this point in the history
  • Loading branch information
moelasmar committed Aug 31, 2022
1 parent b6ac337 commit 760455a
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 2 deletions.
61 changes: 59 additions & 2 deletions samcli/hook_packages/terraform/hooks/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from samcli.lib.hook.exceptions import PrepareHookException, InvalidSamMetadataPropertiesException
from samcli.lib.utils import osutils
from samcli.lib.utils.hash import str_checksum
from samcli.lib.utils.packagetype import ZIP
from samcli.lib.utils.packagetype import ZIP, IMAGE
from samcli.lib.utils.resources import (
AWS_LAMBDA_FUNCTION as CFN_AWS_LAMBDA_FUNCTION,
)
Expand Down Expand Up @@ -483,7 +483,64 @@ def _enrich_zip_lambda_function(sam_metadata_resource: Dict, cfn_resource: Dict,
cfn_resource["Metadata"]["ProjectRootDirectory"] = terraform_application_dir

def _enrich_image_lambda_function(sam_metadata_resource: Dict, cfn_resource: Dict, cfn_resource_logical_id: str):
pass
sam_metadata_attributes = sam_metadata_resource.get("values", {}).get("triggers", {})
sam_metadata_resource_address = sam_metadata_resource.get("address")
if not sam_metadata_resource_address:
raise PrepareHookException(
"Invalid Terraform plan output. The address property should not be null to any terraform resource."
)
cfn_resource_properties = cfn_resource.get("Properties", {})

LOG.info(
"Enrich the IMAGE lambda function %s using the metadata properties defined in resource %s",
cfn_resource_logical_id,
sam_metadata_resource_address,
)

_validate_referenced_resource_matches_sam_metadata_type(
cfn_resource, sam_metadata_attributes, sam_metadata_resource_address, IMAGE
)

cfn_docker_context_path = _get_lambda_function_source_code_path(
sam_metadata_attributes,
sam_metadata_resource_address,
terraform_application_dir,
"docker_context",
"docker_context_property_path",
"docker context",
)
cfn_docker_file = sam_metadata_attributes.get("docker_file")
cfn_docker_build_args_string = sam_metadata_attributes.get("docker_build_args")
if cfn_docker_build_args_string:
try:
LOG.debug("Parse the docker build args %s", cfn_docker_build_args_string)
cfn_docker_build_args = json.loads(cfn_docker_build_args_string)
if not isinstance(cfn_docker_build_args, dict):
raise InvalidSamMetadataPropertiesException(
f"The sam metadata resource {sam_metadata_resource_address} should contain a valid json "
f"encoded string for the lambda function docker build arguments."
)
except JSONDecodeError as exc:
raise InvalidSamMetadataPropertiesException(
f"The sam metadata resource {sam_metadata_resource_address} should contain a valid json encoded "
f"string for the lambda function docker build arguments."
) from exc

cfn_docker_tag = sam_metadata_attributes.get("docker_tag")

if cfn_resource_properties.get("Code"):
cfn_resource_properties.pop("Code")

if not cfn_resource.get("Metadata", {}):
cfn_resource["Metadata"] = {}
cfn_resource["Metadata"]["SkipBuild"] = False
cfn_resource["Metadata"]["DockerContext"] = cfn_docker_context_path
if cfn_docker_file:
cfn_resource["Metadata"]["Dockerfile"] = cfn_docker_file
if cfn_docker_tag:
cfn_resource["Metadata"]["DockerTag"] = cfn_docker_tag
if cfn_docker_build_args:
cfn_resource["Metadata"]["DockerBuildArgs"] = cfn_docker_build_args

resources_types_enrichment_functions = {
"ZIP_LAMBDA_FUNCTION": _enrich_zip_lambda_function,
Expand Down
133 changes: 133 additions & 0 deletions tests/unit/hook_packages/terraform/test_prepare_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,139 @@ def test_enrich_mapped_resources_zip_functions(
_enrich_mapped_resources(sam_metadata_resources, cfn_resources, "/output/dir", "/terraform/project/root")
self.assertEquals(cfn_resources, expected_cfn_resources)

@patch("samcli.hook_packages.terraform.hooks.prepare._get_relevant_cfn_resource")
@patch("samcli.hook_packages.terraform.hooks.prepare._validate_referenced_resource_matches_sam_metadata_type")
@patch("samcli.hook_packages.terraform.hooks.prepare._get_lambda_function_source_code_path")
def test_enrich_mapped_resources_image_functions(
self,
mock_get_lambda_function_source_code_path,
mock_validate_referenced_resource_matches_sam_metadata_type,
mock_get_relevant_cfn_resource,
):
mock_get_lambda_function_source_code_path.side_effect = ["src/code/path1", "src/code/path2"]
image_function_1 = {
"Type": CFN_AWS_LAMBDA_FUNCTION,
"Properties": {
**self.expected_cfn_image_package_type_function_common_properties,
"ImageConfig": {
"Command": ["cmd1", "cmd2"],
"EntryPoint": ["entry1", "entry2"],
"WorkingDirectory": "/working/dir/path",
},
"Code": {
"ImageUri": "image/uri:tag",
},
},
"Metadata": {"SamResourceId": f"aws_lambda_function.func1", "SkipBuild": True},
}

cfn_resources = {
"logical_id1": image_function_1,
}
mock_get_relevant_cfn_resource.side_effect = [
(image_function_1, "logical_id1"),
]
sam_metadata_resources = [
SamMetadataResource(
current_module_address=None,
resource=self.tf_image_package_type_lambda_function_resource_sam_metadata,
),
]

expected_image_function_1 = {
"Type": CFN_AWS_LAMBDA_FUNCTION,
"Properties": {
**self.expected_cfn_image_package_type_function_common_properties,
"ImageConfig": {
"Command": ["cmd1", "cmd2"],
"EntryPoint": ["entry1", "entry2"],
"WorkingDirectory": "/working/dir/path",
},
},
"Metadata": {
"SamResourceId": "aws_lambda_function.func1",
"SkipBuild": False,
"DockerContext": "src/code/path1",
"Dockerfile": "Dockerfile",
"DockerTag": "2.0",
"DockerBuildArgs": {"FOO": "bar"},
},
}

expected_cfn_resources = {
"logical_id1": expected_image_function_1,
}

_enrich_mapped_resources(sam_metadata_resources, cfn_resources, "/output/dir", "/terraform/project/root")
self.assertEquals(cfn_resources, expected_cfn_resources)

@parameterized.expand(
[
("ABCDEFG",),
('"ABCDEFG"',),
]
)
@patch("samcli.hook_packages.terraform.hooks.prepare._get_relevant_cfn_resource")
@patch("samcli.hook_packages.terraform.hooks.prepare._validate_referenced_resource_matches_sam_metadata_type")
@patch("samcli.hook_packages.terraform.hooks.prepare._get_lambda_function_source_code_path")
def test_enrich_mapped_resources_image_functions_invalid_docker_args(
self,
docker_args_value,
mock_get_lambda_function_source_code_path,
mock_validate_referenced_resource_matches_sam_metadata_type,
mock_get_relevant_cfn_resource,
):
mock_get_lambda_function_source_code_path.side_effect = ["src/code/path1", "src/code/path2"]
image_function_1 = {
"Type": CFN_AWS_LAMBDA_FUNCTION,
"Properties": {
**self.expected_cfn_image_package_type_function_common_properties,
"ImageConfig": {
"Command": ["cmd1", "cmd2"],
"EntryPoint": ["entry1", "entry2"],
"WorkingDirectory": "/working/dir/path",
},
"Code": {
"ImageUri": "image/uri:tag",
},
},
"Metadata": {"SamResourceId": f"aws_lambda_function.func1", "SkipBuild": True},
}

cfn_resources = {
"logical_id1": image_function_1,
}
mock_get_relevant_cfn_resource.side_effect = [
(image_function_1, "logical_id1"),
]
sam_metadata_resources = [
SamMetadataResource(
current_module_address=None,
resource={
**self.tf_sam_metadata_resource_common_attributes,
"values": {
"triggers": {
"resource_name": f"aws_lambda_function.{self.image_function_name}",
"docker_build_args": docker_args_value,
"docker_context": "context",
"docker_file": "Dockerfile",
"docker_tag": "2.0",
"resource_type": "IMAGE_LAMBDA_FUNCTION",
},
},
"address": f"null_resource.sam_metadata_{self.image_function_name}",
"name": f"sam_metadata_{self.image_function_name}",
},
),
]

with self.assertRaises(
InvalidSamMetadataPropertiesException,
msg="The sam metadata resource null_resource.sam_metadata_func1 should contain a valid json encoded "
"string for the lambda function docker build arguments.",
):
_enrich_mapped_resources(sam_metadata_resources, cfn_resources, "/output/dir", "/terraform/project/root")

def test_enrich_mapped_resources_invalid_source_type(self):
image_function_1 = {
"Type": CFN_AWS_LAMBDA_FUNCTION,
Expand Down

0 comments on commit 760455a

Please sign in to comment.