3 O4Â\5ã@sLddlmZddlmZGdd„deƒZGdd„deƒZGdd„deƒZd S) é)ÚSamResourceType)Ú is_intrinsicsc@s¢eZdZdZdZdZejjddddddd d d d d ddddddgej jddddddddddddd d!d"gej jd#giZ d$d%„Z d&d'„Z ed(d)„ƒZd*d+„Zd,d-„Zd.S)/ÚGlobalszØ Class to parse and process Globals section in SAM template. If a property is specified at Global section for say Function, then this class will add it to each resource of AWS::Serverless::Function type. zAWS::Serverless::ÚHandlerZRuntimeZCodeUriZDeadLetterQueueÚ DescriptionZ MemorySizeZTimeoutZ VpcConfigÚ EnvironmentZTagsZTracingZ KmsKeyArnZAutoPublishAliasZLayersZDeploymentPreferenceZPermissionsBoundaryZReservedConcurrentExecutionsZAuthÚNameZ DefinitionUriZCacheClusterEnabledZCacheClusterSizeÚ VariablesZEndpointConfigurationZMethodSettingsZBinaryMediaTypesZMinimumCompressionSizeZCorsZGatewayResponsesZAccessLogSettingZ CanarySettingZTracingEnabledZSSESpecificationcsJ‡fdd„ˆjjƒDƒˆ_ˆjjƒiˆ_ˆj|krFˆj|ˆjƒˆ_dS)zp Constructs an instance of this object :param dict template: SAM template to be parsed csg|]}|jˆjdƒ‘qS)Ú)ÚreplaceÚ_RESOURCE_PREFIX)Ú.0Úx)Úself©ú�/Users/sshvans/Documents/Work/Quickstart/python-virtual-environments/env/lib/python3.6/site-packages/samtranslator/plugins/globals/globals.pyú Fsz$Globals.__init__..N)Úsupported_propertiesÚkeysÚ supported_resource_section_namesÚsortÚtemplate_globalsÚ_KEYWORDÚ_parse)rÚtemplater)rrÚ__init__@s    zGlobals.__init__cCs"||jkr|S|j|}|j|ƒS)a� Adds global properties to the resource, if necessary. This method is a no-op if there are no global properties for this resource type :param string resource_type: Type of the resource (Ex: AWS::Serverless::Function) :param dict resource_properties: Properties of the resource that need to be merged :return dict: Merged properties of the resource )rÚmerge)rÚ resource_typeZresource_propertiesZ global_propsrrrrPs  z Globals.mergecCs|j|kr||j=dS)z Helper method to delete the Globals section altogether from the template :param dict template: SAM template :return: Modified SAM template with Globals section N)r)ÚclsrrrrÚ del_sectionbs zGlobals.del_sectionc CsÊi}t|tƒs"t|jdj|jƒƒ‚x¢|jƒD]–\}}|j|ƒ}||jkr`t|jdj||jd�ƒ‚t|tƒsvt|jdƒ‚x>|jƒD]2\}}|j|}||kr€t|jdj|||d�ƒ‚q€Wt |ƒ||<q,W|S)af Takes a SAM template as input and parses the Globals section :param globals_dict: Dictionary representation of the Globals section :return: Processed globals dictionary which can be used to quickly identify properties to merge :raises: InvalidResourceException if the input contains properties that we don't support z!It must be a non-empty dictionaryzO'{section}' is not supported. Must be one of the following values - {supported})ÚsectionÚ supportedz(Value of ${section} must be a dictionaryze'{key}' is not a supported property of '{section}'. Must be one of the following values - {supported})Úkeyr r!) Ú isinstanceÚdictÚInvalidGlobalsSectionExceptionrÚformatÚitemsÚ_make_resource_typerrÚGlobalProperties) rZ globals_dictÚglobalsÚ section_nameZ propertiesrr"Úvaluer!rrrrns*        zGlobals._parsecCs |j|S)N)r )rr"rrrr(—szGlobals._make_resource_typeN)Ú__name__Ú __module__Ú __qualname__Ú__doc__rr rZFunctionr,ZApiZ SimpleTablerrrÚ classmethodrrr(rrrrrsX )rc@sVeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z Gdd„dƒZ dS)r)av Object holding the global properties of given type. It also contains methods to perform a merge between Global & resource-level properties. Here are the different cases during the merge and how we handle them: **Primitive Type (String, Integer, Boolean etc)** If either global & local are of primitive types, then we the value at local will overwrite global. Example: ``` Global: Function: Runtime: nodejs Function: Runtime: python ``` After processing, Function resource will contain: ``` Runtime: python ``` **Different data types** If a value at Global is a array, but local is a dictionary, then we will simply use the local value. There is no merge to be done here. Similarly for other data type mismatches between global & local value. Example: ``` Global: Function: CodeUri: s3://bucket/key Function: CodeUri: Bucket: foo Key: bar ``` After processing, Function resource will contain: ``` CodeUri: Bucket: foo Key: bar ``` **Arrays** If a value is an array at both global & local level, we will simply concatenate them without de-duplicating. Customers can easily fix the duplicates: Example: ``` Global: Function: Policy: [Policy1, Policy2] Function: Policy: [Policy1, Policy3] ``` After processing, Function resource will contain: (notice the duplicates) ``` Policy: [Policy1, Policy2, Policy1, Policy3] ``` **Dictionaries** If both global & local value is a dictionary, we will recursively merge properties. If a value is one of the above types, they will handled according the above rules. Example: ``` Global: EnvironmentVariables: TableName: foo DBName: generic-db Function: EnvironmentVariables: DBName: mydb ConnectionString: bar ``` After processing, Function resource will contain: ``` EnvironmentVariables: TableName: foo DBName: mydb ConnectionString: bar ``` ***Optional Properties*** Some resources might have optional properties with default values when it is skipped. If an optional property is skipped at local level, an explicitly specified value at global level will be used. Example: Global: DeploymentPreference: Enabled: False Type: Canary Function: DeploymentPreference: Type: Linear After processing, Function resource will contain: ``` DeploymentPreference: Enabled: False Type: Linear ``` (in other words, Deployments will be turned off for the Function) cCs ||_dS)N)Úglobal_properties)rr2rrrrszGlobalProperties.__init__cCs|j|j|ƒS)z– Merge Global & local level properties according to the above rules :return local_properties: Dictionary of local properties )Ú _do_merger2)rZlocal_propertiesrrrrszGlobalProperties.mergecCs´|j|ƒ}|j|ƒ}||kr(|j||ƒS|jj|ko>|knrP|j||ƒS|jj|kof|knrx|j||ƒS|jj|koŽ|knr |j||ƒStdj ||ƒƒ‚dS)aK Actually perform the merge operation for the given inputs. This method is used as part of the recursion. Therefore input values can be of any type. So is the output. :param global_value: Global value to be merged :param local_value: Local value to be merged :return: Merged result z8Unsupported type of objects. GlobalType={}, LocalType={}N) Ú _token_ofÚ _prefer_localÚTOKENÚ PRIMITIVEÚDICTÚ _merge_dictÚLISTÚ _merge_listsÚ TypeErrorr&)rÚ global_valueÚ local_valueZ token_globalZ token_localrrrr3s      zGlobalProperties._do_mergecCs||S)a Merges the global list with the local list. List merging is simply a concatenation = global + local :param global_list: Global value list :param local_list: Local value list :return: New merged list with the elements shallow copied r)rZ global_listZ local_listrrrr;<s zGlobalProperties._merge_listscCsL|jƒ}x>|jƒD]2}||kr8|j||||ƒ||<q||||<qW|S)zí Merges the two dictionaries together :param global_dict: Global dictionary to be merged :param local_dict: Local dictionary to be merged :return: New merged dictionary with values shallow copied )Úcopyrr3)rZ global_dictZ local_dictr"rrrr9Gs zGlobalProperties._merge_dictcCs|S)a; Literally returns the local value whatever it may be. This method is useful to provide a unified implementation for cases that don't require special handling. :param global_value: Global value :param local_value: Local value :return: Simply returns the local value r)rr=r>rrrr5_s zGlobalProperties._prefer_localcCsBt|tƒr$t|ƒr|jjS|jjSnt|tƒr6|jjS|jjSdS)z¢ Returns the token type of the input. :param input: Input whose type is to be determined :return TOKENS: Token type of the input N)r#r$rr6r7r8Úlistr:)rÚinputrrrr4js   zGlobalProperties._token_ofc@seZdZdZdZdZdZdS)zGlobalProperties.TOKENz4 Enum of tokens used in the merging Z primitiver$r@N)r-r.r/r0r7r8r:rrrrr6‚sr6N) r-r.r/r0rrr3r;r9r5r4r6rrrrr)›sv  r)c@s$eZdZdZdd„Zedd„ƒZdS)r%zxException raised when a Globals section is is invalid. Attributes: message -- explanation of the error cCs||_||_dS)N)Ú _logical_idÚ_message)rZ logical_idÚmessagerrrr‘sz'InvalidGlobalsSectionException.__init__cCsdj|j|jƒS)Nz'{}' section is invalid. {})r&rBrC)rrrrrD•sz&InvalidGlobalsSectionException.messageN)r-r.r/r0rÚpropertyrDrrrrr%‹sr%N) Z!samtranslator.public.sdk.resourcerZsamtranslator.public.intrinsicsrÚobjectrr)Ú Exceptionr%rrrrÚs  q