-
Notifications
You must be signed in to change notification settings - Fork 597
/
SnapStartSupported.py
121 lines (104 loc) · 3.81 KB
/
SnapStartSupported.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""
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.jsonschema.CfnLintKeyword import CfnLintKeyword
class SnapStartSupported(CfnLintKeyword):
"""Check if Lambda function using SnapStart has the correct runtimes"""
id = "E2530"
shortdesc = "SnapStart supports the configured runtime"
description = (
"To properly leverage SnapStart, you must have a runtime of Java11 or greater"
)
source_url = "https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html"
tags = ["resources", "lambda"]
def __init__(self):
super().__init__(["Resources/AWS::Lambda::Function/Properties"])
self.child_rules = {"I2530": None}
self.regions = [
"us-east-2",
"us-east-1",
"us-west-1",
"us-west-2",
"af-south-1",
"ap-east-1",
"ap-southeast-3",
"ap-south-1",
"ap-northeast-2",
"ap-northeast-3",
"ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1",
"ca-central-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
"eu-south-1",
"eu-west-3",
"eu-north-1",
"me-south-1",
"sa-east-1",
]
def _is_runtime_valid(self, runtime: str) -> bool:
if not any(runtime.startswith(r) for r in ["python", "java", "dotnet"]):
return False
if runtime.startswith("dotnetcore"):
return False
return runtime not in [
"dotnet5.0",
"dotnet6",
"dotnet7",
"java8.al2",
"java8",
"python3.10",
"python3.11",
"python3.7",
"python3.8",
"python3.9",
]
def validate(
self, validator: Validator, _, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
for scenario in validator.cfn.get_object_without_conditions(
instance,
["Runtime", "SnapStart"],
):
props = scenario.get("Object")
runtime = props.get("Runtime")
snap_start = props.get("SnapStart")
if not snap_start:
if self.child_rules["I2530"]:
if all(
region in self.regions for region in validator.context.regions
):
yield from self.child_rules["I2530"].validate( # type: ignore
runtime,
)
continue
if snap_start.get("ApplyOn") != "PublishedVersions":
continue
if any(region not in self.regions for region in validator.context.regions):
unsupported_regions = [
region
for region in validator.context.regions
if region not in self.regions
]
yield ValidationError(
(
"'SnapStart' enabled functions are not supported in "
f"{unsupported_regions!r}"
),
path=deque(["SnapStart", "ApplyOn"]),
)
# Validate runtime is a string before using startswith
if not isinstance(runtime, str):
continue
if not self._is_runtime_valid(runtime):
yield ValidationError(
f"{runtime!r} is not supported for 'SnapStart' enabled functions",
path=deque(["SnapStart", "ApplyOn"]),
)