a _Æb12ã@s’dZddlmZddlZddlmZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlmZe e¡ZdZdZGd d „d eƒZdS) uT TODO: * Async mode – take a wait condition handle as an input, increases max timeout to 12 hours * Idempotency – If a duplicate request comes in (say there was a network error in signaling back to cfn) the subsequent request should return the already created response, will need a persistent store of some kind... * Functional tests é)Úprint_functionN)Ú_send_response)Ú log_helper)ÚsleepÚSUCCESSÚFAILEDc@seZdZdFdd„Zd d „Zefd d „Zd d„Zdd„Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zdd-efd.d/„Zd0d1„Zd2d3„Zed4d5„ƒZd6d7„Zd8d9„Zd:d;„Zdd?„Z!d@dA„Z"dBdC„Z#dDdE„Z$dS)GÚ CfnResourceFÚDEBUGÚERRORééxNc Csl||_d|_d|_d|_d|_d|_d|_d|_d|_||_ ||_ ||_ d|_ ||_ d|_d|_d|_d|_d|_d|_i|_d|_i|_d|_d|_t d¡|_t d¡|_||_zt|jsþtjd|j|jd|_ tjd|j|jd|_!tjd|j|jd|_"|rt#j$||d d nt#j$|d|d Wn>t%yf}z$t&j'|d d | (|¡WYd}~n d}~00dS)NFÚZ AWS_SAM_LOCALZ AWS_REGIONÚlambda)Z region_nameÚverifyÚeventsZlogsZ ContainerInit)Ú boto_levelÚ RequestType)Ú formatter_clsrT©Úexc_info))Ú_sleep_on_deleteÚ _create_funcÚ _update_funcÚ _delete_funcÚ_poll_create_funcÚ_poll_update_funcÚ_poll_delete_funcÚ_timerÚ _init_failedÚ _json_loggingÚ _log_levelÚ _boto_levelrÚ_polling_intervalÚStatusÚReasonÚPhysicalResourceIdÚStackIdÚ RequestIdÚLogicalResourceIdÚDataÚNoEchoÚ_eventÚ_contextÚ _response_urlÚosÚgetenvÚ _sam_localZ_regionÚ _ssl_verifyÚboto3ÚclientÚ_lambda_clientÚ_events_clientZ _logs_clientrÚsetupÚ ExceptionÚloggerÚerrorÚ init_failure)ÚselfZ json_loggingÚ log_levelrZpolling_intervalZsleep_on_deleteZ ssl_verifyÚe©r>ú?/tmp/pip-target-4jja1joz/lib/python/crhelper/resource_helper.pyÚ__init__sN  zCfnResource.__init__c Cs$zz®| ||¡t |¡| ||¡s@WW|jr<|j ¡dS| ¡rZ|jrZt d¡n$| ¡rn|  |¡nt d¡d|_ t d|j ¡|j r°|j dkr¦|  ¡|  |¡WnBtyô}z*tj|dd| tt|ƒ¡WYd}~n d}~00W|jr |j ¡n|jr|j ¡0dS)Nzr>r?Ú__call__Hs4    ì    ( ÿzCfnResource.__call__cCs>t|j ¡dƒd}d}||jkr*|j}|dkr:||ƒdS)Nièéré)Úintr,Úget_remaining_time_in_millisr)r;rZ time_leftZ sleep_timer>r>r?rIcs  zCfnResource._wait_for_cwlogsc CsN|jr6tj|j|j|d|d|d|d|jdntj|j|jdddS)Nrr&r'r()rrr&r'r(Úaws_request_id)rr)rrr6r r!rT©r;rMrNr>r>r?rBms   þzCfnResource._log_setupcCs¸d|_t|_d|_d|_|d|_|d|_|d|_i|_d|  ¡vrR|d|_|d|_ ||_ ||_ |d|_ |jr‚|j ¡|jrž| tt|jƒ¡dS| ¡| | ¡¡d S) NFr r&r'r(Ú CrHelperDatarZ ResponseURLT)rrr#r$r%r&r'r(r)Úkeysrr+r,r-rrErrKrrLÚ _set_timeoutÚ_wrap_functionÚ _get_funcrUr>r>r?rDus,        zCfnResource._crhelper_initcCs–t d|j¡d| ¡vrZ|jtkrZt d¡|j|jd<| ¡d|_t d|j¡t d|j¡|jsz|jtkr’t d¡|  ¡d|_ dS) Nzpid1: %sÚ CrHelperPollzSetting up pollingr%zpid2: %szpid3: %sz'Polling complete, removing cwe scheduleT) r8rCr%rWr#rrGr)Ú_setup_pollingÚ_remove_pollingr©r;rMr>r>r?rHs   zCfnResource._polling_initcCs(d |d d¡d|d| d¡g¡S)NÚ_r&ú/rQr(é)ÚjoinÚsplitÚ _rand_stringr^r>r>r?Úgenerate_physical_ids ýz CfnResource.generate_physical_idcCsZ|js(d| ¡vr(t d¡|d|_n&|jr8|jdurNt d¡| |¡|_| ¡dS)Nr%zr>r?rJ¤s    zCfnResource._cfn_responsecCst|d |jd ¡¡ƒS)Nz _poll_{}_funcr)ÚgetattrÚformatr+Úlower©r;r>r>r?rF¯szCfnResource._poll_enabledcCs ||_|S©N)r©r;Úfuncr>r>r?Úcreate²szCfnResource.createcCs ||_|Srj)rrkr>r>r?Úupdate¶szCfnResource.updatecCs ||_|Srj)rrkr>r>r?ÚdeleteºszCfnResource.deletecCs ||_|Srj)rrkr>r>r?Ú poll_create¾szCfnResource.poll_createcCs ||_|Srj)rrkr>r>r?Ú poll_updateÂszCfnResource.poll_updatecCs ||_|Srj)rrkr>r>r?Ú poll_deleteÆszCfnResource.poll_deletec Cshz|r||j|jƒnd|_WnFtyb}z.tjt|ƒddt|ƒ|_t|_ WYd}~n d}~00dS)Nr Tr) r+r,r%r7r8r9rLr$rr#)r;rlr=r>r>r?rYÊs  zCfnResource._wrap_functioncCst d¡| td¡dS)Nz7Execution is about to time out, sending failure messagezExecution timed out)r8r9rKrrir>r>r?Ú_timeoutÒs zCfnResource._timeoutcCs,t |j ¡dd|j¡|_|j ¡dS)Ng@@gà?)Ú threadingÚTimerr,rSrsrÚstartrir>r>r?rXÖsÿzCfnResource._set_timeoutcCs4d}d|j ¡vrd|}t|| |jd ¡¡ƒS)Nz_{}_funcr[Z_pollr)r+rWrfrgrh)r;Z request_typer>r>r?rZÛszCfnResource._get_funcr c CsÂttt|jƒƒƒdkrr>r?rKás & ø zCfnResource._sendcCs||_tjt|ƒdddS)NTr)rr8r9rL)r;r9r>r>r?r:ôszCfnResource.init_failurecCs$dD]}||j ¡vr|j|=qdS)N)r[ÚCrHelperPermissionÚ CrHelperRule)r)rW)r;Úkr>r>r?Ú_cleanup_responseøszCfnResource._cleanup_responsecCsd dd„t|ƒDƒ¡S)Nr css |]}t tjtj¡VqdSrj)ÚrandomÚchoiceÚstringÚascii_uppercaseÚdigits)Ú.0r_r>r>r?Ú ÿóz+CfnResource._rand_string..)rbÚrange)Úlr>r>r?rdýszCfnResource._rand_stringcCs2|jd| d¡}|jj|jj|dd|d|S)Nr(razlambda:InvokeFunctionzevents.amazonaws.com)Ú FunctionNameÚ StatementIdÚActionZ PrincipalZ SourceArn)r+rdr4Zadd_permissionr,Ú function_name)r;Úrule_arnÚsidr>r>r?Ú_add_permissionsûzCfnResource._add_permissioncCs2|jj|jd| d¡d |j¡dd}|dS)Nr(razrate({} minutes)ZENABLED)ÚNameZScheduleExpressionÚStateZRuleArn)r5Zput_ruler+rdrgr")r;Úresponser>r>r?Ú _put_rule s  ýzCfnResource._put_rulecCsŽ|jd d¡d}|jd d¡d}|jd d¡d}|jd d¡d}t |j¡|jj|dd||||ft |j¡d œgd dS) Nr}ú:éérQr`Ú1zarn:%s:lambda:%s:%s:function:%s)ZIdZArnZInput)ÚRuleZTargets)r+rcr8rCr5Z put_targetsÚjsonÚdumps)r;Ú func_nameÚregionZ account_idÚ partitionZ rule_namer>r>r?Ú _put_targetss  ýÿþzCfnResource._put_targetscCs |jj| d¡ddgddS)Nr`rQr˜)r™ZIds)r5Zremove_targetsrc©r;rŽr>r>r?Ú_remove_targets%s þzCfnResource._remove_targetscCs|jj|jj|ddS)N)rŠr‹)r4Zremove_permissionr,r)r;rr>r>r?Ú_remove_permission+sþzCfnResource._remove_permissioncCs|jj| d¡dddS)Nr`rQ)r‘)r5Z delete_rulercr r>r>r?Ú _delete_rule1s ÿzCfnResource._delete_rulecCsL|j|jd<d|jd<| ¡|jd<| |jd¡|jd<| |jj¡dS)NrVTr[r}r|)r)r+r”rrŸr,rrir>r>r?r\6s   zCfnResource._setup_pollingcCs¶d|j ¡vr|j d¡d|j ¡vr4|j d¡d|j ¡vrT| |jd¡n t d¡d|j ¡vr~| |jd¡n t d¡d|j ¡vr¨| |jd¡n t d¡dS)NrVr%r}zECannot remove CloudWatch events rule, Rule arn not available in eventr|zLCannot remove lambda events permission, permission id not available in eventzGCannot remove CloudWatch events target, Rule arn not available in event) r+rWÚpopr)r¡r8r9r¢r£rir>r>r?r]=s    zCfnResource._remove_polling)Fr r r r N)%Ú__name__Ú __module__Ú __qualname__r@rOrrIrBrDrHrerJrFrmrnrorprqrrrYrsrXrZrrKr:rÚ staticmethodrdrr”rŸr¡r¢r£r\r]r>r>r>r?rs@ *    r)Ú__doc__Ú __future__rrtZcrhelper.utilsrZcrhelperrÚloggingr€r2r‚ršr.ÚtimerÚ getLoggerr¥r8rrÚobjectrr>r>r>r?Ús