3 O4\g@sXddlZddlZddlmZddlmZmZddlmZm Z m Z m Z m Z ddl mZmZmZmZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd l m!Z!m"Z"ddl#m$Z$dZ%GdddeZ&Gddde&Z'Gddde&Z(Gddde&Z)Gddde&Z*Gddde&Z+Gddde&Z,Gddde&Z-dS) N) string_types) ResourceMacro PropertyType)is_typelist_ofdict_ofone_ofis_str)reffnSubmake_shorthandmake_conditional) get_tag_list)S3Bucket)SNSSubscription)LambdaPermission) EventsRule) IotTopicRule) ArnGenerator)InvalidEventExceptionInvalidResourceException) SwaggerEditor Conditionc@seZdZdZdZdddZdS)PushEventSourceaBase class for push event sources for SAM Functions. Push event sources correspond to services that call Lambda's Invoke API whenever an event occurs. Each Push event needs an Lambda Permission resource, which will add permissions for the source service to invoke the Lambda function to the function's resource policy. SourceArn is attached to the resource policy to avoid giving lambda invoke permissions to every resource of that category. ARN is currently constructed in ARN format http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for: - API gateway - IotRule ARN is accessible through Fn:GetAtt for: - Schedule - Cloudwatch :cvar str principal: The AWS service principal of the source service. Nc Csrt|jd||jd}y|jd}Wntk rF|jd}YnXd|_||_|j|_||_ ||_ ||_ |S)zConstructs the Lambda Permission resource allowing the source service to invoke the function this event source triggers. :returns: the permission resource :rtype: model.lambda_.LambdaPermission Z Permission)Z attributesnamearnzlambda:invokeFunction) r logical_idZ#get_passthrough_resource_attributesget_runtime_attrNotImplementedErrorZActionZ FunctionName principalZ PrincipalZ SourceArnZ SourceAccountZEventSourceToken)selffunction source_arnsource_accountsuffixevent_source_tokenZlambda_permissionZfunction_name_or_arnr'/Users/sshvans/Documents/Work/Quickstart/python-virtual-environments/env/lib/python3.6/site-packages/samtranslator/model/eventsources/push.py_construct_permission+s z%PushEventSource._construct_permission)NNrN)__name__ __module__ __qualname____doc__r r)r'r'r'r(rsrc@sBeZdZdZdZdZedeededZddZ dd Z d S) Schedulez'Scheduled executions for SAM Functions.zevents.amazonaws.comTF)r.InputcKs|jd}|stdg}t|j}|j||j|_|j|g|_|j d}t |j krj|j t |j t |j|j ||d|S)a-Returns the CloudWatch Events Rule and Lambda Permission to which this Schedule event source corresponds. :param dict kwargs: no existing resources need to be modified :returns: a list of vanilla CloudFormation Resources, to which this pull event expands :rtype: list r"z+Missing required keyword argument: functionr)r#)get TypeErrorrrappendr.ZScheduleExpression_construct_targetTargetsr CONDITIONresource_attributesset_resource_attributer))r!kwargsr" resources events_ruler#r'r'r(to_cloudformationNs     zSchedule.to_cloudformationcCs.|jd|jdd}|jdk r*|j|d<|S)zConstructs the Target property for the CloudWatch Events Rule. :returns: the Target property :rtype: dict r LambdaTarget)ArnIdNr/)rrr/)r!r"targetr'r'r(r3is   zSchedule._construct_targetN) r*r+r,r- resource_typer rr property_typesr;r3r'r'r'r(r.Es r.c@sNeZdZdZdZdZedeeede ede dZ ddZ ddZ d S) CloudWatchEventz1CloudWatch Events event source for SAM Functions.zevents.amazonaws.comF)Patternr/ InputPathcKs|jd}|stdg}t|j}|j|_|j|g|_t|j krV|j t|j t|j ||j d}|j |j ||d|S)a>Returns the CloudWatch Events Rule and Lambda Permission to which this CloudWatch Events event source corresponds. :param dict kwargs: no existing resources need to be modified :returns: a list of vanilla CloudFormation Resources, to which this pull event expands :rtype: list r"z+Missing required keyword argument: functionr)r#)r0r1rrrCZ EventPatternr3r4r5r6r7r2rr))r!r8r"r9r:r#r'r'r(r;s     z!CloudWatchEvent.to_cloudformationcCsB|jd|jdd}|jdk r*|j|d<|jdk r>|j|d<|S)zConstructs the Target property for the CloudWatch Events Rule. :returns: the Target property :rtype: dict rr<)r=r>Nr/rD)rrr/rD)r!r"r?r'r'r(r3s    z!CloudWatchEvent._construct_targetN) r*r+r,r-r@r rrdictr rAr;r3r'r'r'r(rBys  rBc@sxeZdZdZdZdZedeedeee eede eedZ ddZ dd Z d d Zd d ZddZdS)S3z)S3 bucket event source for SAM Functions.zs3.amazonaws.comTF)BucketEventsFiltercCsFt|jtr6d|jkr6|jd}||kr6|||dSt|jddS)NRef)bucket bucket_idz;S3 events must reference an S3 bucket in the same template.) isinstancerGrEr relative_id)r!r9rLr'r'r(resources_to_links  zS3.resources_to_linkcKs|jd}|stdd|ks*|ddkr2tdd|ksF|ddkrNtd|d}|d}g}td}|j||d }t|jkr|j||n |j|||j||j |||jt j |||S) aReturns the Lambda Permission resource allowing S3 to invoke the function this event source triggers. :param dict kwargs: S3 bucket resource :returns: a list of vanilla CloudFormation Resources, to which this S3 event expands :rtype: list r"z+Missing required keyword argument: functionrKNz)Missing required keyword argument: bucketrLz,Missing required keyword argument: bucket_idzAWS::AccountId)r$) r0r1r r)r5r6'_depend_on_lambda_permissions_using_tag_depend_on_lambda_permissionsr2"_inject_notification_configurationrZ from_dict)r!r8r"rKrLr9r$ permissionr'r'r(r;s&    zS3.to_cloudformationcCs@|jdg}t|tr|g}t|}|j|jt||d<|S)a| Make the S3 bucket depends on Lambda Permissions resource because when S3 adds a Notification Configuration, it will check whether it has permissions to access Lambda. This will fail if the Lambda::Permissions is not already applied for this bucket to invoke the Lambda. :param dict bucket: Dictionary representing the bucket in SAM template. This is a raw dictionary and not a "resource" object :param model.lambda_.lambda_permission permission: Lambda Permission resource that needs to be created before the bucket. :return: Modified Bucket dictionary Z DependsOn)r0rMrsetaddrlist)r!rKrSZ depends_onZdepends_on_setr'r'r(rQs    z S3._depend_on_lambda_permissionscCsx|jdd}|dkr i}||d<|jdd}|dkr@g}||d<d|jd|jtt|jdgii}|t||d<|S)a Since conditional DependsOn is not supported this undocumented way of implicitely making dependency through tags is used. See https://stackoverflow.com/questions/34607476/cloudformation-apply-condition-on-dependson It is done by using Ref wrapped in a conditional Fn::If. Using Ref implies a dependency, so CloudFormation will automatically wait once it reaches that function, the same as if you were using a DependsOn. PropertiesNZTagszsam:ConditionalDependsOn:zFn::Ifz no dependency)r0rr6r5r r)r!rKrS propertiestagsZdep_tagr'r'r(rP s   z*S3._depend_on_lambda_permissions_using_tagc Csd|jdi}|jdk r"|j|d<|j}t|jtr<|jg}g}xB|D]:}tj|}||d<t|jkrvt |jt|}|j |qFW|j dd}|dkri}||d<|j dd} | dkri} | |d<| j dd} | dkrg} | | d<x|D]} | | kr| j | qW|S)NZFunctionrrIEventrWZNotificationConfigurationZLambdaConfigurations) rrIrHrMrcopydeepcopyr5r6r r2r0) r!r"rKZbase_event_mappingZ event_typesZevent_mappingsZ event_typeZ lambda_eventrXZnotification_configZlambda_notificationsZ event_mappingr'r'r(rR+s:          z%S3._inject_notification_configurationN)r*r+r,r-r@r rr rrrrArOr;rQrPrRr'r'r'r(rFs  .rFc @sXeZdZdZdZdZedeedeee e ee e dZ ddZdd Zd S) SNSz)SNS topic event source for SAM Functions.zsns.amazonaws.comTF)Topic FilterPolicycKs8|jd}|std|j||jd|j||j|jgS)a)Returns the Lambda Permission resource allowing SNS to invoke the function this event source triggers. :param dict kwargs: no existing resources need to be modified :returns: a list of vanilla CloudFormation Resources, to which this SNS event expands :rtype: list r"z+Missing required keyword argument: function)r#)r0r1r)r^_inject_subscriptionr_)r!r8r"r'r'r(r;^s  zSNS.to_cloudformationcCsPt|j}d|_|jd|_||_t|jkr>|jt|jt|dk rL||_ |S)Nlambdar) rrZProtocolrZEndpointZTopicArnr5r6r7r_)r!r"ZtopicZ filterPolicyZ subscriptionr'r'r(r`ms   zSNS._inject_subscriptionN)r*r+r,r-r@r rr rrrrrErAr;r`r'r'r'r(r]Us &r]c@speZdZdZdZdZedeedeedeedee dZ ddZ dd Z d d Z d d ZddZdS)Apiz*Api method event source for SAM Functions.zapigateway.amazonaws.comTF)PathMethod RestApiIdAuthcCs|j}t|tr d|kr |d}d}d}d}t|tr||krd||krd||dkr||d}|d}t|tr|st|d|}qd}n t|jd |||d d S) z If this API Event Source refers to an explicit API resource, resolve the reference and grab necessary data from the explicit API rJ*Z AllStagesNrWZ StageNamezStageName cannot be empty.ZStagezURestApiId property of Api event must reference a valid resource in the same template.)permitted_stager%) explicit_apiexplicit_api_stage)rerMrErrrrN)r!r9Z rest_api_idrhZ stage_suffixrir'r'r(rOs*      zApi.resources_to_linkcKsbg}|jd}|std|jdk r0|jj|_|j|j||d}|jdr^|j|||S)aEIf the Api event source has a RestApi property, then simply return the Lambda Permission resource allowing API Gateway to call the function. If no RestApi is provided, then additionally inject the path, method, and the x-amazon-apigateway-integration into the Swagger body for a provided implicit API. :param dict kwargs: a dict containing the implicit RestApi to be modified, should no explicit RestApi be provided. :returns: a list of vanilla CloudFormation Resources, to which this Api event expands :rtype: list r"z+Missing required keyword argument: functionNriZ__MANAGE_SWAGGER)r0r1rdlowerextend_get_permissions_add_swagger_integration)r!r8r9r"rir'r'r(r;s      zApi.to_cloudformationcCsXg}|j|j|ddd}}d|kr@|dd}|dd}|j|j||||S)NrgZTestZProdrjrhr%)r2_get_permission)r!rOZ permissionsrhr%r'r'r(rms  zApi._get_permissionsc Cstjdd|j}| s| r$td|jdd}|jjdkrBdn|jj}|j}d||}t j }t t j |d |d ||d } |j |d | |d S)Nz^(.+)/$z\1z,Could not add permission to lambda function.z{proxy+}rganyz ${__ApiId__}/z ${__Stage__}/z execute-api) partitionserviceresource)Z __ApiId__Z __Stage__r")r#r%z${__ApiId__}/${__Stage__}/)resubrc RuntimeErrorreplacerdrkupperrerget_partition_namer generate_arnr)) r!rOZstager%pathmethodZapi_idrsrqr#r'r'r(ros    zApi._get_permissionc Cs|jd}|dkrdS|jd}tj}td|dt|d}t|}|j|j|j rvt |j dj |j |jdd}t |jkr|jt }|j|j|j ||j|jd |d |jr|jjd } | r|jd } | o| jd } | d krt| st |j dj | |j |jd| dkrB| j|  rBt |j dj | |j |jd| dkrt| jd rtt |j dj |j |jd|j||j|j |jd|j|d<dS)zAdds the path and method for this Api event source to the Swagger body for the provided RestApi. :param model.apigateway.ApiGatewayRestApi rest_api: the RestApi to which the path and method should be added. ZDefinitionBodyNrzarn:z<:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/z /invocationsz?API method "{method}" defined multiple times for path "{path}".)r|r{rf) conditionZ AuthorizerZ AuthorizersZAWS_IAMzUnable to set Authorizer [{authorizer}] on API method [{method}] for path [{path}] because the related API does not define any Authorizers.)Z authorizerr|r{NONEzUnable to set Authorizer [{authorizer}] on API method [{method}] for path [{path}] because it wasn't defined in the API's Authorizers.ZDefaultAuthorizerzUnable to set Authorizer on API method [{method}] for path [{path}] because 'NONE' is only a valid value when a DefaultAuthorizer on the API is specified.)apir{ method_nameZauth)r0rrryr r rZhas_integrationrcrdrrNformatr5r6Zadd_lambda_integrationrfZadd_auth_to_methodZswagger) r!rr"Z swagger_bodyZ function_arnrqZuriZeditorr}Zmethod_authorizerZapi_authZapi_authorizersr'r'r(rnsP    "   zApi._add_swagger_integrationN)r*r+r,r-r@r rr rrErArOr;rmrornr'r'r'r(rb{s   1rbc@s,eZdZdZdZdedeiZddZdS) AlexaSkillzalexa-appkit.amazon.comSkillIdFcKs4|jd}|stdg}|j|j||jd|S)Nr"z+Missing required keyword argument: function)r&)r0r1r2r)r)r!r8r"r9r'r'r(r;Bs  zAlexaSkill.to_cloudformationN) r*r+r,r@r rr rAr;r'r'r'r(r:src@s>eZdZdZdZedeededZddZddZ d S) IoTRuleziot.amazonaws.comTF)SqlAwsIotSqlVersioncKsx|jd}|stdg}d}tj}ttj|d|ddt|ji}td}|j|j |||d|j|j ||S) Nr"z+Missing required keyword argument: functionzrule/${RuleName}Ziot)rqrrrsZRuleNamez${AWS::AccountId})r#r$) r0r1rryr rzr rr2r)_construct_iot_rule)r!r8r"r9rsrqr#r$r'r'r(r;Ws   zIoTRule.to_cloudformationcCs^t|j}|jddd|jdiigd}|jr8|j|d<||_t|jkrZ|jt|jt|S)NFLambdaZ FunctionArnr)rZ RuleDisabledZActionsr) rrrrrZTopicRulePayloadr5r6r7)r!r"Zrulepayloadr'r'r(rls   zIoTRule._construct_iot_ruleN) r*r+r,r@r rr rAr;rr'r'r'r(rNs  r).r[rtsixrZsamtranslator.modelrrZsamtranslator.model.typesrrrrr Zsamtranslator.model.intrinsicsr r r r Z)samtranslator.model.tags.resource_taggingrZsamtranslator.model.s3rZsamtranslator.model.snsrZsamtranslator.model.lambda_rZsamtranslator.model.eventsrZsamtranslator.model.iotrZ&samtranslator.translator.arn_generatorrZsamtranslator.model.exceptionsrrZsamtranslator.swagger.swaggerrr5rr.rBrFr]rbrrr'r'r'r(s2         048%&@