-
Notifications
You must be signed in to change notification settings - Fork 606
/
Copy pathEventSourceMappingToSqsTimeout.py
96 lines (80 loc) · 3.69 KB
/
EventSourceMappingToSqsTimeout.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
from __future__ import annotations
from collections import deque
from typing import Any
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
from cfnlint.rules.helpers import get_value_from_path
from cfnlint.rules.jsonschema.CfnLintKeyword import CfnLintKeyword
class EventSourceMappingToSqsTimeout(CfnLintKeyword):
id = "E3505"
shortdesc = (
"Validate SQS 'VisibilityTimeout' is greater than a function's 'Timeout'"
)
description = (
"When attaching a Lambda function to a SQS queue to a Lambda function the "
"SQS 'VisibilityTimeout' has to be greater than or equal to "
" the lambda functions's 'Timeout'"
)
source_url = "https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html"
tags = ["resources", "lambda", "sqs"]
def __init__(self):
"""Init"""
super().__init__(["Resources/AWS::Lambda::Function/Properties/Timeout"])
def validate(
self, validator: Validator, keywords: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if validator.is_type(instance, "string"):
try:
instance = int(instance)
except: # noqa: E722
return
if not validator.is_type(instance, "integer"):
return
if validator.cfn.graph is None: # pragma: no cover
return # pragma: no cover
if not len(validator.context.path.path) >= 2:
return
resource_name = validator.context.path.path[1]
for child_1, _ in validator.cfn.graph.graph.in_edges(resource_name):
if child_1 not in validator.context.resources:
continue
if (
validator.context.resources[child_1].type
== "AWS::Lambda::EventSourceMapping"
):
for _, child_2 in validator.cfn.graph.graph.out_edges(child_1):
if child_2 not in validator.context.resources:
continue
if validator.context.resources[child_2].type == "AWS::SQS::Queue":
for visibility_timeout, _ in get_value_from_path(
validator,
validator.cfn.template,
deque(
[
"Resources",
child_2,
"Properties",
"VisibilityTimeout",
]
),
):
if validator.is_type(visibility_timeout, "string"):
try:
visibility_timeout = int(visibility_timeout)
except: # noqa: E722
continue
if not validator.is_type(visibility_timeout, "integer"):
continue
if visibility_timeout < instance:
yield ValidationError(
message=(
f"Queue visibility timeout "
f"({visibility_timeout!r}) "
"is less than Function timeout "
f"({instance!r}) seconds"
),
rule=self,
)