From 23873687675c4883e9ce944bf5afc853bd21ad43 Mon Sep 17 00:00:00 2001 From: Thomas O'Brien Date: Sun, 24 May 2020 17:44:18 +0100 Subject: [PATCH 1/4] Rule E3042 - Check at least one essential container is specified --- .../ecs/TaskDefinitionEssentialContainer.py | 44 +++++++++++++++ src/cfnlint/rules/resources/ecs/__init__.py | 4 ++ ...cs_task_definition_essential_container.yml | 53 +++++++++++++++++++ ...cs_task_definition_essential_container.yml | 44 +++++++++++++++ ...ecs_task_definition_essential_container.py | 26 +++++++++ 5 files changed, 171 insertions(+) create mode 100644 src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py create mode 100644 src/cfnlint/rules/resources/ecs/__init__.py create mode 100644 test/fixtures/templates/bad/resources/ecs/test_ecs_task_definition_essential_container.yml create mode 100644 test/fixtures/templates/good/resources/ecs/test_ecs_task_definition_essential_container.yml create mode 100644 test/unit/rules/resources/ecs/test_ecs_task_definition_essential_container.py diff --git a/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py b/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py new file mode 100644 index 0000000000..d658f47a74 --- /dev/null +++ b/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py @@ -0,0 +1,44 @@ +""" +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: MIT-0 +""" +from cfnlint.rules import CloudFormationLintRule +from cfnlint.rules import RuleMatch + + +class TaskDefinitionEssentialContainer(CloudFormationLintRule): + """Check if Ec2 Ebs Resource Properties""" + id = 'E3042' + shortdesc = 'Check at least one essential container is specified' + description = 'Check that every TaskDefinition specifies at least one essential container' + source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html#cfn-ecs-taskdefinition-containerdefinition-essential' + tags = ['properties', 'ecs', 'task', 'container', 'fargate'] + + def match(self, cfn): + """Check at least one essential container is specified""" + + matches = [] + + results = cfn.get_resource_properties(['AWS::ECS::TaskDefinition', 'ContainerDefinitions']) + + for result in results: + path = result['Path'] + + has_essential_container = False + + for container in result['Value']: + if 'Essential' in container: + if container['Essential']: + has_essential_container = True + else: + pass + else: + # If 'Essential' is not specified, it defaults to an essential container + has_essential_container = True + + if not has_essential_container: + message = 'No essential containers defined for {0}' + rule_match = RuleMatch(path, message.format('/'.join(map(str, path)))) + matches.append(rule_match) + + return matches diff --git a/src/cfnlint/rules/resources/ecs/__init__.py b/src/cfnlint/rules/resources/ecs/__init__.py new file mode 100644 index 0000000000..e58049dc73 --- /dev/null +++ b/src/cfnlint/rules/resources/ecs/__init__.py @@ -0,0 +1,4 @@ +""" +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: MIT-0 +""" diff --git a/test/fixtures/templates/bad/resources/ecs/test_ecs_task_definition_essential_container.yml b/test/fixtures/templates/bad/resources/ecs/test_ecs_task_definition_essential_container.yml new file mode 100644 index 0000000000..6d9c9dc461 --- /dev/null +++ b/test/fixtures/templates/bad/resources/ecs/test_ecs_task_definition_essential_container.yml @@ -0,0 +1,53 @@ +--- +Resources: + + BadTaskDefinitionNoEssentialContainersSpecified: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: false + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + + GoodTaskDefinitionEssentialContainerSpecified: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: true + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + + GoodTaskDefinitionEssentialContainerDefault: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + + GoodTaskDefinitionEssentialContainerSpecifiedTwo: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: true + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + - Essential: false + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli-two + + GoodTaskDefinitionMultipleEssentialContainersSpecified: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: true + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + - Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli-two diff --git a/test/fixtures/templates/good/resources/ecs/test_ecs_task_definition_essential_container.yml b/test/fixtures/templates/good/resources/ecs/test_ecs_task_definition_essential_container.yml new file mode 100644 index 0000000000..8b7b96f6b6 --- /dev/null +++ b/test/fixtures/templates/good/resources/ecs/test_ecs_task_definition_essential_container.yml @@ -0,0 +1,44 @@ +--- +Resources: + + GoodTaskDefinitionEssentialContainerSpecified: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: true + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + + GoodTaskDefinitionEssentialContainerDefault: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + + GoodTaskDefinitionEssentialContainerSpecifiedTwo: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: true + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + - Essential: false + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli-two + + GoodTaskDefinitionMultipleEssentialContainersSpecified: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Essential: true + Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli + - Image: amazon/aws-cli + Memory: 40 + Name: amazon-cli-two diff --git a/test/unit/rules/resources/ecs/test_ecs_task_definition_essential_container.py b/test/unit/rules/resources/ecs/test_ecs_task_definition_essential_container.py new file mode 100644 index 0000000000..671a49f1ca --- /dev/null +++ b/test/unit/rules/resources/ecs/test_ecs_task_definition_essential_container.py @@ -0,0 +1,26 @@ +""" +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: MIT-0 +""" +from test.unit.rules import BaseRuleTestCase +from cfnlint.rules.resources.ecs.TaskDefinitionEssentialContainer import TaskDefinitionEssentialContainer # pylint: disable=E0401 + + +class TestECSTaskDefinitionEssentialContainer(BaseRuleTestCase): + """Test ECS Task Definition has at least one essential container defined""" + + def setUp(self): + """Setup""" + super(TestECSTaskDefinitionEssentialContainer, self).setUp() + self.collection.register(TaskDefinitionEssentialContainer()) + self.success_templates = [ + 'test/fixtures/templates/good/resources/ecs/test_ecs_task_definition_essential_container.yml', + ] + + def test_file_positive(self): + """Test Positive""" + self.helper_file_positive() + + def test_file_negative(self): + """Test failure""" + self.helper_file_negative('test/fixtures/templates/bad/resources/ecs/test_ecs_task_definition_essential_container.yml', 1) From 864b39a6c704f7748b65d6aa6794fbe8471af67e Mon Sep 17 00:00:00 2001 From: Thomas O'Brien Date: Sun, 24 May 2020 18:03:21 +0100 Subject: [PATCH 2/4] Adding __init__.py --- test/unit/rules/resources/ecs/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 test/unit/rules/resources/ecs/__init__.py diff --git a/test/unit/rules/resources/ecs/__init__.py b/test/unit/rules/resources/ecs/__init__.py new file mode 100644 index 0000000000..e58049dc73 --- /dev/null +++ b/test/unit/rules/resources/ecs/__init__.py @@ -0,0 +1,4 @@ +""" +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: MIT-0 +""" From 7c200b172ed7ca4501cd2b3fc6d711badf08f446 Mon Sep 17 00:00:00 2001 From: Thomas O'Brien Date: Sun, 24 May 2020 18:31:45 +0100 Subject: [PATCH 3/4] Fixing rule documentation string --- .../rules/resources/ecs/TaskDefinitionEssentialContainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py b/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py index d658f47a74..46022628df 100644 --- a/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py +++ b/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py @@ -7,7 +7,7 @@ class TaskDefinitionEssentialContainer(CloudFormationLintRule): - """Check if Ec2 Ebs Resource Properties""" + """Check ECS TaskDefinition ContainerDefinitions Property Species At Least One Essential Container""" id = 'E3042' shortdesc = 'Check at least one essential container is specified' description = 'Check that every TaskDefinition specifies at least one essential container' From 14e9f2181638e461b83bf81230d080340cf6162b Mon Sep 17 00:00:00 2001 From: Thomas O'Brien Date: Sun, 24 May 2020 18:51:57 +0100 Subject: [PATCH 4/4] Fixing rule documentation string --- .../rules/resources/ecs/TaskDefinitionEssentialContainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py b/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py index 46022628df..b9c8d3f955 100644 --- a/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py +++ b/src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py @@ -7,7 +7,7 @@ class TaskDefinitionEssentialContainer(CloudFormationLintRule): - """Check ECS TaskDefinition ContainerDefinitions Property Species At Least One Essential Container""" + """Check ECS TaskDefinition ContainerDefinitions Property Specifies at least one Essential Container""" id = 'E3042' shortdesc = 'Check at least one essential container is specified' description = 'Check that every TaskDefinition specifies at least one essential container'