o
    !dx&                     @   s~   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
m
Z
 eeZedddgZG dd	 d	eZdS )
    N)
exceptions)
mktempfileparse_s3_url)datetimeChangeSetResultchangeset_idchangeset_typec                   @   sL   e Zd Z	dddZdd Zdd Zdd	 Z	
dddZdd Zdd Z	dS )Deployer%awscli-cloudformation-package-deploy-c                 C   s   || _ || _d S N)_clientchangeset_prefix)selfZcloudformation_clientr    r   Qusr/lib/python3.10/site-packages/awscli/customizations/cloudformation/deployer.py__init__!   s   
zDeployer.__init__c              
   C   s   z| j j|d}t|d dkrW dS |d d }|d dkW S  tjjyP } z#t|}d||v rCt	d| W Y d	}~dS tj	d
|d |d	}~ww )z
        Checks if a CloudFormation stack with given name exists

        :param stack_name: Name or ID of the stack
        :return: True if stack exists. False otherwise
        	StackNameZStacks   Fr   ZStackStatusZREVIEW_IN_PROGRESSz Stack with id {0} does not existNzUnable to get stack details.exc_info)
r   Zdescribe_stackslenbotocorer   ZClientErrorstrformatLOGdebug)r   
stack_namerespstackemsgr   r   r   	has_stack&   s"   zDeployer.has_stackc	              
      s|  t   }	d|	}
| jttt  }| |s%d}dd |D }nd}| j	j
|d}dd |d D   fd	d|D }|||||||
|d
}|rt /}||d |  ||jd}t|dd}||d |dd|d< W d   n1 sw   Y  |dur||d< |dur||d< z| j	jdi |}t|d |W S  ty } z	tjd|d |d}~ww )a  
        Call Cloudformation to create a changeset and wait for it to complete

        :param stack_name: Name or ID of stack
        :param cfn_template: CloudFormation template string
        :param parameter_values: Template parameters object
        :param capabilities: Array of capabilities passed to CloudFormation
        :param tags: Array of tags passed to CloudFormation
        :return:
        zCreated by AWS CLI at {0} UTCCREATEc                 S   s   g | ]
}| d ds|qS )UsePreviousValueFget.0xr   r   r   
<listcomp>c   s    

z-Deployer.create_changeset.<locals>.<listcomp>UPDATEr   c                 S   s   g | ]}|d  qS )ParameterKeyr   )r(   	parameterr   r   r   r*   i   s    
Parametersc                    s(   g | ]}| d dr|d  vs|qS )r$   Fr,   r%   r'   Zexisting_parametersr   r   r*   k   s    
)ChangeSetNamer   TemplateBodyZChangeSetTyper.   ZCapabilitiesDescriptionZTagsr1   templateVersion)Zversion_propertyKeyNZTemplateURLZRoleARNZNotificationARNsZIdzUnable to create changesetr   r   )r   utcnow	isoformatr   r   r   inttimer"   r   Zget_template_summaryr   writepopflushZupload_with_dedupnamer   Zto_path_style_s3_urlr&   Zcreate_change_setr   	Exceptionr   r   )r   r   cfn_templateparameter_valuescapabilitiesrole_arnnotification_arnss3_uploadertagsnowdescriptionZchangeset_namer   summarykwargsZtemporary_fileurlpartsr   exr   r/   r   create_changesetJ   sV   


zDeployer.create_changesetc           	   
   C   s   t jd t j  | jd}ddi}z|j|||d W dS  tjj	y[ } z-t
jd|d |j}|d }|d	 }|d
krDd|v sHd|v rNtj|dtd|||d}~ww )z
        Waits until the changeset creation completes

        :param changeset_id: ID or name of the changeset
        :param stack_name:   Stack name
        :return: Latest status of the create-change-set operation
        z'
Waiting for changeset to be created..
Zchange_set_create_completeDelay   )r0   r   WaiterConfigz!Create changeset waiter exceptionr   ZStatusZStatusReasonZFAILEDz1The submitted information didn't contain changes.zNo updates are to be performedr   z<Failed to create the changeset: {0} Status: {1}. Reason: {2}N)sysstdoutr:   r<   r   
get_waiterwaitr   r   WaiterErrorr   r   Zlast_responseZChangeEmptyErrorRuntimeErrorr   )	r   r   r   waiterwaiter_configrL   r   statusreasonr   r   r   wait_for_changeset   s,   

zDeployer.wait_for_changesetFc                 C   s   | j j|||dS )a!  
        Calls CloudFormation to execute changeset

        :param changeset_id: ID of the changeset
        :param stack_name: Name or ID of the stack
        :param disable_rollback: Disable rollback of all resource changes
        :return: Response from execute-change-set call
        )r0   r   ZDisableRollback)r   Zexecute_change_set)r   r   r   Zdisable_rollbackr   r   r   execute_changeset   s
   
zDeployer.execute_changesetc              
   C   s   t jd t j  |dkr| jd}n|dkr!| jd}ntd|ddd	}z
|j||d
 W d S  t	j
jyR } ztjd|d t
j|dd }~ww )Nz,Waiting for stack create/update to complete
r#   Zstack_create_completer+   Zstack_update_completezInvalid changeset type {0}   x   )rN   ZMaxAttempts)r   rP   z"Execute changeset waiter exceptionr   rQ   )rR   rS   r:   r<   r   rT   rW   r   rU   r   r   rV   r   r   ZDeployFailedError)r   r   r   rX   rY   rL   r   r   r   wait_for_execute   s&   
zDeployer.wait_for_executec	           
   
   C   s*   |  ||||||||}	| |	j| |	S r   )rM   r\   r   )
r   r   r?   r@   rA   rB   rC   rD   rE   resultr   r   r   create_and_wait_for_changeset   s   z&Deployer.create_and_wait_for_changesetN)r
   )F)
__name__
__module____qualname__r   r"   rM   r\   r]   r`   rb   r   r   r   r   r	      s    
$H#
r	   )rR   r9   loggingr   collectionsZ$awscli.customizations.cloudformationr   Z6awscli.customizations.cloudformation.artifact_exporterr   r   r   	getLoggerrc   r   
namedtupler   objectr	   r   r   r   r   <module>   s   
