U `„`³0ã@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@seZdZdCdd„Zdd„Zefd d „Zd d „Zd d„Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*efd+d,„Zd-d.„Zd/d0„Zed1d2„ƒZd3d4„Zd5d6„Zd7d8„Zd9d:„Zd;d<„Z d=d>„Z!d?d@„Z"dAdB„Z#d)S)DÚ CfnResourceFÚDEBUGÚERRORéc CsJd|_d|_d|_d|_d|_d|_d|_d|_||_||_ ||_ d|_ ||_ d|_ d|_d|_d|_d|_d|_i|_i|_d|_d|_t d¡|_t d¡|_zf|jsàtjd|jd|_tjd|jd|_tjd|jd|_|röt j!||d d nt j!|d|d Wn<t"k rD}zt#j$|d d | %|¡W5d}~XYnXdS)NFÚZ AWS_SAM_LOCALZ AWS_REGIONÚlambda)Ú region_nameÚeventsÚlogsZ ContainerInit)Ú boto_levelÚ RequestType)Ú formatter_clsrT©Úexc_info)&Ú _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Ú_eventÚ_contextÚ _response_urlÚosÚgetenvÚ _sam_localZ_regionÚboto3ÚclientÚ_lambda_clientÚ_events_clientZ _logs_clientrÚsetupÚ ExceptionÚloggerÚerrorÚ init_failure)ÚselfÚ json_loggingÚ log_levelrÚpolling_intervalÚe©r=úp/Volumes/workspace/Demo/src/IotBifrostDemoAssets/src/iot_sitewise_asset_model_lambda/crhelper/resource_helper.pyÚ__init__sH  zCfnResource.__init__c CsôzÜz–| ||¡t |¡| ||¡| ¡r@|jr@t d¡n$| ¡rT|  |¡nt d¡d|_ t d|j ¡|j r–|j dkrŒ|  ¡|  |¡Wn@tk rØ}z"tj|dd| tt|ƒ¡W5d}~XYnXW5|jrî|j ¡XdS)NzÚ__call__Es(       &zCfnResource.__call__cCs6t|j ¡dƒd}|dkr"d}|dkr2||ƒdS)Nièééxé)Úintr*Úget_remaining_time_in_millis)r8rZ sleep_timer=r=r>rG_s 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)rrr3rr rS©r8rKrLr=r=r>rAfsþzCfnResource._log_setupcCs´d|_t|_d|_d|_|d|_|d|_|d|_i|_d|  ¡krR|d|_|d|_ ||_ ||_ |d|_ |jr‚|j ¡|jrš| tt|jƒ¡S| ¡| | ¡¡dS) NFr r%r&r'Ú CrHelperDatarZ ResponseURL)rrr"r#r$r%r&r'r(Úkeysrr)r*r+rr@rrIrrJÚ _set_timeoutÚ_wrap_functionÚ _get_funcrTr=r=r>rCns(        zCfnResource._crhelper_initcCs–t d|j¡d| ¡krZ|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) r5rBr$rVr"rrEr(Ú_setup_pollingÚ_remove_pollingr©r8rKr=r=r>rF„s   zCfnResource._polling_initcCs’|js(d| ¡kr(t d¡|d|_n^|jr8|jdkr†d| ¡krNt d¡t d¡|d d¡dd|d d| d ¡|_| ¡dS) Nr$zrH”s     ÿÿÿzCfnResource._cfn_responsecCst|d |jd ¡¡ƒS)Nz _poll_{}_funcr)ÚgetattrÚformatr)Úlower©r8r=r=r>rD¢szCfnResource._poll_enabledcCs ||_|S©N)r©r8Úfuncr=r=r>Úcreate¥szCfnResource.createcCs ||_|Srg)rrhr=r=r>Úupdate©szCfnResource.updatecCs ||_|Srg)rrhr=r=r>Údelete­szCfnResource.deletecCs ||_|Srg)rrhr=r=r>Ú poll_create±szCfnResource.poll_createcCs ||_|Srg)rrhr=r=r>Ú poll_updateµszCfnResource.poll_updatecCs ||_|Srg)rrhr=r=r>Ú poll_delete¹szCfnResource.poll_deletec Csfz|r||j|jƒnd|_WnDtk r`}z&tjt|ƒddt|ƒ|_t|_ W5d}~XYnXdS)Nr Tr) r)r*r$r4r5r6rJr#rr")r8rir<r=r=r>rX½s  zCfnResource._wrap_functioncCst d¡| td¡dS)Nz7Execution is about to time out, sending failure messagezExecution timed out)r5r6rIrrfr=r=r>Ú_timeoutÅs zCfnResource._timeoutcCs,t |j ¡dd|j¡|_|j ¡dS)Ng@@gà?)Ú threadingÚTimerr*rRrprÚstartrfr=r=r>rWÉsÿzCfnResource._set_timeoutcCs4d}d|j ¡krd|}t|| |jd ¡¡ƒS)Nz_{}_funcrZZ_pollr)r)rVrcrdre)r8Z request_typer=r=r>rYÎszCfnResource._get_funcNr cCsºttt|jƒƒƒdkrrIÔs& ù zCfnResource._sendcCs||_tjt|ƒdddS)NTr)rr5r6rJ)r8r6r=r=r>r7æszCfnResource.init_failurecCs$dD]}||j ¡kr|j|=qdS)N)rZÚCrHelperPermissionÚ CrHelperRule)r(rV)r8Úkr=r=r>Ú_cleanup_responseêszCfnResource._cleanup_responsecCsd dd„t|ƒDƒ¡S)Nr css |]}t tjtj¡VqdSrg)ÚrandomÚchoiceÚstringÚascii_uppercaseÚdigits)Ú.0r_r=r=r>Ú ñsz+CfnResource._rand_string..)ÚjoinÚrange)Úlr=r=r>rbïszCfnResource._rand_stringcCs2|jd| d¡}|jj|jj|dd|d|S)Nr'r`zlambda:InvokeFunctionzevents.amazonaws.com)Ú FunctionNameÚ StatementIdÚActionZ PrincipalZ SourceArn)r)rbr1Zadd_permissionr*Ú function_name)r8Úrule_arnÚsidr=r=r>Ú_add_permissionósûzCfnResource._add_permissioncCs2|jj|jd| d¡d |j¡dd}|dS)Nr'r`zrate({} minutes)ZENABLED)ÚNameZScheduleExpressionÚStateZRuleArn)r2Zput_ruler)rbrdr!)r8Ú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{ú:éérPr^Ú1zarn:%s:lambda:%s:%s:function:%s)ZIdZArnZInput)ÚRuleZTargets)r)rar5rBr2Z put_targetsÚjsonÚdumps)r8Ú func_nameÚregionZ account_idÚ partitionZ rule_namer=r=r>Ú _put_targetss  ýÿþzCfnResource._put_targetscCs |jj| d¡ddgddS)Nr^rPr–)r—ZIds)r2Zremove_targetsra©r8rŒr=r=r>Ú_remove_targetss þzCfnResource._remove_targetscCs|jj|jj|ddS)N)rˆr‰)r1Zremove_permissionr*r‹)r8rr=r=r>Ú_remove_permissionsþzCfnResource._remove_permissioncCs|jj| d¡dddS)Nr^rP)r)r2Z delete_ruleraržr=r=r>Ú _delete_rule#s ÿzCfnResource._delete_rulecCsL|j|jd<d|jd<| ¡|jd<| |jd¡|jd<| |jj¡dS)NrUTrZr{rz)r(r)r’rŽrr*r‹rfr=r=r>r[(s   zCfnResource._setup_pollingcCs¶d|j ¡kr|j d¡d|j ¡kr4|j d¡d|j ¡krT| |jd¡n t d¡d|j ¡kr~| |jd¡n t d¡d|j ¡kr¨| |jd¡n t d¡dS)NrUr$r{zECannot remove CloudWatch events rule, Rule arn not available in eventrzzLCannot remove lambda events permission, permission id not available in eventzGCannot remove CloudWatch events target, Rule arn not available in event) r)rVÚpopr(rŸr5r6r r¡rfr=r=r>r\/s    zCfnResource._remove_polling)Fr r r )$Ú__name__Ú __module__Ú __qualname__r?rMrrGrArCrFrHrDrjrkrlrmrnrorXrprWrYrrIr7r}Ú staticmethodrbrŽr’rrŸr r¡r[r\r=r=r=r>rs> '   r)Ú__doc__Ú __future__rrqZcrhelper.utilsrÚcrhelperrÚloggingr~r/r€r˜r,ÚtimerÚ getLoggerr£r5rrÚobjectrr=r=r=r>Ús