Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added throw error when event function name is long #1205

Merged
merged 16 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -932,11 +932,11 @@ to change Zappa's behavior. Use these at your own risk!
"environment_variables": {"your_key": "your_value"}, // A dictionary of environment variables that will be available to your deployed app. See also "remote_env" and "aws_environment_variables". Default {}.
"events": [
{ // Recurring events
"function": "your_module.your_recurring_function", // The function to execute
"function": "your_module.your_recurring_function", // The function to execute (Pattern: [._A-Za-z0-9]+).
"expression": "rate(1 minute)" // When to execute it (in cron or rate format)
},
{ // AWS Reactive events
"function": "your_module.your_reactive_function", // The function to execute
"function": "your_module.your_reactive_function", // The function to execute (Pattern: [._A-Za-z0-9]+).
"event_source": {
"arn": "arn:aws:s3:::my-bucket", // The ARN of this event source
"events": [
Expand Down
46 changes: 46 additions & 0 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2238,6 +2238,52 @@ def test_get_scheduled_event_name__truncated__has_name__has_index(self):
f"{hashed_lambda_name}-{index}-{event['name']}-{function}",
)

def test_get_scheduled_event_name__using_invalid_character(self):
zappa = Zappa()
event = {}
function = "foo$"
lambda_name = "bar"
with self.assertRaises(EnvironmentError):
zappa.get_scheduled_event_name(event, function, lambda_name)

def test_get_scheduled_event_name__using_hyphen(self):
zappa = Zappa()
event = {}
function = "foo-2"
lambda_name = "bar"
with self.assertRaises(EnvironmentError):
zappa.get_scheduled_event_name(event, function, lambda_name)

def test_get_scheduled_event_name__max_function_name(self):
zappa = Zappa()
event = {}
function = "a" * 63
lambda_name = "bar"

self.assertEqual(
zappa.get_scheduled_event_name(event, function, lambda_name),
f"-{function}",
)

def test_get_scheduled_event_name__over_function_name(self):
zappa = Zappa()
event = {}
function = "a" * 64
lambda_name = "bar"

with self.assertRaises(EnvironmentError):
zappa.get_scheduled_event_name(event, function, lambda_name)

def test_get_scheduled_event_name__over_name_with_index(self):
zappa = Zappa()
event = {}
function = "a" * 62
index = 1
lambda_name = "bar"

with self.assertRaises(EnvironmentError):
zappa.get_scheduled_event_name(event, function, lambda_name, index)

def test_shameless(self):
shamelessly_promote()

Expand Down
17 changes: 16 additions & 1 deletion zappa/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2939,7 +2939,17 @@ def get_scheduled_event_name(self, event, function, lambda_name, index=0):
"""
Returns an AWS-valid CloudWatch rule name using a digest of the event name, lambda name, and function.
This allows support for rule names that may be longer than the 64 char limit.

function pattern: '^[._A-Za-z0-9]{0,63}$'
monkut marked this conversation as resolved.
Show resolved Hide resolved
"""
max_event_rule_name_length = 64
max_name_length = max_event_rule_name_length - 1 # Because it must contain the delimiter "-".
function_regex = re.compile(f"^[._A-Za-z0-9]{{0,{max_name_length}}}$")
if not re.fullmatch(function_regex, function):
# Validation Rule: https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_Rule.html
# '-' cannot be used because it is a delimiter
raise EnvironmentError("event['function']: Pattern '^[._A-Za-z0-9]{0,63}$'.")

name = event.get("name", function)
if name != function:
# a custom event name has been provided, make sure function name is included as postfix,
Expand All @@ -2950,11 +2960,16 @@ def get_scheduled_event_name(self, event, function, lambda_name, index=0):
# prefix all entries bar the first with the index
# Related: https://github.com/Miserlou/Zappa/pull/1051
name = "{}-{}".format(index, name)
monkut marked this conversation as resolved.
Show resolved Hide resolved

# https://github.com/zappa/Zappa/issues/1036
# Error because the name cannot be obtained if the function name is longer than 64 characters
if len(name) > max_name_length:
raise EnvironmentError(f"Generated scheduled event name is too long, shorten the function name!: '{name}'")
# prefix scheduled event names with lambda name. So we can look them up later via the prefix.
event_name = self.get_event_name(lambda_name, name)
# if it's possible that we truncated name, generate a unique, shortened name
# https://github.com/Miserlou/Zappa/issues/970
if len(event_name) >= 64:
if len(event_name) >= max_event_rule_name_length:
lambda_name = self.get_hashed_lambda_name(lambda_name)
event_name = self.get_event_name(lambda_name, name)

Expand Down
Loading