1from enum import Enum 2from samtranslator.model.exceptions import InvalidDocumentException, InvalidTemplateException 3from samtranslator.model.types import is_str 4 5 6class SamResource(object): 7 """ 8 Class representing a SAM resource. It is designed to make minimal assumptions about the resource structure. 9 Any mutating methods also touch only "Properties" and "Type" attributes of the resource. This allows compatibility 10 with any CloudFormation constructs, like DependsOn, Conditions etc. 11 """ 12 13 type = None 14 properties = {} 15 16 def __init__(self, resource_dict): 17 """ 18 Initialize the object given the resource as a dictionary 19 20 :param dict resource_dict: Resource dictionary containing type & properties 21 """ 22 23 self.resource_dict = resource_dict 24 self.type = resource_dict.get("Type") 25 self.condition = resource_dict.get("Condition", None) 26 self.deletion_policy = resource_dict.get("DeletionPolicy", None) 27 self.update_replace_policy = resource_dict.get("UpdateReplacePolicy", None) 28 29 # Properties is *not* required. Ex: SimpleTable resource has no required properties 30 self.properties = resource_dict.get("Properties", {}) 31 32 def valid(self): 33 """ 34 Checks if the resource data is valid 35 36 :return: True, if the resource is valid 37 """ 38 # As long as the type is valid and type string. 39 # validate the condition should be string 40 41 if self.condition: 42 43 if not is_str()(self.condition, should_raise=False): 44 raise InvalidDocumentException([InvalidTemplateException("Every Condition member must be a string.")]) 45 46 if self.deletion_policy: 47 48 if not is_str()(self.deletion_policy, should_raise=False): 49 raise InvalidDocumentException( 50 [InvalidTemplateException("Every DeletionPolicy member must be a string.")] 51 ) 52 53 if self.update_replace_policy: 54 55 if not is_str()(self.update_replace_policy, should_raise=False): 56 raise InvalidDocumentException( 57 [InvalidTemplateException("Every UpdateReplacePolicy member must be a string.")] 58 ) 59 60 return SamResourceType.has_value(self.type) 61 62 def to_dict(self): 63 64 if self.valid(): 65 # Touch a resource dictionary ONLY if it is valid 66 # Modify only Type & Properties section to preserve CloudFormation properties like DependsOn, Conditions etc 67 self.resource_dict["Type"] = self.type 68 self.resource_dict["Properties"] = self.properties 69 70 return self.resource_dict 71 72 73class SamResourceType(Enum): 74 """ 75 Enum of supported SAM types 76 """ 77 78 Api = "AWS::Serverless::Api" 79 Function = "AWS::Serverless::Function" 80 SimpleTable = "AWS::Serverless::SimpleTable" 81 Application = "AWS::Serverless::Application" 82 LambdaLayerVersion = "AWS::Serverless::LayerVersion" 83 HttpApi = "AWS::Serverless::HttpApi" 84 StateMachine = "AWS::Serverless::StateMachine" 85 86 @classmethod 87 def has_value(cls, value): 88 """ 89 Checks if the given value belongs to the Enum 90 91 :param string value: Value to be checked 92 :return: True, if input is in the Enum 93 """ 94 return any(value == item.value for item in cls) 95