forked from aws-cloudformation/cfn-lint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ebs.py
71 lines (63 loc) · 3.29 KB
/
Ebs.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
69
70
71
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
import re
import six
from cfnlint.rules import CloudFormationLintRule
from cfnlint.rules import RuleMatch
class Ebs(CloudFormationLintRule):
"""Check Ec2 Ebs Resource Properties"""
id = 'E2504'
shortdesc = 'Check Ec2 Ebs Properties'
description = 'See if Ec2 Ebs Properties are valid'
source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html'
tags = ['properties', 'ec2', 'ebs']
def _checkEbs(self, cfn, ebs, path):
matches = []
if isinstance(ebs, dict):
volume_types_obj = cfn.get_values(ebs, 'VolumeType')
iops_obj = cfn.get_values(ebs, 'Iops')
if volume_types_obj is not None:
for volume_type_obj in volume_types_obj:
volume_type = volume_type_obj.get('Value')
if isinstance(volume_type, six.string_types):
if volume_type in ('io1', 'io2'):
if iops_obj is None:
pathmessage = path[:] + ['VolumeType']
message = 'VolumeType {0} requires Iops to be specified for {1}'
matches.append(
RuleMatch(
pathmessage,
message.format(volume_type, '/'.join(map(str, pathmessage)))))
elif volume_type in ('gp2', 'st1', 'sc1', 'standard'):
if iops_obj is not None:
pathmessage = path[:] + ['Iops']
message = 'Iops shouldn\'t be defined for type {0} for {1}'
matches.append(
RuleMatch(
pathmessage,
message.format(volume_type, '/'.join(map(str, pathmessage)))))
return matches
def match(self, cfn):
"""Check Ec2 Ebs Resource Parameters"""
matches = []
results = cfn.get_resource_properties(['AWS::EC2::Instance', 'BlockDeviceMappings'])
results.extend(cfn.get_resource_properties(
['AWS::AutoScaling::LaunchConfiguration', 'BlockDeviceMappings']))
for result in results:
path = result['Path']
if isinstance(result['Value'], list):
for index, properties in enumerate(result['Value']):
virtual_name = properties.get('VirtualName')
ebs = properties.get('Ebs')
if virtual_name:
# switch to regex
if not re.match(r'^ephemeral([0-9]|[1][0-9]|[2][0-3])$', virtual_name):
pathmessage = path[:] + [index, 'VirtualName']
message = 'Property VirtualName should be of type ephemeral(n) for {0}'
matches.append(
RuleMatch(pathmessage, message.format('/'.join(map(str, pathmessage)))))
elif ebs:
matches.extend(self._checkEbs(cfn, ebs, path[:] + [index, 'Ebs']))
return matches