Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule E3042 - Check at least one essential container is specified #1548

Merged
merged 4 commits into from
May 24, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 ECS TaskDefinition ContainerDefinitions Property Species At Least One Essential Container"""
Tro95 marked this conversation as resolved.
Show resolved Hide resolved
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
4 changes: 4 additions & 0 deletions src/cfnlint/rules/resources/ecs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions test/unit/rules/resources/ecs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
Original file line number Diff line number Diff line change
@@ -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)