From af771515b4902920390d5f3b69ef9b7e71546ca1 Mon Sep 17 00:00:00 2001 From: Bikouo Aubin <79859644+abikouo@users.noreply.github.com> Date: Wed, 7 Dec 2022 13:42:25 +0100 Subject: [PATCH] lambda_layer_info - add support for version_number (#1293) lambda_layer_info - add support for version_number SUMMARY ISSUE TYPE Feature Pull Request COMPONENT NAME lambda_layer_info Reviewed-by: Alina Buzachis Reviewed-by: Bikouo Aubin --- ...layer_info-add-parameter-layer_version.yml | 3 + plugins/modules/lambda_layer_info.py | 82 ++++++++++++++++--- .../plugins/modules/test_lambda_layer_info.py | 61 ++++++++++++++ 3 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 changelogs/fragments/lambda_layer_info-add-parameter-layer_version.yml diff --git a/changelogs/fragments/lambda_layer_info-add-parameter-layer_version.yml b/changelogs/fragments/lambda_layer_info-add-parameter-layer_version.yml new file mode 100644 index 00000000000..92f60030ba0 --- /dev/null +++ b/changelogs/fragments/lambda_layer_info-add-parameter-layer_version.yml @@ -0,0 +1,3 @@ +--- +minor_changes: +- lambda_layer_info - add support for parameter version_number to retrieve detailed information for a specific layer version (https://github.com/ansible-collections/amazon.aws/pull/1241). diff --git a/plugins/modules/lambda_layer_info.py b/plugins/modules/lambda_layer_info.py index 2d2ab3c9f32..284b4726e4b 100644 --- a/plugins/modules/lambda_layer_info.py +++ b/plugins/modules/lambda_layer_info.py @@ -19,6 +19,14 @@ type: str aliases: - layer_name + version_number: + description: + - The Lambda layer version number to retrieve. + - Requires I(name) to be provided. + type: int + aliases: + - layer_version + version_added: 5.2.0 compatible_runtime: description: - A runtime identifier. @@ -62,6 +70,12 @@ - name: list latest versions for all layers amazon.aws.lambda_layer_info: compatible_runtime: python3.7 + +# Retrieve specific lambda layer information +- name: Get lambda layer version information + amazon.aws.lambda_layer_info: + name: my-layer + version_number: 1 ''' RETURN = ''' @@ -110,6 +124,30 @@ description: A list of compatible instruction set architectures. returned: if it was defined for the layer version. type: list + content: + description: Details about the layer version. + returned: if I(version_number) was provided + type: complex + version_added: 5.2.0 + contains: + location: + description: A link to the layer archive in Amazon S3 that is valid for 10 minutes. + type: str + sample: 'https://awslambda-us-east-2-layers.s3.us-east-2.amazonaws.com/snapshots/123456789012/mylayer-4aaa2fbb-96a?versionId=27iWyA73c...' + code_sha256: + description: The SHA-256 hash of the layer archive. + type: str + sample: 'tv9jJO+rPbXUUXuRKi7CwHzKtLDkDRJLB3cC3Z/ouXo=' + code_size: + description: The size of the layer archive in bytes. + type: int + sample: 169 + signing_profile_version_arn: + description: The Amazon Resource Name (ARN) for a signing profile version. + type: str + signing_job_arn: + description: The Amazon Resource Name (ARN) of a signing job. + type: str ''' try: @@ -175,23 +213,39 @@ def list_layers(lambda_client, compatible_runtime=None, compatible_architecture= raise LambdaLayerInfoFailure(exc=e, msg="Unable to list layers {0}".format(params)) +def get_layer_version(lambda_client, layer_name, version_number): + + try: + layer_version = lambda_client.get_layer_version(LayerName=layer_name, VersionNumber=version_number) + if layer_version: + layer_version.pop("ResponseMetadata") + return [camel_dict_to_snake_dict(layer_version)] + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: + raise LambdaLayerInfoFailure(exc=e, msg="get_layer_version() failed.") + + def execute_module(module, lambda_client): - params = {} - f_operation = list_layers name = module.params.get("name") - if name is not None: - f_operation = list_layer_versions - params["name"] = name - compatible_runtime = module.params.get("compatible_runtime") - if compatible_runtime is not None: - params["compatible_runtime"] = compatible_runtime - compatible_architecture = module.params.get("compatible_architecture") - if compatible_architecture is not None: - params["compatible_architecture"] = compatible_architecture + version_number = module.params.get("version_number") try: - result = f_operation(lambda_client, **params) + if name is not None and version_number is not None: + result = get_layer_version(lambda_client, name, version_number) + else: + params = {} + f_operation = list_layers + if name is not None: + f_operation = list_layer_versions + params["name"] = name + compatible_runtime = module.params.get("compatible_runtime") + if compatible_runtime is not None: + params["compatible_runtime"] = compatible_runtime + compatible_architecture = module.params.get("compatible_architecture") + if compatible_architecture is not None: + params["compatible_architecture"] = compatible_architecture + result = f_operation(lambda_client, **params) + module.exit_json(changed=False, layers_versions=result) except LambdaLayerInfoFailure as e: module.fail_json_aws(exception=e.exc, msg=e.msg) @@ -202,11 +256,15 @@ def main(): name=dict(type="str", aliases=["layer_name"]), compatible_runtime=dict(type="str"), compatible_architecture=dict(type="str"), + version_number=dict(type="int", aliases=["layer_version"]), ) module = AnsibleAWSModule( argument_spec=argument_spec, supports_check_mode=True, + required_by=dict( + version_number=('name', ) + ) ) lambda_client = module.client('lambda') diff --git a/tests/unit/plugins/modules/test_lambda_layer_info.py b/tests/unit/plugins/modules/test_lambda_layer_info.py index 17a6386d186..eda29604da8 100644 --- a/tests/unit/plugins/modules/test_lambda_layer_info.py +++ b/tests/unit/plugins/modules/test_lambda_layer_info.py @@ -248,6 +248,67 @@ def raise_botocore_exception(): return BotoCoreError(error="failed", operation="list_layers") +def test_get_layer_version_success(): + + aws_layer_version = { + "CompatibleRuntimes": [ + "python3.8" + ], + "Content": { + "CodeSha256": "vqxKx6nTW31obVcB4MYaTWv5H3fBQTn2PHklL9+mF9E=", + "CodeSize": 9492621, + "Location": "https://test.s3.us-east-1.amazonaws.com/snapshots/123456789012/test-79b29d149e06?versionId=nmEKA3ZgiP7hce3J" + }, + "CreatedDate": "2022-12-05T10:47:32.379+0000", + "Description": "Python units test layer", + "LayerArn": "arn:aws:lambda:us-east-1:123456789012:layer:test", + "LayerVersionArn": "arn:aws:lambda:us-east-1:123456789012:layer:test:2", + "LicenseInfo": "GPL-3.0-only", + "Version": 2, + "ResponseMetadata": { + "some-metadata": "some-result" + } + } + + ansible_layer_version = { + "compatible_runtimes": [ + "python3.8" + ], + "content": { + "code_sha256": "vqxKx6nTW31obVcB4MYaTWv5H3fBQTn2PHklL9+mF9E=", + "code_size": 9492621, + "location": "https://test.s3.us-east-1.amazonaws.com/snapshots/123456789012/test-79b29d149e06?versionId=nmEKA3ZgiP7hce3J" + }, + "created_date": "2022-12-05T10:47:32.379+0000", + "description": "Python units test layer", + "layer_arn": "arn:aws:lambda:us-east-1:123456789012:layer:test", + "layer_version_arn": "arn:aws:lambda:us-east-1:123456789012:layer:test:2", + "license_info": "GPL-3.0-only", + "version": 2 + } + + lambda_client = MagicMock() + lambda_client.get_layer_version.return_value = aws_layer_version + + layer_name = "test" + layer_version = 2 + + assert [ansible_layer_version] == lambda_layer_info.get_layer_version(lambda_client, layer_name, layer_version) + lambda_client.get_layer_version.assert_called_once_with(LayerName=layer_name, VersionNumber=layer_version) + + +def test_get_layer_version_failure(): + + lambda_client = MagicMock() + lambda_client.get_layer_version.side_effect = raise_botocore_exception() + + layer_name = MagicMock() + layer_version = MagicMock() + + with pytest.raises(lambda_layer_info.LambdaLayerInfoFailure): + lambda_layer_info.get_layer_version(lambda_client, layer_name, layer_version) + + @pytest.mark.parametrize( "params", [