def check(self, cfn, properties, value_specs, property_specs, path): """Check itself""" matches = list() for p_value, p_path in properties.items_safe(path[:]): for prop in p_value: if prop in value_specs: value = value_specs.get(prop).get('Value', {}) if value: value_type = value.get('ValueType', '') list_value_type = value.get('ListValueType', '') property_type = property_specs.get('Properties').get( prop).get('Type') matches.extend( cfn.check_value( p_value, prop, p_path, check_ref=self.check_value_ref, check_get_att=self.check_value_getatt, value_specs=RESOURCE_SPECS.get( cfn.regions[0]).get('ValueTypes').get( value_type, {}), list_value_specs=RESOURCE_SPECS.get( cfn.regions[0]).get('ValueTypes').get( list_value_type, {}), cfn=cfn, property_type=property_type, property_name=prop)) return matches
def __init__(self, ): """Init """ super(ValueRefGetAtt, self).__init__() for resource_type_spec in RESOURCE_SPECS.get('us-east-1').get('ResourceTypes'): self.resource_property_types.append(resource_type_spec) for property_type_spec in RESOURCE_SPECS.get('us-east-1').get('PropertyTypes'): self.resource_sub_property_types.append(property_type_spec)
def initialize(self, cfn): """Initialize the rule""" for resource_type_spec in RESOURCE_SPECS.get( cfn.regions[0]).get('ResourceTypes'): self.resource_property_types.append(resource_type_spec) for property_type_spec in RESOURCE_SPECS.get( cfn.regions[0]).get('PropertyTypes'): self.resource_sub_property_types.append(property_type_spec)
def match_resource_sub_properties(self, properties, property_type, path, cfn): """Match for sub properties""" matches = list() specs = RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes').get(property_type, {}).get('Properties', {}) property_specs = RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes').get(property_type) matches.extend(self.check(cfn, properties, specs, property_specs, path)) return matches
def match_resource_properties(self, properties, resource_type, path, cfn): """Check CloudFormation Properties""" matches = list() specs = RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes').get(resource_type, {}).get('Properties', {}) resource_specs = RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes').get(resource_type) matches.extend(self.check(cfn, properties, specs, resource_specs, path)) return matches
def check(self, cfn, properties, specs, path): """Check itself""" matches = [] for p_value, p_path in properties.items_safe(path[:]): for prop in p_value: if prop in specs: value_type = specs.get(prop).get('Value', {}).get('ValueType', '') if value_type: property_type = specs.get(prop).get('PrimitiveType') value_specs = RESOURCE_SPECS.get( cfn.regions[0]).get('ValueTypes').get( value_type, {}) if value_specs.get('NumberMax') and value_specs.get( 'NumberMin'): if property_type in ['Integer', 'Double', 'Long']: matches.extend( cfn.check_value( properties, prop, p_path, check_value=self._check_number_value, number_max=value_specs.get( 'NumberMax'), number_min=value_specs.get( 'NumberMin'))) return matches
def check(self, cfn, properties, specs, path): """Check itself""" matches = [] for p_value, p_path in properties.items_safe(path[:]): for prop in p_value: if prop in specs: value_type = specs.get(prop).get('Value', {}).get('ValueType', '') if value_type: property_type = specs.get(prop).get('PrimitiveType') value_specs = RESOURCE_SPECS.get( cfn.regions[0]).get('ValueTypes').get( value_type, {}) if value_specs.get('StringMax') and value_specs.get( 'StringMin'): if property_type == 'String': matches.extend( cfn.check_value( properties, prop, p_path, check_value=self._check_string_length, string_max=value_specs.get( 'StringMax'), string_min=value_specs.get( 'StringMin'))) return matches
def check_value_ref(self, value, path, **kwargs): """Check Ref""" matches = list() cfn = kwargs.get('cfn') value_specs = kwargs.get('value_specs', {}).get('Ref') list_value_specs = kwargs.get('list_value_specs', {}).get('Ref') property_type = kwargs.get('property_type') property_name = kwargs.get('property_name') if path[-1] == 'Ref' and property_type == 'List' and self.is_value_a_list(path[:-1], property_name): specs = list_value_specs else: specs = value_specs if not specs: # If no Ref's are specified, just skip # Opposite of GetAtt you will always have a Ref to a Parameter so if this is # None it just hasn't been defined and we can skip return matches if value in cfn.template.get('Parameters', {}): param = cfn.template.get('Parameters').get(value, {}) parameter_type = param.get('Type') valid_parameter_types = [] for parameter in specs.get('Parameters'): for param_type in RESOURCE_SPECS.get('us-east-1').get('ParameterTypes').get(parameter): valid_parameter_types.append(param_type) if not specs.get('Parameters'): message = 'Property "{0}" has no valid Refs to Parameters at {1}' matches.append(RuleMatch(path, message.format(property_name, '/'.join(map(str, path))))) elif parameter_type not in valid_parameter_types: message = 'Property "{0}" can Ref to parameter of types [{1}] at {2}' matches.append( RuleMatch( path, message.format( property_name, ', '.join(map(str, valid_parameter_types)), '/'.join(map(str, path))))) if value in cfn.template.get('Resources', {}): resource = cfn.template.get('Resources').get(value, {}) resource_type = resource.get('Type') if not specs.get('Resources'): message = 'Property "{0}" has no valid Refs to Resources at {1}' matches.append(RuleMatch(path, message.format(property_name, '/'.join(map(str, path))))) elif resource_type not in specs.get('Resources'): message = 'Property "{0}" can Ref to resources of types [{1}] at {2}' matches.append( RuleMatch( path, message.format( property_name, ', '.join(map(str, specs.get('Resources'))), '/'.join(map(str, path))))) return matches
def __init__(self): """Initialize the rule""" super(Join, self).__init__() self.list_supported_functions = [] self.singular_supported_functions = [] for intrinsic_type, intrinsic_value in RESOURCE_SPECS.get('us-east-1').get('IntrinsicTypes').items(): if 'List' in intrinsic_value.get('ReturnTypes', []): self.list_supported_functions.append(intrinsic_type) if 'Singular' in intrinsic_value.get('ReturnTypes', []): self.singular_supported_functions.append(intrinsic_type)
def check(self, cfn, properties, specs, path): """Check itself""" matches = [] for p_value, p_path in properties.items_safe(path[:]): for prop in p_value: if prop in specs: value = specs.get(prop).get('Value', {}) if value: value_type = value.get('ListValueType', '') property_type = specs.get(prop).get('Type') if property_type == 'List': matches.extend( self.check_value( p_value, p_path, prop, cfn, RESOURCE_SPECS.get( cfn.regions[0]).get('ValueTypes').get( value_type, {}))) return matches