Skip to content

Commit 439806b

Browse files
authored
Create rule E3055 to validate CreationPolicy (#3609)
* Create rule E3055 to validate CreationPolicy * Better patch for required properties on AutoScalingGroup
1 parent e500fcc commit 439806b

File tree

6 files changed

+302
-67
lines changed

6 files changed

+302
-67
lines changed

scripts/update_schemas_manually.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,12 @@
7979
),
8080
Patch(
8181
values={
82-
"dependentExcluded": {
83-
"InstanceId": [
84-
"LaunchConfigurationName",
85-
"LaunchTemplate",
86-
"MixedInstancesPolicy",
87-
],
88-
"LaunchConfigurationName": [
89-
"InstanceId",
90-
"LaunchTemplate",
91-
"MixedInstancesPolicy",
92-
],
93-
"LaunchTemplate": [
94-
"InstanceId",
95-
"LaunchConfigurationName",
96-
"MixedInstancesPolicy",
97-
],
98-
"MixedInstancesPolicy": [
99-
"InstanceId",
100-
"LaunchConfigurationName",
101-
"LaunchTemplate",
102-
],
103-
},
82+
"requiredXor": [
83+
"InstanceId",
84+
"LaunchConfigurationName",
85+
"LaunchTemplate",
86+
"MixedInstancesPolicy",
87+
]
10488
},
10589
path="/",
10690
),

src/cfnlint/data/schemas/patches/extensions/all/aws_autoscaling_autoscalinggroup/manual.json

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,12 @@
1717
},
1818
{
1919
"op": "add",
20-
"path": "/dependentExcluded",
21-
"value": {
22-
"InstanceId": [
23-
"LaunchConfigurationName",
24-
"LaunchTemplate",
25-
"MixedInstancesPolicy"
26-
],
27-
"LaunchConfigurationName": [
28-
"InstanceId",
29-
"LaunchTemplate",
30-
"MixedInstancesPolicy"
31-
],
32-
"LaunchTemplate": [
33-
"InstanceId",
34-
"LaunchConfigurationName",
35-
"MixedInstancesPolicy"
36-
],
37-
"MixedInstancesPolicy": [
38-
"InstanceId",
39-
"LaunchConfigurationName",
40-
"LaunchTemplate"
41-
]
42-
}
20+
"path": "/requiredXor",
21+
"value": [
22+
"InstanceId",
23+
"LaunchConfigurationName",
24+
"LaunchTemplate",
25+
"MixedInstancesPolicy"
26+
]
4327
}
4428
]

src/cfnlint/data/schemas/providers/us_east_1/aws-autoscaling-autoscalinggroup.json

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -459,28 +459,6 @@
459459
"type": "object"
460460
}
461461
},
462-
"dependentExcluded": {
463-
"InstanceId": [
464-
"LaunchConfigurationName",
465-
"LaunchTemplate",
466-
"MixedInstancesPolicy"
467-
],
468-
"LaunchConfigurationName": [
469-
"InstanceId",
470-
"LaunchTemplate",
471-
"MixedInstancesPolicy"
472-
],
473-
"LaunchTemplate": [
474-
"InstanceId",
475-
"LaunchConfigurationName",
476-
"MixedInstancesPolicy"
477-
],
478-
"MixedInstancesPolicy": [
479-
"InstanceId",
480-
"LaunchConfigurationName",
481-
"LaunchTemplate"
482-
]
483-
},
484462
"deprecatedProperties": [
485463
"/properties/NotificationConfiguration"
486464
],
@@ -715,6 +693,12 @@
715693
"MinSize",
716694
"MaxSize"
717695
],
696+
"requiredXor": [
697+
"InstanceId",
698+
"LaunchConfigurationName",
699+
"LaunchTemplate",
700+
"MixedInstancesPolicy"
701+
],
718702
"tagging": {
719703
"cloudFormationSystemTags": true,
720704
"tagOnCreate": true,
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
SPDX-License-Identifier: MIT-0
4+
"""
5+
6+
from __future__ import annotations
7+
8+
from typing import Any
9+
10+
from cfnlint.jsonschema import Validator
11+
from cfnlint.rules.jsonschema.CfnLintJsonSchema import CfnLintJsonSchema
12+
13+
14+
class CreationPolicy(CfnLintJsonSchema):
15+
id = "E3055"
16+
shortdesc = "Check CreationPolicy values for Resources"
17+
description = "Check that the CreationPolicy values are valid"
18+
source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html"
19+
tags = ["resources", "creationPolicy"]
20+
21+
def __init__(self) -> None:
22+
super().__init__(
23+
keywords=["Resources/*/CreationPolicy"],
24+
all_matches=True,
25+
)
26+
27+
def _get_schema(self, resource_type: str) -> dict[str, Any]:
28+
if resource_type == "AWS::AppStream::Fleet":
29+
return {
30+
"type": "object",
31+
"additionalProperties": False,
32+
"properties": {
33+
"StartFleet": {
34+
"additionalProperties": False,
35+
"type": "object",
36+
"properties": {"Type": {"type": "boolean"}},
37+
}
38+
},
39+
}
40+
if resource_type == "AWS::AutoScaling::AutoScalingGroup":
41+
return {
42+
"type": "object",
43+
"additionalProperties": False,
44+
"properties": {
45+
"AutoScalingCreationPolicy": {
46+
"type": "object",
47+
"additionalProperties": False,
48+
"properties": {
49+
"MinSuccessfulInstancesPercent": {"type": "integer"}
50+
},
51+
},
52+
"ResourceSignal": {
53+
"additionalProperties": False,
54+
"type": "object",
55+
"properties": {
56+
"Timeout": {"type": "string"},
57+
"Count": {"type": "integer"},
58+
},
59+
},
60+
},
61+
}
62+
if resource_type == "AWS::CloudFormation::WaitCondition":
63+
64+
return {
65+
"type": "object",
66+
"additionalProperties": False,
67+
"properties": {
68+
"ResourceSignal": {
69+
"additionalProperties": False,
70+
"type": "object",
71+
"properties": {
72+
"Timeout": {"type": "string"},
73+
"Count": {"type": "integer"},
74+
},
75+
}
76+
},
77+
}
78+
79+
return {}
80+
81+
# pylint: disable=unused-argument, arguments-renamed
82+
def validate(self, validator: Validator, dP: str, instance, schema):
83+
resource_name = validator.context.path.path[1]
84+
if not isinstance(resource_name, str):
85+
return
86+
resource_type = validator.context.resources[resource_name].type
87+
88+
validator = validator.evolve(
89+
context=validator.context.evolve(
90+
functions=[
91+
"Fn::Sub",
92+
"Fn::Select",
93+
"Fn::FindInMap",
94+
"Fn::If",
95+
"Ref",
96+
],
97+
strict_types=False,
98+
),
99+
schema=self._get_schema(resource_type),
100+
)
101+
102+
yield from self._iter_errors(validator, instance)

test/integration/test_schema_files.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class TestSchemaFiles(TestCase):
4343
"Resources",
4444
"Resources/*",
4545
"Resources/*/Condition",
46+
"Resources/*/CreationPolicy",
4647
"Resources/*/DeletionPolicy",
4748
"Resources/*/DependsOn",
4849
"Resources/*/DependsOn/*",

0 commit comments

Comments
 (0)