-
Notifications
You must be signed in to change notification settings - Fork 602
/
Copy pathRestApiMixingDefinitions.py
68 lines (57 loc) · 2.48 KB
/
RestApiMixingDefinitions.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
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
from __future__ import annotations
from typing import Any
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
from cfnlint.rules.jsonschema.CfnLintKeyword import CfnLintKeyword
class RestApiMixingDefinitions(CfnLintKeyword):
id = "W3660"
shortdesc = "Validate if multiple resources are modifying a Rest API definition"
description = (
"When using AWS::ApiGateway::RestApi with 'Body' or 'BodyS3Location' "
"the resource handler will use PutRestApi with mode overwrite. "
"Depending on how resources are updated the IaC template will "
"drift and create orphaned resources."
)
tags = ["resources", "apigateway"]
def __init__(self) -> None:
super().__init__(
keywords=[
"Resources/AWS::ApiGateway::RestApi/Properties/Body",
"Resources/AWS::ApiGateway::RestApi/Properties/BodyS3Location",
],
)
self._mix_types = [
"AWS::ApiGateway::Method",
"AWS::ApiGateway::Model",
"AWS::ApiGateway::Resource",
"AWS::ApiGateway::GatewayResponse",
"AWS::ApiGateway::RequestValidator",
"AWS::ApiGateway::Authorizer",
]
def validate(
self, validator: Validator, keywords: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if validator.cfn.graph is None: # pragma: no cover
return # pragma: no cover
if not len(validator.context.path.path) > 3:
return
resource_name = validator.context.path.path[1]
key = validator.context.path.path[3]
unique_sources: set[str] = set()
for source, _ in validator.cfn.graph.graph.in_edges(resource_name):
if source not in validator.context.resources:
continue
if validator.context.resources[source].type in self._mix_types:
if source not in unique_sources:
yield ValidationError(
message=(
f"Defining {key!r} with a relation to resource {source!r} "
f"of type {validator.context.resources[source].type!r} "
"may result in drift and orphaned resources"
),
rule=self,
)
unique_sources.add(source)