o
    f9                     @   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g d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-stream)z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-Disposition
attachment)filename)
add_headerstr)r   r   r   r   r   _set_filename@   s   r   c                 C   s   t jrt| |t|  d S r   )r   ERROR_ON_USER_DATA_FAILURERuntimeErrorLOGwarning)error_message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   fetch_ssl_detailsssl_details)selfr   r   r   r   __init__M   s   zUserDataProcessor.__init__c                 C   sB   t  }t|tr|D ]
}| t|| q
|S | t|| |S r   )r   
isinstancelist_process_msgconvert_string)r"   blobaccumulating_msgbr   r   r   processQ   s   
zUserDataProcessor.processc                 C   s  dd }|  D ]}t|rqd }| }t|}d}|tv rOztj|dd}d }d}W n! tjyN }	 zd|t	||	}
t
|
|	 W Y d }	~	qd }	~	ww |sSt}|tdg v r^||}|d u rd|}|r|dd	\}}t||}|| | rt||  d
D ]}||v rt||t||  q|}||krt|t| |tv r| || q|tv 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   fully_decoded_payloadDECOMP_TYPESdecomp_gzip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"   base_msg
append_msgr.   partctype
ctype_origr-   was_compresseder   maintypesubtypen_parthr   r   r   r&   Z   sf   




zUserDataProcessor._process_msgc              	   C   s   | dd }d }| tv r*zt|jdd}|r| d}W n	 ty)   Y nw |d ur0|}|d u r6|}|d urTz|dtt	| W d S  t
tfyS   Y d S w d S )Nr2   Tdecodelaunch-index)getr5   EXAMINE_FOR_LAUNCH_INDEXr   	load_yamlget_payload	Exceptionr   r   int
ValueError	TypeError)r"   r   
header_idx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 )Nmd5@   dataurlcache)r   	hash_blobospathjoinr   get_ipath_cur)r"   entryentry_fnr   r   r   _get_include_once_filename   s   z,UserDataProcessor._get_include_once_filenamec                 C   s$   |  st|t|  | | d S r   )r@   r   PART_FN_TPLr_   )r"   r   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r5q| }|s<qd }d }|rG| |}|rUtj	|rUt
|}npz-t|dd| jd}|rn| rnt
j||jd	d
 | rv|j}nd||j}	t|	 W nB ty }
 zt|
}||vr|d|7 }t||
 W Y d }
~
n!d }
~
w ty } zd||}	t|	| W Y d }~nd }~ww |d urt|}| || qd S )NFz#include-onceTz#include#   
   )timeoutretriesr!   i  )modez6Fetching from {} resulted in a invalid http code of {}z for url: {0}zFetching from {} resulted in {})
splitlineslower
startswithr;   lstripstriprk   re   rf   isfiler   load_text_filer
   r!   ok
write_filecontentsr:   coder   r	   r   IOErrorr'   r&   )r"   contentrH   include_once_onlinelc_lineinclude_urlinclude_once_fnrespr   urlemessageioenew_msgr   r   r   rC      st   



zUserDataProcessor._do_includec                 C   sH  t j|g ttfd}|D ]}t|trd|i}t|tsq|dd}|d}|s9t}t|t	r3t
}t||}|dd\}}	|dkrUt|t	rN| }t||	d}
n
t||	}
|
| d	|v rjt|
|d	  d
|v rx|
dt|d
  t| D ]}| dd	dd
dt t fv rq~|
|||  q~| ||
 qd S )N)defaultallowedr    typer0   r1   text)_subtyper   rT   r2   zcontent-disposition)r   rW   r%   setr$   r   dictrU   ARCHIVE_UNDEF_TYPEbytesARCHIVE_UNDEF_BINARY_TYPEr   r,   r>   rS   r   r   r?   r   r   keysrv   ATTACHMENT_FIELDrA   rF   )r"   archiverH   entriesentr   mtyper   rN   rO   r   headerr   r   r   rE     sL   






	z"UserDataProcessor._explode_archiveNc              	   C   sj   t |vrd|t < |durt|t t| d}z
t|t }W |S  ttfy4   t|t t| Y |S w )z
        Return the number of attachments to this MIMEMultipart by looking
        at its 'Number-Attachments' header.
        0Nr   )r   r   r   rZ   rU   r[   r\   )r"   	outer_msg	new_count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.
        r1   N)r   rn   attach)r"   r   rI   
part_countr   r   r   rF   X  s   

zUserDataProcessor._attach_partr   )__name__
__module____qualname__r#   r+   r&   r_   rk   rn   rC   rE   r   rF   r   r   r   r   r   L   s    	PE
4r   c                 C   s    |   pd}| dkrdS dS )Nr   	multipartTF)get_content_maintyperv   )rI   part_maintyper   r   r   r4   d  s   r4   c                 C   sn   | sd} dd }t | tr| d}n| }tj|dd}d|dd	  v r0t|d}|S |||}|S )
zJconvert a string (more likely bytes) or a message into
    a mime message.    c                 S   s(   | dd\}}t||}||  |S )Nr0   r1   )r>   r   r?   )rb   content_typerN   rO   r   r   r   r   create_binmsgs  s   

z%convert_string.<locals>.create_binmsgzutf-8FrR   s   mime-version:r   i   )r$   r   encoder   r8   rv   message_from_stringrS   )raw_datar   r   bdatar   r   r   r   r'   m  s   

r'   r   )'loggingre   email.mime.baser   email.mime.multipartr   email.mime.nonmultipartr   email.mime.textr   	cloudinitr   r   r   cloudinit.url_helperr	   r
   	getLoggerr   r   NOT_MULTIPART_TYPErl   
OCTET_TYPErA   r=   rB   rD   r<   r   r   r7   r   rV   r   r   r   r   r4   r'   r   r   r   r   <module>   s<   


  	