U
    Ӈg9                     @   s  d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZmZmZ d dlmZmZ e eZejZejZejZdZd	d
gZddgZdgZd	ZdZdZddddddddgZdZdgZ dd Z!dd Z"d%ddZ#G dd  d Z$d!d" Z%efd#d$Z&dS )&    N)MIMEBase)MIMEMultipart)MIMENonMultipart)MIMEText)featureshandlersutil)UrlErrorread_file_or_urlzContent-Typez
text/plainztext/x-not-multipartztext/x-include-urlztext/x-include-once-urlztext/cloud-config-archiveztext/cloud-configzapplication/octet-streamzapplication/gzipzapplication/gzip-compressedzapplication/gzippedzapplication/x-compresszapplication/x-compressedzapplication/x-gunzipzapplication/x-gzipzapplication/x-gzip-compressedzNumber-Attachmentsc                 C   s   | |= || |< d S N )msgkeyvaluer   r   5/usr/lib/python3/dist-packages/cloudinit/user_data.py_replace_header;   s    r   c                 C   s   | d= | j ddt|d d S )NzContent-DispositionZ
attachment)filename)
add_headerstr)r   r   r   r   r   _set_filename@   s    r   c                 C   s    t jrt| |n
t|  d S r   )r   ZERROR_ON_USER_DATA_FAILURERuntimeErrorLOGZwarning)error_messageZsource_exceptionr   r   r   _handle_errorE   s    r   c                   @   s^   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dddZdd ZdS )UserDataProcessorc                 C   s   || _ t|| _d S r   )pathsr   Zfetch_ssl_detailsssl_details)selfr   r   r   r   __init__M   s    zUserDataProcessor.__init__c                 C   s@   t  }t|tr,|D ]}| t|| qn| t|| |S r   )r   
isinstancelist_process_msgconvert_string)r   ZblobZaccumulating_msgbr   r   r   processQ   s    
zUserDataProcessor.processc                 C   s  dd }|  D ]}t|r qd }| }t|}d}|tkrztj|dd}d }d}W nH tjk
r }	 z(d|t	||	}
t
|
|	 W Y qW 5 d }	~	X Y nX |st}|tdg kr||}|d kr|}|r@|dd	\}}t||}|| | rt||  d
D ]$}||krt||t||  q|}||krVt|t| |tkrn| || q|tkr| || qt|t| | || qd S )Nc                 S   s
   t | S r   )r   type_from_starts_with)payloadr   r   r   
find_ctype[   s    z2UserDataProcessor._process_msg.<locals>.find_ctypeF)quietTz<Failed decompressing payload from {} of length {} due to: {}ztext/x-shellscript/   )Launch-Index)walkis_skippableget_content_typer   Zfully_decoded_payloadDECOMP_TYPESdecomp_gzipZDecompressionErrorformatlenr   
UNDEF_TYPETYPE_NEEDEDsplitr   set_payloadget_filenamer   r   r   CONTENT_TYPEINCLUDE_TYPES_do_includeARCHIVE_TYPES_explode_archive_attach_part)r   Zbase_msg
append_msgr'   partZctypeZ
ctype_origr&   Zwas_compresseder   maintypesubtypeZn_parthr   r   r   r!   Z   s`    
  







zUserDataProcessor._process_msgc              	   C   s   | dd }d }| tkrVz$t|jdd}|r>| d}W n tk
rT   Y nX |d k	rb|}|d krn|}|d k	rz|dtt	| W n t
tfk
r   Y nX d S )Nr+   Tdecodelaunch-index)getr.   EXAMINE_FOR_LAUNCH_INDEXr   	load_yamlZget_payload	Exceptionr   r   int
ValueError	TypeError)r   r   Z
header_idxZpayload_idxr&   r   r   r   _attach_launch_index   s$    z&UserDataProcessor._attach_launch_indexc                 C   s&   t |dd}tj| jdd|S )NZmd5@   dataZurlcache)r   Z	hash_blobospathjoinr   Zget_ipath_cur)r   entryZentry_fnr   r   r   _get_include_once_filename   s    
  z,UserDataProcessor._get_include_once_filenamec                 C   s$   |  st|t|  | | d S r   )r7   r   PART_FN_TPLrN   )r   r   Zattached_idr   r   r   _process_before_attach   s    z(UserDataProcessor._process_before_attachc                 C   s  d}|  D ]}| }|dr>|tdd   }d}n"|dr`|tdd   }d}|drlq| }|szqd }d }|r| |}|rtj	|rt
|}nzZt|dd| jd}|r| rt
j||jd	d
 | r|j}nd||j}	t|	 W n tk
rT }
 z.t|
}||kr:|d|7 }t||
 W 5 d }
~
X Y n: tk
r } zd||}	t|	| W 5 d }~X Y nX |d k	rt|}| || qd S )NFz#include-onceTz#include#   
   )ZtimeoutZretriesr   i  )modez6Fetching from {} resulted in a invalid http code of {}z for url: {0}zFetching from {} resulted in {})
splitlineslower
startswithr2   lstripstriprU   rQ   rR   isfiler   Zload_text_filer
   r   okZ
write_filecontentsr1   coder   r	   r   IOErrorr"   r!   )r   contentr>   Zinclude_once_onlineZlc_lineZinclude_urlZinclude_once_fnZrespr   ZurlemessageZioeZnew_msgr   r   r   r:      sn    



   
 zUserDataProcessor._do_includec                 C   sL  t j|g ttfd}|D ],}t|tr0d|i}t|ts<q|dd}|d}|stt}t|t	rht
}t||}|dd\}}	|dkrt|t	r| }t||	d}
nt||	}
|
| d	|krt|
|d	  d
|kr|
dt|d
  t| D ]:}| dd	dd
dt t fkr(q|
|||  q| ||
 qd S )N)defaultZallowedrf    typer)   r*   text)Z_subtyper   rF   r+   zcontent-disposition)r   rI   r    setr   r   dictrG   ARCHIVE_UNDEF_TYPEbytesARCHIVE_UNDEF_BINARY_TYPEr   r%   r5   rE   r   r   r6   r   r   keysr]   ATTACHMENT_FIELDr8   r=   )r   archiver>   entriesZentrf   Zmtyperi   rA   rB   r   headerr   r   r   r<     sJ    







	z"UserDataProcessor._explode_archiveNc              	   C   sl   t |krd|t < |dk	r(t|t t| d}zt|t }W n( ttfk
rf   t|t t| Y nX |S )z
        Return the number of attachments to this MIMEMultipart by looking
        at its 'Number-Attachments' header.
        0Nr   )rs   r   r   rK   rG   rL   rM   )r   	outer_msgZ	new_countZfetched_countr   r   r   _multi_part_countF  s    z#UserDataProcessor._multi_part_countc                 C   s8   |  |}| ||d  || |  ||d  dS )z
        Attach a message to an outer message. outermsg must be a MIMEMultipart.
        Modifies a header in the outer message to keep track of number of
        attachments.
        r*   N)ry   rW   Zattach)r   rx   r?   Z
part_countr   r   r   r=   X  s    

zUserDataProcessor._attach_part)N)__name__
__module____qualname__r   r$   r!   rN   rU   rW   r:   r<   ry   r=   r   r   r   r   r   L   s   	PE4
r   c                 C   s    |   p
d}| dkrdS dS )Nrj   Z	multipartTF)Zget_content_maintyper]   )r?   Zpart_maintyper   r   r   r-   d  s    r-   c                 C   sl   | sd} dd }t | tr&| d}n| }tj|dd}d|dd	  kr^t|d}n
|||}|S )
zJconvert a string (more likely bytes) or a message into
    a mime message.    c                 S   s(   | dd\}}t||}||  |S )Nr)   r*   )r5   r   r6   )rP   content_typerA   rB   r   r   r   r   create_binmsgs  s    

z%convert_string.<locals>.create_binmsgzutf-8FrD   s   mime-version:r   i   )r   r   encoder   r0   r]   Zmessage_from_stringrE   )raw_datar~   r   Zbdatar   r   r   r   r"   m  s    

r"   )N)'ZloggingrQ   Zemail.mime.baser   Zemail.mime.multipartr   Zemail.mime.nonmultipartr   Zemail.mime.textr   Z	cloudinitr   r   r   Zcloudinit.url_helperr	   r
   Z	getLoggerrz   r   ZNOT_MULTIPART_TYPErV   Z
OCTET_TYPEr8   r4   r9   r;   r3   ro   rq   r/   rs   rH   r   r   r   r   r-   r"   r   r   r   r   <module>   sJ   

  	