-
Notifications
You must be signed in to change notification settings - Fork 593
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rule E3663 to validate lambda fn env vars (#3505)
* Add rule E3663 to validate lambda fn env vars
- Loading branch information
Showing
3 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
src/cfnlint/data/schemas/extensions/aws_lambda_function/environment_variable_keys.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"propertyNames": { | ||
"not": { | ||
"enum": [ | ||
"_HANDLER", | ||
"_X_AMZN_TRACE_ID", | ||
"AWS_DEFAULT_REGION", | ||
"AWS_REGION", | ||
"AWS_EXECUTION_ENV", | ||
"AWS_LAMBDA_FUNCTION_NAME", | ||
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE", | ||
"AWS_LAMBDA_FUNCTION_VERSION", | ||
"AWS_LAMBDA_INITIALIZATION_TYPE", | ||
"AWS_LAMBDA_LOG_GROUP_NAME", | ||
"AWS_LAMBDA_LOG_STREAM_NAME", | ||
"AWS_ACCESS_KEY", | ||
"AWS_ACCESS_KEY_ID", | ||
"AWS_SECRET_ACCESS_KEY", | ||
"AWS_SESSION_TOKEN", | ||
"AWS_LAMBDA_RUNTIME_API", | ||
"LAMBDA_TASK_ROOT", | ||
"LAMBDA_RUNTIME_DIR" | ||
] | ||
} | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/cfnlint/rules/resources/lmbd/FunctionEnvironmentKeys.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
""" | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
SPDX-License-Identifier: MIT-0 | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import Any | ||
|
||
import cfnlint.data.schemas.extensions.aws_lambda_function | ||
from cfnlint.jsonschema import ValidationResult | ||
from cfnlint.jsonschema.protocols import Validator | ||
from cfnlint.rules.jsonschema import CfnLintJsonSchema, SchemaDetails | ||
|
||
|
||
class FunctionEnvironmentKeys(CfnLintJsonSchema): | ||
|
||
id = "E3663" | ||
shortdesc = "Validate Lambda environment variable names aren't reserved" | ||
description = ( | ||
"Lambda reserves a set of environment variable names for its use. " | ||
"This rule validates that the provided environment variable names " | ||
"don't use the reserved variable names" | ||
) | ||
source_url = ( | ||
"https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html" | ||
) | ||
tags = ["resources", "lambda", "runtime"] | ||
|
||
def __init__(self): | ||
"""Init""" | ||
super().__init__( | ||
keywords=[ | ||
"Resources/AWS::Lambda::Function/Properties/Environment/Variables" | ||
], | ||
schema_details=SchemaDetails( | ||
cfnlint.data.schemas.extensions.aws_lambda_function, | ||
"environment_variable_keys.json", | ||
), | ||
all_matches=True, | ||
) | ||
|
||
def validate( | ||
self, validator: Validator, keywords: Any, instance: Any, schema: dict[str, Any] | ||
) -> ValidationResult: | ||
for err in super().validate(validator, keywords, instance, schema): | ||
err.message = ( | ||
f"{err.instance!r} is a reserved variable name, one of " | ||
f"{self.schema.get('propertyNames').get('not').get('enum')!r}" | ||
) | ||
yield err |
109 changes: 109 additions & 0 deletions
109
test/unit/rules/resources/lmbd/test_function_environment_keys.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
""" | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
SPDX-License-Identifier: MIT-0 | ||
""" | ||
|
||
from collections import deque | ||
|
||
import pytest | ||
|
||
from cfnlint.jsonschema import ValidationError | ||
from cfnlint.rules.resources.lmbd.FunctionEnvironmentKeys import FunctionEnvironmentKeys | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def rule(): | ||
rule = FunctionEnvironmentKeys() | ||
yield rule | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"instance,expected", | ||
[ | ||
( | ||
{"Foo": "Bar"}, | ||
[], | ||
), | ||
( | ||
{"AWS_REGION": "Bar"}, | ||
[ | ||
ValidationError( | ||
( | ||
"'AWS_REGION' is a reserved variable name, one of " | ||
"['_HANDLER', '_X_AMZN_TRACE_ID', 'AWS_DEFAULT_REGION', " | ||
"'AWS_REGION', 'AWS_EXECUTION_ENV', " | ||
"'AWS_LAMBDA_FUNCTION_NAME', " | ||
"'AWS_LAMBDA_FUNCTION_MEMORY_SIZE', " | ||
"'AWS_LAMBDA_FUNCTION_VERSION', " | ||
"'AWS_LAMBDA_INITIALIZATION_TYPE', " | ||
"'AWS_LAMBDA_LOG_GROUP_NAME', " | ||
"'AWS_LAMBDA_LOG_STREAM_NAME', " | ||
"'AWS_ACCESS_KEY', 'AWS_ACCESS_KEY_ID', " | ||
"'AWS_SECRET_ACCESS_KEY', " | ||
"'AWS_SESSION_TOKEN', 'AWS_LAMBDA_RUNTIME_API', " | ||
"'LAMBDA_TASK_ROOT', 'LAMBDA_RUNTIME_DIR']" | ||
), | ||
schema_path=deque(["propertyNames", "not"]), | ||
path=deque(["AWS_REGION"]), | ||
rule=FunctionEnvironmentKeys(), | ||
validator="not", | ||
) | ||
], | ||
), | ||
( | ||
{ | ||
"Foo": "Bar", | ||
"AWS_REGION": "Bar", | ||
"Bar": "Foo", | ||
"AWS_ACCESS_KEY": "Foo", | ||
}, | ||
[ | ||
ValidationError( | ||
( | ||
"'AWS_REGION' is a reserved variable name, one of " | ||
"['_HANDLER', '_X_AMZN_TRACE_ID', 'AWS_DEFAULT_REGION', " | ||
"'AWS_REGION', 'AWS_EXECUTION_ENV', " | ||
"'AWS_LAMBDA_FUNCTION_NAME', " | ||
"'AWS_LAMBDA_FUNCTION_MEMORY_SIZE', " | ||
"'AWS_LAMBDA_FUNCTION_VERSION', " | ||
"'AWS_LAMBDA_INITIALIZATION_TYPE', " | ||
"'AWS_LAMBDA_LOG_GROUP_NAME', " | ||
"'AWS_LAMBDA_LOG_STREAM_NAME', " | ||
"'AWS_ACCESS_KEY', 'AWS_ACCESS_KEY_ID', " | ||
"'AWS_SECRET_ACCESS_KEY', " | ||
"'AWS_SESSION_TOKEN', 'AWS_LAMBDA_RUNTIME_API', " | ||
"'LAMBDA_TASK_ROOT', 'LAMBDA_RUNTIME_DIR']" | ||
), | ||
schema_path=deque(["propertyNames", "not"]), | ||
path=deque(["AWS_REGION"]), | ||
rule=FunctionEnvironmentKeys(), | ||
validator="not", | ||
), | ||
ValidationError( | ||
( | ||
"'AWS_ACCESS_KEY' is a reserved variable name, one of " | ||
"['_HANDLER', '_X_AMZN_TRACE_ID', 'AWS_DEFAULT_REGION', " | ||
"'AWS_REGION', 'AWS_EXECUTION_ENV', " | ||
"'AWS_LAMBDA_FUNCTION_NAME', " | ||
"'AWS_LAMBDA_FUNCTION_MEMORY_SIZE', " | ||
"'AWS_LAMBDA_FUNCTION_VERSION', " | ||
"'AWS_LAMBDA_INITIALIZATION_TYPE', " | ||
"'AWS_LAMBDA_LOG_GROUP_NAME', " | ||
"'AWS_LAMBDA_LOG_STREAM_NAME', " | ||
"'AWS_ACCESS_KEY', 'AWS_ACCESS_KEY_ID', " | ||
"'AWS_SECRET_ACCESS_KEY', " | ||
"'AWS_SESSION_TOKEN', 'AWS_LAMBDA_RUNTIME_API', " | ||
"'LAMBDA_TASK_ROOT', 'LAMBDA_RUNTIME_DIR']" | ||
), | ||
schema_path=deque(["propertyNames", "not"]), | ||
path=deque(["AWS_ACCESS_KEY"]), | ||
rule=FunctionEnvironmentKeys(), | ||
validator="not", | ||
), | ||
], | ||
), | ||
], | ||
) | ||
def test_validate(instance, expected, rule, validator): | ||
errs = list(rule.validate(validator, "LambdaRuntime", instance, {})) | ||
assert errs == expected, f"Expected {expected} got {errs}" |