def fn_import_value(self, value): if not hasattr(self, '_import_value_cache'): self._import_value_cache = dict( (export['Name'], export['Value']) for export in boto3.client('cloudformation', region_name=self.default_region).list_exports()['Exports'] ) return self._import_value_cache.get(value, UnknownValue("IMPORT VALUE: {}".format(value)))
def fn_get_att(self, value): """ >>> from aws_parsecf.parser import Parser >>> root = {'Resources': ... {'SomeResource': {'Properties': {'SomeKey': 'SomeValue'}}}, ... 'Fn::GetAtt': ['SomeResource', 'SomeKey']} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).fn_get_att(['SomeResource', 'SomeKey']) 'SomeValue' >>> root = {'Resources': ... {'SomeResource': {'Properties': {'List': [{'SomeKey': 'SomeValue'}]}}}, ... 'Fn::GetAtt': ['SomeResource', 'SomeKey']} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).fn_get_att(['SomeResource', 'SomeKey']) 'SomeValue' >>> root = {'Fn::GetAtt': ['SomeResource', 'SomeKey']} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).fn_get_att(['SomeResource', 'SomeKey']) 'UNKNOWN ATT: SomeResource.SomeKey' >>> root = {'Resources': {}, ... 'Fn::GetAtt': ['SomeResource', 'SomeKey']} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).fn_get_att(['SomeResource', 'SomeKey']) 'UNKNOWN ATT: SomeResource.SomeKey' """ if len(value) != 2: # the given value list must be an array with 2 values # if not, just return what is given return ".".join(value) resource_name, key = value if resource_name in self.root.get('Resources', ()): resource = self.parser.exploded(self.root['Resources'], resource_name) try: return self._find_att(resource, key) except KeyError as e: if e.args != (key, ): raise return UnknownValue("ATT: {}.{}".format(resource_name, key))
def ref(self, value): """ >>> from aws_parsecf.parser import Parser >>> root = {'Ref': 'AWS::Region'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).ref('AWS::Region') 'us-east-1' >>> root = {'Ref': 'AWS::NoValue'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).ref('AWS::NoValue') DELETE >>> root = {'Resources': ... {'SomeFunction': {'Type': 'AWS::Lambda::Function', ... 'Properties': {'FunctionName': 'SomeFunctionName'}}}, ... 'Ref': 'SomeFunction'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).ref('SomeFunction') 'SomeFunctionName' >>> root = {'Parameters': {'SomeParameter': {'Type': 'String', 'Default': "SomeValue"}}, ... 'Ref': 'SomeParameter'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1', ... ).ref('SomeParameter') 'SomeValue' >>> root = {'Parameters': {'SomeParameter': {'Type': 'String'}}, ... 'Ref': 'SomeParameter'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1', ... {'SomeParameter': "SomeValue"} ... ).ref('SomeParameter') 'SomeValue' >>> root = {'Parameters': {'SomeParameter': {'Type': 'String'}}, ... 'Ref': 'SomeParameter'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).ref('SomeParameter') 'UNKNOWN REF: SomeParameter' >>> root = {'Ref': 'SomeParameter'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1', ... {'SomeParameter': "SomeValue"}, ... ).ref('SomeParameter') 'UNKNOWN REF: SomeParameter' >>> root = {'Resources': ... {'SomeFunction': {'Type': 'AWS::Lambda::Function', 'Properties': {}}}, ... 'Ref': 'SomeFunction'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).ref('SomeFunction') 'UNKNOWN REF: SomeFunction' >>> root = {'Ref': 'SomeValue'} >>> Functions(Parser(root, 'us-east-1'), ... root, ... 'us-east-1' ... ).ref('SomeValue') 'UNKNOWN REF: SomeValue' """ # pseudo function? function = Functions.REF_PSEUDO_FUNCTIONS.get(value) if function: return function(self) # parameter? if value in self.root.get('Parameters', ()): if value in self.parameters: return self.parameters[value] parameter = self.parser.exploded(self.root['Parameters'], value) if 'Default' in parameter: return parameter['Default'] return UnknownValue("REF: {}".format(value)) # resource logical id? if value in self.root.get('Resources', ()): resource = self.parser.exploded(self.root['Resources'], value) # if the resource doesn't have 'Type' attribute like being converted to DELETE, don't process it # because the deleted resource does NOT have any attrbutes including 'Type' # by Alex Ough on July 2nd 2018 if 'Type' in resource: name_type = Functions.REF_RESOURCE_TYPE_PATTERN.match( resource['Type']) if name_type: name = resource.get('Properties', {}).get("{}Name".format( name_type.group(1))) if name: return name return UnknownValue("REF: {}".format(value))