Skip to content

Commit c270f49

Browse files
committed
Improve testing
1 parent 6956944 commit c270f49

File tree

5 files changed

+274
-4
lines changed

5 files changed

+274
-4
lines changed

src/cfnlint/rules/resources/ecs/ServiceNetworkConfiguration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class ServiceNetworkConfiguration(CfnLintKeyword):
1919
id = "E3052"
2020
shortdesc = "Validate ECS service requires NetworkConfiguration"
2121
description = (
22-
"When using an ECS task definition has 'awsvpc' "
23-
"then 'NetworkConfiguration' is required"
22+
"When using an ECS task definition has NetworkMode set to "
23+
"'awsvpc' then 'NetworkConfiguration' is required"
2424
)
2525
tags = ["resources", "ecs"]
2626

src/cfnlint/rules/resources/ecs/TaskDefinitionAwsVpc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
class TaskDefinitionAwsVpc(CfnLintKeyword):
1818
id = "E3053"
19-
shortdesc = "Validate ECS task definition is has correct values for " "'HostPort'"
19+
shortdesc = "Validate ECS task definition is has correct values for 'HostPort'"
2020
description = (
2121
"The 'HostPort' must either be undefined or equal to "
2222
"the 'ContainerPort' value"
@@ -49,7 +49,7 @@ def _get_port_mappings(
4949
container_definition,
5050
path=deque(["ContainerPort"]),
5151
):
52-
if not isinstance(host_port, (str, int)):
52+
if not isinstance(container_port, (str, int)):
5353
continue
5454
if str(host_port) != str(container_port):
5555
yield host_port, container_port, host_port_validator

test/unit/rules/resources/ecs/test_service_fargate.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,122 @@ def rule():
5050
deque(["Resources", "Service", "Properties"]),
5151
[],
5252
),
53+
(
54+
{
55+
"Resources": {
56+
"TaskDefinition": jsonpatch.apply_patch(
57+
dict(_task_definition),
58+
[
59+
{
60+
"op": "remove",
61+
"path": "/Properties/RequiresCompatibilities",
62+
},
63+
],
64+
),
65+
"Service": jsonpatch.apply_patch(
66+
dict(_service),
67+
[
68+
{
69+
"op": "replace",
70+
"path": "/Properties/TaskDefinition",
71+
"value": {"Fn::Sub": "${TaskDefinition.Arn}"},
72+
},
73+
],
74+
),
75+
}
76+
},
77+
deque(["Resources", "Service", "Properties"]),
78+
[],
79+
),
80+
(
81+
{
82+
"Resources": {
83+
"TaskDefinition": jsonpatch.apply_patch(
84+
dict(_task_definition),
85+
[
86+
{
87+
"op": "remove",
88+
"path": "/Properties/RequiresCompatibilities",
89+
},
90+
],
91+
),
92+
"Service": jsonpatch.apply_patch(
93+
dict(_service),
94+
[
95+
{
96+
"op": "replace",
97+
"path": "/Properties/TaskDefinition",
98+
"value": {"Fn::GetAtt": "TaskDefinition.Arn"},
99+
},
100+
],
101+
),
102+
}
103+
},
104+
deque(["Resources", "Service", "Properties"]),
105+
[
106+
ValidationError(
107+
("'RequiresCompatibilities' is a required property"),
108+
validator="required",
109+
rule=ServiceFargate(),
110+
path_override=deque(["Resources", "TaskDefinition", "Properties"]),
111+
)
112+
],
113+
),
114+
(
115+
{
116+
"Parameters": {"MyTask": {"Type": "String"}},
117+
"Resources": {
118+
"TaskDefinition": jsonpatch.apply_patch(
119+
dict(_task_definition),
120+
[
121+
{
122+
"op": "remove",
123+
"path": "/Properties/RequiresCompatibilities",
124+
},
125+
],
126+
),
127+
"Service": jsonpatch.apply_patch(
128+
dict(_service),
129+
[
130+
{
131+
"op": "replace",
132+
"path": "/Properties/TaskDefinition",
133+
"value": {"Ref": "MyTask"},
134+
},
135+
],
136+
),
137+
},
138+
},
139+
deque(["Resources", "Service", "Properties"]),
140+
[],
141+
),
142+
(
143+
{
144+
"Resources": {
145+
"TaskDefinition": jsonpatch.apply_patch(
146+
dict(_task_definition),
147+
[
148+
{
149+
"op": "remove",
150+
"path": "/Properties/RequiresCompatibilities",
151+
},
152+
],
153+
),
154+
"Service": jsonpatch.apply_patch(
155+
dict(_service),
156+
[
157+
{
158+
"op": "replace",
159+
"path": "/Properties/TaskDefinition",
160+
"value": "MyTask",
161+
},
162+
],
163+
),
164+
}
165+
},
166+
deque(["Resources", "Service", "Properties"]),
167+
[],
168+
),
53169
(
54170
{
55171
"Resources": {

test/unit/rules/resources/ecs/test_service_network_configuration.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,105 @@ def rule():
158158
)
159159
],
160160
),
161+
(
162+
{
163+
"Resources": {
164+
"TaskDefinition": dict(_task_definition),
165+
"Service": jsonpatch.apply_patch(
166+
dict(_service),
167+
[
168+
{
169+
"op": "remove",
170+
"path": "/Properties/NetworkConfiguration",
171+
},
172+
{
173+
"op": "replace",
174+
"path": "/Properties/TaskDefinition",
175+
"value": {"Fn::GetAtt": "TaskDefinition.Arn"},
176+
},
177+
],
178+
),
179+
}
180+
},
181+
deque(["Resources", "Service", "Properties"]),
182+
[
183+
ValidationError(
184+
("'NetworkConfiguration' is a required property"),
185+
validator="required",
186+
rule=ServiceNetworkConfiguration(),
187+
)
188+
],
189+
),
190+
(
191+
{
192+
"Parameters": {"MyTargetGroup": {"Type": "String"}},
193+
"Resources": {
194+
"TaskDefinition": dict(_task_definition),
195+
"Service": jsonpatch.apply_patch(
196+
dict(_service),
197+
[
198+
{
199+
"op": "remove",
200+
"path": "/Properties/NetworkConfiguration",
201+
},
202+
{
203+
"op": "replace",
204+
"path": "/Properties/TaskDefinition",
205+
"value": {"Ref": "MyTargetGroup"},
206+
},
207+
],
208+
),
209+
},
210+
},
211+
deque(["Resources", "Service", "Properties"]),
212+
[],
213+
),
214+
(
215+
{
216+
"Resources": {
217+
"TaskDefinition": dict(_task_definition),
218+
"Service": jsonpatch.apply_patch(
219+
dict(_service),
220+
[
221+
{
222+
"op": "remove",
223+
"path": "/Properties/NetworkConfiguration",
224+
},
225+
{
226+
"op": "replace",
227+
"path": "/Properties/TaskDefinition",
228+
"value": {"Foo": "Bar"},
229+
},
230+
],
231+
),
232+
},
233+
},
234+
deque(["Resources", "Service", "Properties"]),
235+
[],
236+
),
237+
(
238+
{
239+
"Resources": {
240+
"TaskDefinition": dict(_task_definition),
241+
"Service": jsonpatch.apply_patch(
242+
dict(_service),
243+
[
244+
{
245+
"op": "remove",
246+
"path": "/Properties/NetworkConfiguration",
247+
},
248+
{
249+
"op": "replace",
250+
"path": "/Properties/TaskDefinition",
251+
"value": {"Fn::Sub": "${TaskDefinition.Arn}"},
252+
},
253+
],
254+
),
255+
},
256+
},
257+
deque(["Resources", "Service", "Properties"]),
258+
[],
259+
),
161260
],
162261
indirect=["template"],
163262
)

test/unit/rules/resources/ecs/test_task_definition_aws_vpc.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,35 @@ def rule():
7373
deque(["Resources", "TaskDefinition", "Properties"]),
7474
[],
7575
),
76+
(
77+
{
78+
"Resources": {
79+
"TaskDefinition": jsonpatch.apply_patch(
80+
dict(_task_definition),
81+
[
82+
{
83+
"op": "add",
84+
"path": (
85+
"/Properties/ContainerDefinitions/"
86+
"0/PortMappings/0/HostPort"
87+
),
88+
"value": "8080",
89+
},
90+
{
91+
"op": "replace",
92+
"path": (
93+
"/Properties/ContainerDefinitions/"
94+
"0/PortMappings/0/ContainerPort"
95+
),
96+
"value": {"Fn::Sub": "8080"},
97+
},
98+
],
99+
),
100+
}
101+
},
102+
deque(["Resources", "TaskDefinition", "Properties"]),
103+
[],
104+
),
76105
(
77106
{
78107
"Parameters": {
@@ -106,6 +135,32 @@ def rule():
106135
deque(["Resources", "TaskDefinition", "Properties"]),
107136
[],
108137
),
138+
(
139+
{
140+
"Resources": {
141+
"TaskDefinition": jsonpatch.apply_patch(
142+
dict(_task_definition),
143+
[
144+
{
145+
"op": "add",
146+
"path": (
147+
"/Properties/ContainerDefinitions/0"
148+
"/PortMappings/0/HostPort"
149+
),
150+
"value": "80",
151+
},
152+
{
153+
"op": "replace",
154+
"path": ("/Properties/NetworkMode"),
155+
"value": "bridge",
156+
},
157+
],
158+
),
159+
}
160+
},
161+
deque(["Resources", "TaskDefinition", "Properties"]),
162+
[],
163+
),
109164
(
110165
{
111166
"Resources": {

0 commit comments

Comments
 (0)