diff --git a/CHANGELOG.md b/CHANGELOG.md index 44717fd5e8f6..da45b4c92bbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -222,6 +222,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - **CUMULUS-4388** - Added cnm_to_cma task (lambda). - Original cnm_to_cma was written in Java. Converted to Python. +- **CUMULUS-4504** + - Added cnm_to_cma CI integration test - **CUMULUS-4382** - Migrated the granule-invalidator task to the `tasks` directory as part of a coreification task in support of providing rolling archive functionality. - **CUMULUS-4385** diff --git a/example/cumulus-tf/cnm_workflow.asl.json b/example/cumulus-tf/cnm_workflow.asl.json index fa7b1538a06d..e85c3be98562 100644 --- a/example/cumulus-tf/cnm_workflow.asl.json +++ b/example/cumulus-tf/cnm_workflow.asl.json @@ -19,7 +19,7 @@ "destination": "{$.meta.cnm}" }, { - "source": "{$.output}", + "source": "{$.output_granules}", "destination": "{$.payload}" } ] diff --git a/example/spec/parallel/cnmWorkflow/KinesisTestTriggerSpec.js b/example/spec/parallel/cnmWorkflow/KinesisTestTriggerSpec.js index f470a91de052..df8036e33e53 100644 --- a/example/spec/parallel/cnmWorkflow/KinesisTestTriggerSpec.js +++ b/example/spec/parallel/cnmWorkflow/KinesisTestTriggerSpec.js @@ -5,7 +5,6 @@ const crypto = require('crypto'); const cloneDeep = require('lodash/cloneDeep'); const get = require('lodash/get'); const isMatch = require('lodash/isMatch'); -const path = require('path'); const replace = require('lodash/replace'); const { getJsonS3Object } = require('@cumulus/aws-client/S3'); const { @@ -78,7 +77,6 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { let executionStatus; let expectedSyncGranulesPayload; let expectedTranslatePayload; - let fileData; let filePrefix; let granuleId; let lambdaStep; @@ -161,32 +159,23 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { { source_bucket: testConfig.bucket, name: recordFile.name, + filename: recordFile.name, type: recordFile.type, - bucket: testConfig.bucket, path: testDataFolder, - url_path: recordFile.uri, - size: recordFile.size, - checksumType: recordFile.checksumType, - checksum: recordFile.checksum, - fileName: recordFile.name, - key: path.join(testDataFolder, recordFile.name), }, ], }, ], }; - fileData = expectedTranslatePayload.granules[0].files[0]; filePrefix = `file-staging/${testConfig.stackName}/${record.collection}___000/${crypto.createHash('md5').update(record.product.name).digest('hex')}`; const fileDataWithFilename = { bucket: testConfig.buckets.private.name, key: `${filePrefix}/${recordFile.name}`, fileName: recordFile.name, - size: fileData.size, + size: recordFile.size, type: recordFile.type, - checksumType: recordFile.checksumType, - checksum: recordFile.checksum, source: `${testDataFolder}/${recordFile.name}`, }; @@ -301,7 +290,7 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { describe('the TranslateMessage Lambda', () => { let lambdaOutput; beforeAll(async () => { - lambdaOutput = await lambdaStep.getStepOutput(workflowExecution.executionArn, 'CNMToCMA'); + lambdaOutput = await lambdaStep.getStepOutput(workflowExecution.executionArn, 'CnmToCma'); }); it('outputs the expectedTranslatePayload object', () => { @@ -327,7 +316,7 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { let startStep; let endStep; beforeAll(async () => { - startStep = await lambdaStep.getStepInput(workflowExecution.executionArn, 'CNMToCMA'); + startStep = await lambdaStep.getStepInput(workflowExecution.executionArn, 'CnmToCma'); endStep = await lambdaStep.getStepOutput(workflowExecution.executionArn, 'CnmResponse'); }); @@ -456,7 +445,7 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { prefix: testConfig.stackName, granuleId, collectionId: constructCollectionId(ruleOverride.collection.name, ruleOverride.collection.version), - }); + }).catch(() => undefined); }); it('executes but fails', () => { @@ -472,23 +461,10 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { describe('the CnmResponse Lambda', () => { let beforeAllFailed = false; let lambdaOutput; - let failedGranule; beforeAll(async () => { try { lambdaOutput = await lambdaStep.getStepOutput(failingWorkflowExecution.executionArn, 'CnmResponse'); - failedGranule = await waitForApiRecord( - getGranule, - { - prefix: testConfig.stackName, - granuleId: record.product.name, - collectionId: constructCollectionId(ruleOverride.collection.name, ruleOverride.collection.version), - }, - { - status: 'failed', - execution: getExecutionUrlFromArn(failingWorkflowExecution.executionArn), - } - ); } catch (error) { beforeAllFailed = true; console.log('CnmResponse Lambda error:::', error); @@ -520,10 +496,22 @@ describe('The Cloud Notification Mechanism Kinesis workflow', () => { } }); - it('puts cnm message to cumulus message for granule record', () => { - const cnm = get(lambdaOutput, 'meta.granule.queryFields.cnm'); - expect(isMatch(cnm, badRecord)).toBe(true); - expect(get(failedGranule, 'queryFields.cnm')).toEqual(cnm); + it('puts cnm message on the CnmResponse output', () => { + const cnm = get(lambdaOutput, 'meta.cnmResponse'); + expect(cnm).toEqual(jasmine.objectContaining({ + version: badRecord.version, + submissionTime: badRecord.submissionTime, + collection: badRecord.collection, + provider: badRecord.provider, + identifier: badRecord.identifier, + receivedTime: jasmine.any(String), + response: jasmine.objectContaining({ + status: 'FAILURE', + errorCode: 'TRANSFER_ERROR', + }), + processCompleteTime: jasmine.any(String), + })); + expect(cnm.product).toBeUndefined(); }); }); }); diff --git a/example/spec/parallel/cnmWorkflow/KinesisTestTriggerWithUniqueGranuleIdsSpec.js b/example/spec/parallel/cnmWorkflow/KinesisTestTriggerWithUniqueGranuleIdsSpec.js index efc9310bcf36..db73139ea1ac 100644 --- a/example/spec/parallel/cnmWorkflow/KinesisTestTriggerWithUniqueGranuleIdsSpec.js +++ b/example/spec/parallel/cnmWorkflow/KinesisTestTriggerWithUniqueGranuleIdsSpec.js @@ -5,7 +5,6 @@ const crypto = require('crypto'); const cloneDeep = require('lodash/cloneDeep'); const get = require('lodash/get'); const isMatch = require('lodash/isMatch'); -const path = require('path'); const replace = require('lodash/replace'); const { getJsonS3Object } = require('@cumulus/aws-client/S3'); const { @@ -86,7 +85,6 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI let expectedSyncGranulesPayload; let expectedTranslatePayload; let failingWorkflowExecution; - let fileData; let initialExecutionStatus; let initialRecord; let initialRuleDirectory; @@ -200,31 +198,21 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI { source_bucket: testConfig.bucket, name: recordFile.name, + filename: recordFile.name, type: recordFile.type, - bucket: testConfig.bucket, path: testDataFolder, - url_path: recordFile.uri, - size: recordFile.size, - checksumType: recordFile.checksumType, - checksum: recordFile.checksum, - fileName: recordFile.name, - key: path.join(testDataFolder, recordFile.name), }, ], }, ], }; - fileData = expectedTranslatePayload.granules[0].files[0]; - const fileDataWithFilename = { bucket: testConfig.buckets.private.name, key: 'key_placeholder', fileName: recordFile.name, - size: fileData.size, + size: recordFile.size, type: recordFile.type, - checksumType: recordFile.checksumType, - checksum: recordFile.checksum, source: `${testDataFolder}/${recordFile.name}`, }; @@ -331,7 +319,7 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI describe('the TranslateMessage Lambda', () => { let lambdaOutput; beforeAll(async () => { - lambdaOutput = await lambdaStep.getStepOutput(initialWorkflowExecution.executionArn, 'CNMToCMA'); + lambdaOutput = await lambdaStep.getStepOutput(initialWorkflowExecution.executionArn, 'CnmToCma'); }); it('outputs the expectedTranslatePayload object', () => { @@ -357,7 +345,7 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI let startStep; let endStep; beforeAll(async () => { - startStep = await lambdaStep.getStepInput(initialWorkflowExecution.executionArn, 'CNMToCMA'); + startStep = await lambdaStep.getStepInput(initialWorkflowExecution.executionArn, 'CnmToCma'); endStep = await lambdaStep.getStepOutput(initialWorkflowExecution.executionArn, 'CnmResponse'); }); @@ -615,23 +603,10 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI describe('the CnmResponse Lambda', () => { let beforeAllFailed = false; let lambdaOutput; - let failedGranule; beforeAll(async () => { try { lambdaOutput = await lambdaStep.getStepOutput(failingWorkflowExecution.executionArn, 'CnmResponse'); - failedGranule = await waitForApiRecord( - getGranule, - { - prefix: testConfig.stackName, - granuleId: uniqueGranuleIdError, - collectionId: constructCollectionId(initialRuleOverride.collection.name, initialRuleOverride.collection.version), - }, - { - status: 'failed', - execution: getExecutionUrlFromArn(failingWorkflowExecution.executionArn), - } - ); } catch (error) { beforeAllFailed = true; console.log('CnmResponse Lambda error:::', error); @@ -643,10 +618,6 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI if (beforeAllFailed) fail('beforeAll() failed to prepare test suite'); }); - it('failed granule has the same granuleId as successful granule', () => { - expect(failedGranule.granuleId === existingGranuleId); - }); - it('sends the error to the CnmResponse task', async () => { const CnmResponseInput = await lambdaStep.getStepInput(failingWorkflowExecution.executionArn, 'CnmResponse'); expect(CnmResponseInput.exception.Error).toEqual('FileNotFound'); @@ -667,10 +638,22 @@ describe('The Cloud Notification Mechanism Kinesis workflow with Unique GranuleI } }); - it('puts cnm message to cumulus message for granule record', () => { - const cnm = get(lambdaOutput, 'meta.granule.queryFields.cnm'); - expect(isMatch(cnm, badRecord)).toBe(true); - expect(get(failedGranule, 'queryFields.cnm')).toEqual(cnm); + it('puts cnm message on the CnmResponse output', () => { + const cnm = get(lambdaOutput, 'meta.cnmResponse'); + expect(cnm).toEqual(jasmine.objectContaining({ + version: badRecord.version, + submissionTime: badRecord.submissionTime, + collection: badRecord.collection, + provider: badRecord.provider, + identifier: badRecord.identifier, + receivedTime: jasmine.any(String), + response: jasmine.objectContaining({ + status: 'FAILURE', + errorCode: 'TRANSFER_ERROR', + }), + processCompleteTime: jasmine.any(String), + })); + expect(cnm.product).toBeUndefined(); }); }); }); diff --git a/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154.json b/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154.json index 54bdae308208..98d288c164a5 100644 --- a/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154.json +++ b/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154.json @@ -2,7 +2,7 @@ "version": "1.5", "provider": "PODAAC_SWOT", "collection": "L2_HR_PIXC", - "submissionTime": "2017-09-30T03:42:29.791198", + "submissionTime": "2017-09-30T03:42:29.791198Z", "identifier": "<>", "product": { "name": "L2_HR_PIXC_product_0001-of-4154", diff --git a/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154_dupe.json b/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154_dupe.json index b1b2b498aa11..58984776d866 100644 --- a/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154_dupe.json +++ b/example/spec/parallel/cnmWorkflow/data/records/L2_HR_PIXC_product_0001-of-4154_dupe.json @@ -2,7 +2,7 @@ "version": "1.5", "provider": "PODAAC_SWOT", "collection": "L2_HR_PIXC", - "submissionTime": "2017-10-01T05:45:29.000000", + "submissionTime": "2017-10-01T05:45:29.000000Z", "identifier": "<>", "product": { "name": "L2_HR_PIXC_product_0001-of-4154", diff --git a/example/spec/parallel/cnmWorkflow/data/records/ascat_20121029_010301_metopb_00588_eps_o_coa_2101_ovw.l2.json b/example/spec/parallel/cnmWorkflow/data/records/ascat_20121029_010301_metopb_00588_eps_o_coa_2101_ovw.l2.json index b905e2937331..09d67cb01d18 100644 --- a/example/spec/parallel/cnmWorkflow/data/records/ascat_20121029_010301_metopb_00588_eps_o_coa_2101_ovw.l2.json +++ b/example/spec/parallel/cnmWorkflow/data/records/ascat_20121029_010301_metopb_00588_eps_o_coa_2101_ovw.l2.json @@ -2,7 +2,7 @@ "version": "1.4", "provider": "NASA/JPL/PO.DAAC", "collection": "ASCATB-L2-Coastal/op", - "submissionTime": "2022-08-10T17:49:30.477188", + "submissionTime": "2022-08-10T17:49:30.477188Z", "identifier": "<>", "product": { "name": "ascat_20121029_010301_metopb_00588_eps_o_coa_2101_ovw.l2", diff --git a/tasks/cnm-to-cma/deploy/README.md b/tasks/cnm-to-cma/deploy/README.md new file mode 100644 index 000000000000..6ab4386c1156 --- /dev/null +++ b/tasks/cnm-to-cma/deploy/README.md @@ -0,0 +1,58 @@ +# aws-api-proxy deploy module + +This Terraform configuration deploys the `aws-api-proxy` Lambda task using the shared [cumulus-task](../../../tf-modules/cumulus-task/README.md) module. + +## What this deploy config does + +- Resolves a Lambda execution role from either: + - a regex (`lambda_processing_role_pattern`), or + - a direct ARN (`lambda_processing_role_arn`) +- Resolves private application subnet IDs for the current region +- Creates the `aws-api-proxy` Lambda function from `../dist/final/lambda.zip` +- Applies timeout, memory, VPC, and tags settings + +## Prerequisites + +- Build the task package so `tasks/aws-api-proxy/dist/final/lambda.zip` exists +- Terraform and AWS credentials configured for the target account/region +- Either a role that matches `lambda_processing_role_pattern` or a direct `lambda_processing_role_arn` +- A subnet with tag name `Private application a subnet` + +## Usage + +From this directory: + +```bash +cd tasks/aws-api-proxy/deploy + +# Required deploy-time variables +export TF_VAR_prefix= +export TF_VAR_lambda_processing_role_pattern='^-.*lambda-processing.*$' + +# OR provide a direct role ARN (do not set both) +# export TF_VAR_lambda_processing_role_arn='arn:aws:iam:::role/' + +# Optional +export TF_VAR_tags='{"Project":"cumulus"}' + +terraform init +terraform apply +``` + +## Inputs + +| Name | Description | Type | Default | Required | +| --- | --- | --- | --- | :---: | +| lambda_processing_role_pattern | Regex pattern to match IAM role name when lambda_processing_role_arn is not provided | `string` | `""` | no | +| lambda_processing_role_arn | The ARN of the IAM role to use for the Lambda function. If not provided, lambda_processing_role_pattern will be used to find a matching role. | `string` | `""` | no | +| lambda_timeout | The timeout value for the Lambda function in seconds | `number` | n/a | yes | +| lambda_memory_size | The memory size for the Lambda function in MB | `number` | n/a | yes | +| security_group_id | Security group ID for Lambda VPC configuration | `string` | `""` | no | +| prefix | The prefix for resource names | `string` | n/a | yes | +| tags | A map of tags to apply to resources | `map(string)` | `{}` | no | + +Default values for task-specific settings are in [terraform.tfvars](./terraform.tfvars). + +## Notes + +- This deploy config includes Terraform `check` blocks that fail early if both role inputs are set (or both are empty), if the role pattern does not match exactly one role, or if no expected subnet is found. diff --git a/tasks/cnm-to-cma/deploy/terraform.tfvars b/tasks/cnm-to-cma/deploy/terraform.tfvars new file mode 100644 index 000000000000..4519286af3ab --- /dev/null +++ b/tasks/cnm-to-cma/deploy/terraform.tfvars @@ -0,0 +1,10 @@ +# This tfvars file is only used if this task is deployed in isolation and not referenced by other tasks. + +# This tfvars file contains non-sensitive customization that's specific to this task +# Additional variables are specified at deploy-time as environment variables: +# export TF_VAR_prefix= +# export TF_VAR_lambda_processing_role_pattern="^my-prefix-.*lambda-processing.*$" +# Optionally, you can also specify tags to apply to resources created by this task: +# export TF_VAR_tags='{"tag_key": "tag_value"}' +lambda_timeout = 180 # 6 minutes in seconds +lambda_memory_size = 512 diff --git a/tasks/cnm-to-cma/deploy/variables.tf b/tasks/cnm-to-cma/deploy/variables.tf index 381275e7dd31..4cbda8042480 100644 --- a/tasks/cnm-to-cma/deploy/variables.tf +++ b/tasks/cnm-to-cma/deploy/variables.tf @@ -8,13 +8,13 @@ variable "lambda_subnet_ids" { } variable "lambda_timeout" { - description = "Timeout value for the Lambda function in seconds" + description = "The timeout value for the Lambda function in seconds" type = number default = 300 } variable "lambda_memory_size" { - description = "Memory size for the Lambda function in MB" + description = "The memory size for the Lambda function in MB" type = number default = 512 } diff --git a/tasks/cnm-to-cma/src/cnm_to_cma/__init__.py b/tasks/cnm-to-cma/src/cnm_to_cma/__init__.py index e69de29bb2d1..1eba5dc2b4dc 100644 --- a/tasks/cnm-to-cma/src/cnm_to_cma/__init__.py +++ b/tasks/cnm-to-cma/src/cnm_to_cma/__init__.py @@ -0,0 +1,7 @@ +"""CNM to CMA task.""" + +from .task import lambda_handler + +__all__ = [ + "lambda_handler", +] diff --git a/tasks/cnm-to-cma/src/cnm_to_cma/cnm_to_cma.py b/tasks/cnm-to-cma/src/cnm_to_cma/task.py similarity index 84% rename from tasks/cnm-to-cma/src/cnm_to_cma/cnm_to_cma.py rename to tasks/cnm-to-cma/src/cnm_to_cma/task.py index a2f579e8da7d..ef8694bc402f 100644 --- a/tasks/cnm-to-cma/src/cnm_to_cma/cnm_to_cma.py +++ b/tasks/cnm-to-cma/src/cnm_to_cma/task.py @@ -1,5 +1,7 @@ """lambda function used to translate CNM messages to CMA messages in aws lambda with cumulus""" +import logging +import os import re from datetime import UTC, datetime from typing import Any @@ -11,10 +13,10 @@ from . import models_cnm, models_granule # Create Cumulus Logger instance -LOGGER = CumulusLogger("cnm_to_cma") +logger = CumulusLogger(__name__, level=int(os.environ.get("LOGLEVEL", logging.DEBUG))) -def task(event: dict[str, Any], context: object) -> dict[str, Any]: +def lambda_adapter(event: dict, context) -> dict[str, Any]: """Entry point of the lambda Args: event: Passed through from {handler} @@ -24,18 +26,20 @@ def task(event: dict[str, Any], context: object) -> dict[str, Any]: A dict representing input and copied files. See schemas/output.json for more information. """ - LOGGER.debug(event) cnm = event["input"] config = event["config"] - LOGGER.info(f"cnm message: {cnm} config: {config}") + logger.debug(f"cnm message: {cnm} config: {config}") granule = mapper(cnm, config) output: models_granule.SyncGranuleInput = models_granule.SyncGranuleInput( granules=[granule] ) now_as_iso = datetime.now(UTC).isoformat(timespec="milliseconds") + "Z" cnm["receivedTime"] = now_as_iso - output_dict = {"cnm": cnm, "output_granules": output.model_dump(mode="json")} + output_dict = { + "cnm": cnm, + "output_granules": output.model_dump(mode="json", exclude_none=True), + } return output_dict @@ -52,12 +56,12 @@ def mapper(cnm: dict, config: dict) -> models_granule.Granule: """ try: cnm_model = models_cnm.CloudNotificationMessageCnm12.model_validate(cnm) - LOGGER.info(f"CNM Model in mapper: {cnm_model}") + logger.info(f"CNM Model in mapper: {cnm_model}") granule_id_extraction = config.get("collection", {}).get("granuleIdExtraction") # retrieve granule_id from product.names product = cnm_model.root.product granule_id = product.name - LOGGER.info(f"Raw granule_id: {granule_id}") + logger.info(f"Raw granule_id: {granule_id}") # Extract the last token after the last slash granule_id = product.name.rsplit("/", 1)[-1] # Apply regex extraction if provided @@ -66,11 +70,11 @@ def mapper(cnm: dict, config: dict) -> models_granule.Granule: if matcher: granule_id = matcher.group(1) else: - LOGGER.warn( + logger.warn( f"granuleIdExtraction regex: {granule_id_extraction} did not match the " f"granuleId: {granule_id} but program will continue" ) - LOGGER.info(f"Granule ID: {granule_id}") + logger.info(f"Granule ID: {granule_id}") cnm_input_files: list[models_cnm.File] = get_cnm_input_files(product) cma_files: list[models_granule.File] = create_granule_files(cnm_input_files) granule = models_granule.Granule( @@ -80,10 +84,10 @@ def mapper(cnm: dict, config: dict) -> models_granule.Granule: dataType=config.get("collection", {}).get("name"), version=config.get("collection", {}).get("version"), ) - LOGGER.info(f"Granule Model in mapper: {granule}") + logger.info(f"Granule Model in mapper: {granule}") return granule except pydantic.ValidationError as pydan_error: - LOGGER.error("pydantic schema validation failed:", pydan_error) + logger.error("pydantic schema validation failed:", pydan_error) raise pydan_error @@ -126,7 +130,7 @@ def build_granule_file(cnm_file: Any) -> models_granule.File: r"^(?P.*?)://(?P[^/]+)(?:/(?P.*))?$", uri ) if not match: - LOGGER.error(f"Invalid URI format: {uri}") + logger.error(f"Invalid URI format: {uri}") raise ValueError(f"Invalid URI format: {uri}") groups = match.groupdict() protocol = groups["protocol"] @@ -146,7 +150,7 @@ def build_granule_file(cnm_file: Any) -> models_granule.File: # handler that is provided to aws lambda -def handler(event: dict[str, list[str] | dict], context: object) -> Any: +def lambda_handler(event: dict, context): """Lambda handler. Runs a cumulus task that Args: @@ -157,4 +161,6 @@ def handler(event: dict[str, list[str] | dict], context: object) -> Any: The result of the cumulus task. See schemas/output.json for more information. """ - return run_cumulus_task(task, event, context) + logger.setMetadata(event, context) + cumulus_task_return = run_cumulus_task(lambda_adapter, event, context) + return cumulus_task_return diff --git a/tasks/cnm-to-cma/src/main.py b/tasks/cnm-to-cma/src/main.py index 05544557302e..4cf654801c41 100644 --- a/tasks/cnm-to-cma/src/main.py +++ b/tasks/cnm-to-cma/src/main.py @@ -3,7 +3,7 @@ This file provides the Lambda handler. """ -from cnm_to_cma.cnm_to_cma import handler as lambda_handler +from cnm_to_cma import lambda_handler __all__ = [ "lambda_handler", diff --git a/tasks/cnm-to-cma/tests/test_cnm_to_cma.py b/tasks/cnm-to-cma/tests/test_cnm_to_cma.py index 95ef5aebe2ee..d6bbe6fad6c6 100644 --- a/tasks/cnm-to-cma/tests/test_cnm_to_cma.py +++ b/tasks/cnm-to-cma/tests/test_cnm_to_cma.py @@ -4,7 +4,7 @@ import pytest from cnm_to_cma import models_cnm, models_granule -from cnm_to_cma.cnm_to_cma import create_granule_files, get_cnm_input_files, mapper +from cnm_to_cma.task import create_granule_files, get_cnm_input_files, mapper class TestCNMToCMA: diff --git a/tf-modules/cumulus/outputs.tf b/tf-modules/cumulus/outputs.tf index 8452f697e997..7651fae19946 100644 --- a/tf-modules/cumulus/outputs.tf +++ b/tf-modules/cumulus/outputs.tf @@ -67,6 +67,10 @@ output "cnm_response_task" { value = module.ingest.cnm_response_task } +output "cnm_to_cma_task" { + value = module.ingest.cnm_to_cma_task +} + output "discover_granules_task" { value = module.ingest.discover_granules_task } diff --git a/tf-modules/ingest/cnm-to-cma.tf b/tf-modules/ingest/cnm-to-cma.tf new file mode 100644 index 000000000000..dd98d2e54096 --- /dev/null +++ b/tf-modules/ingest/cnm-to-cma.tf @@ -0,0 +1,13 @@ +module "cnm_to_cma_task" { + source = "../../tasks/cnm-to-cma/deploy" + + prefix = var.prefix + lambda_processing_role_arn = var.lambda_processing_role_arn + lambda_timeout = lookup(var.lambda_timeouts, "CnmToCma", 60 * 3) + lambda_memory_size = lookup(var.lambda_memory_sizes, "CnmToCma", 512) + lambda_subnet_ids = var.lambda_subnet_ids + security_group_id = length(var.lambda_subnet_ids) > 0 ? aws_security_group.no_ingress_all_egress[0].id : "" + log_retention_days = var.default_log_retention_days + + tags = var.tags +} diff --git a/tf-modules/ingest/outputs.tf b/tf-modules/ingest/outputs.tf index e101014ed66f..038b8adc0923 100644 --- a/tf-modules/ingest/outputs.tf +++ b/tf-modules/ingest/outputs.tf @@ -28,6 +28,14 @@ output "cnm_response_task" { } } +output "cnm_to_cma_task" { + value = { + task_arn = module.cnm_to_cma_task.cumulus_task_lambda.arn + task_log_group = module.cnm_to_cma_task.cumulus_task_log_group_name + last_modified_date = module.cnm_to_cma_task.cumulus_task_lambda.last_modified + } +} + output "discover_granules_task" { value = { task_arn = aws_lambda_function.discover_granules_task.arn