3
b                 @   s  d dl m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m	Z	m
Z
 yd dljjZW n ek
rv   d dljZY nX ddlmZ ddlmZ ddlT dd	lmZmZmZmZmZmZ dd
lmZmZmZmZm Z  ddl!m"Z" ddl#m#Z#m$Z$ ddl%m%Z% ddl&m&Z& ej'd)kZ(dZ)dde)i Z*dd Z+dd Z,G dd de-Z.G dd de-Z/G dd de-Z0G dd de-Z1G dd  d e-Z2G d!d" d"e-Z3G d#d$ d$e-Z4G d%d& d&e-Z5G d'd( d(e-Z6dS )*    )absolute_importN)datetime)debuginfowarningerror   )S3)Config)*)getTreeFromXmlappendXmlTextNodegetDictFromTreedateS3toPythonencode_to_s3decode_from_s3)getBucketFromHostnamegetHostnameFromBucketdeunicodiseurlencode_stringconvertHeaderTupleListToDict)sign_string_v2)S3UriS3UriS3)ConnMan)
SortedDict   z
2010-11-01z/%(api_ver)s/distributionapi_verc             C   s   t jj| d  d S )N
)sysstdoutwrite)message r#   M/oak/stanford/groups/akundaje/marinovg/programs/s3cmd-master/S3/CloudFront.pyoutput'   s    r%   c             C   s"   d|  j d} td| |f  d S )Nz%s:   z%s %s)ljustr%   )labelr"   r#   r#   r$   pretty_output*   s    r)   c               @   s$   e Zd Zdd Zdd Zdd ZdS )DistributionSummaryc             C   s&   |j dkrtd|j  | j| d S )Nr*   z1Expected <DistributionSummary /> xml, got: <%s />)tag
ValueErrorparse)selftreer#   r#   r$   __init__@   s    
zDistributionSummary.__init__c             C   sT   t || _| jd j dk| jd< d| jkrPt| jd tkrP| jd g| jd< d S )NEnabledtrueCNAME)r   r   lowertypelist)r.   r/   r#   r#   r$   r-   E   s    
zDistributionSummary.parsec             C   s   t d| jd  S )Nzcf://%sId)r   r   )r.   r#   r#   r$   uriK   s    zDistributionSummary.uriN)__name__
__module____qualname__r0   r-   r8   r#   r#   r#   r$   r*   /   s   r*   c               @   s   e Zd Zdd Zdd ZdS )DistributionListc             C   s.   t |}|jdkr td|j | j| d S )Nr<   z.Expected <DistributionList /> xml, got: <%s />)r   r+   r,   r-   )r.   xmlr/   r#   r#   r$   r0   Z   s    
zDistributionList.__init__c             C   sP   t || _| jd j dk| jd< g | _x"|jdD ]}| jjt| q4W d S )NIsTruncatedr2   z.//DistributionSummary)r   r   r4   
dist_summsfindallappendr*   )r.   r/   Z	dist_summr#   r#   r$   r-   `   s
    
zDistributionList.parseN)r9   r:   r;   r0   r-   r#   r#   r#   r$   r<   N   s   r<   c               @   s$   e Zd Zdd Zdd Zdd ZdS )Distributionc             C   s.   t |}|jdkr td|j | j| d S )NrB   z*Expected <Distribution /> xml, got: <%s />)r   r+   r,   r-   )r.   r=   r/   r#   r#   r$   r0   v   s    
zDistribution.__init__c             C   s8   t || _t| jd | jd< t|jdd| jd< d S )NZLastModifiedTimez.//DistributionConfig)r/   DistributionConfig)r   r   r   rC   find)r.   r/   r#   r#   r$   r-   |   s    
zDistribution.parsec             C   s   t d| jd  S )Nzcf://%sr7   )r   r   )r.   r#   r#   r$   r8      s    zDistribution.uriN)r9   r:   r;   r0   r-   r8   r#   r#   r#   r$   rB   i   s   rB   c               @   sF   e Zd ZdZddei ZdddZdd Zd	d
 Zdd Z	dd Z
dS )rC   zq<DistributionConfig><S3Origin><DNSName/></S3Origin><CallerReference/><Enabled>true</Enabled></DistributionConfig>z0http://cloudfront.amazonaws.com/doc/%(api_ver)s/r   Nc             C   sD   |d krt j}|d krt|}|jdkr6td|j | j| d S )NrC   z0Expected <DistributionConfig /> xml, got: <%s />)rC   EMPTY_CONFIGr   r+   r,   r-   )r.   r=   r/   r#   r#   r$   r0      s    
zDistributionConfig.__init__c             C   s   t || _| jd j dk| jd< d| jkr6g | jd< t| jd tkrZ| jd g| jd< dd | jd D | jd< d| jkrd| jd< d| jkrd| jd< |jd	}|rt |d
 }t|d \|d< }|std|d   td| | jd< n
d | jd< d S )Nr1   r2   r3   c             S   s   g | ]}|j  qS r#   )r4   ).0cnamer#   r#   r$   
<listcomp>   s    z,DistributionConfig.parse.<locals>.<listcomp>Comment DefaultRootObjectz
.//Loggingr   Bucketz%Logging to unparsable bucket name: %szs3://%(Bucket)s/%(Prefix)sLogging)	r   r   r4   r5   r6   r@   r   r   r   )r.   r/   Zlogging_nodesZlogging_dictsuccessr#   r#   r$   r-      s&    







zDistributionConfig.parsec             C   s  t jd}tj|jd< tdd|}td| jd d | td| jd | x"| jd D ]}td|j | qVW | jd rtd| jd | td	t| jd	 j | t| jd
 rtd
t| jd
 | | jd rt jd}tdt	| jd j
 | td| jd j | |j| |S )NrC   xmlnsS3OriginrJ   DNSNameCallerReferencer3   rI   r1   rK   rM   rL   Prefix)ETElementrC   rO   attribr   r   r4   strr   bucketobjectrA   )r.   r/   Zs3orgrG   Z
logging_elr#   r#   r$   get_printable_tree   s$    



z%DistributionConfig.get_printable_treec             C   s   t tj| j S )N)r   rT   tostringrZ   )r.   r#   r#   r$   __unicode__   s    zDistributionConfig.__unicode__c             C   s(   t rtj| j ddS tj| j S d S )Nunicode)encoding)PY3rT   r[   rZ   )r.   r#   r#   r$   __str__   s    zDistributionConfig.__str__)NN)r9   r:   r;   rE   cloudfront_api_versionrO   r0   r-   rZ   r\   r`   r#   r#   r#   r$   rC      s   
rC   c               @   s$   e Zd Zdd Zdd Zdd ZdS )Invalidationc             C   s.   t |}|jdkr td|j | j| d S )Nrb   z*Expected <Invalidation /> xml, got: <%s />)r   r+   r,   r-   )r.   r=   r/   r#   r#   r$   r0      s    
zInvalidation.__init__c             C   s   t || _d S )N)r   r   )r.   r/   r#   r#   r$   r-      s    zInvalidation.parsec             C   s
   t | jS )N)rW   r   )r.   r#   r#   r$   r`      s    zInvalidation.__str__N)r9   r:   r;   r0   r-   r`   r#   r#   r#   r$   rb      s   rb   c               @   s$   e Zd Zdd Zdd Zdd ZdS )InvalidationListc             C   s.   t |}|jdkr td|j | j| d S )Nrc   z.Expected <InvalidationList /> xml, got: <%s />)r   r+   r,   r-   )r.   r=   r/   r#   r#   r$   r0     s    
zInvalidationList.__init__c             C   s   t || _d S )N)r   r   )r.   r/   r#   r#   r$   r-     s    zInvalidationList.parsec             C   s
   t | jS )N)rW   r   )r.   r#   r#   r$   r`     s    zInvalidationList.__str__N)r9   r:   r;   r0   r-   r`   r#   r#   r#   r$   rc      s   rc   c               @   sD   e Zd Zddg fddZdd Zdd Zdd	 Zd
d Zdd ZdS )InvalidationBatchNc             C   sL   |r|| _ n,|sd}d|tjtj dtjddf | _ g | _| j| d S )N0z%s.%s.%sz%Y%m%d%H%M%Si  i'  )	referencer   strftimenowrandomrandintpathsadd_objects)r.   rf   distributionrk   r#   r#   r$   r0     s    zInvalidationBatch.__init__c             C   s   | j j| d S )N)rk   extend)r.   rk   r#   r#   r$   rl   *  s    zInvalidationBatch.add_objectsc             C   s   | j S )N)rf   )r.   r#   r#   r$   get_reference-  s    zInvalidationBatch.get_referencec             C   s\   t jd}x>| jD ]4}t|dk s.|d dkr6d| }tdt|| qW td| j| |S )Nrd   r   r   /PathrR   )rT   rU   rk   lenr   r   rf   )r.   r/   pathr#   r#   r$   rZ   0  s    
z$InvalidationBatch.get_printable_treec             C   s   t tj| j S )N)r   rT   r[   rZ   )r.   r#   r#   r$   r\   9  s    zInvalidationBatch.__unicode__c             C   s(   t rtj| j ddS tj| j S d S )Nr]   )r^   )r_   rT   r[   rZ   )r.   r#   r#   r$   r`   <  s    zInvalidationBatch.__str__)	r9   r:   r;   r0   rl   ro   rZ   r\   r`   r#   r#   r#   r$   rd     s   	rd   c               @   s  e Zd Zdddddddddddddddddddd	ddd	ddd
dd	ZdZdZdd Zdd Zg dddfddZg g ddddfddZ	dd Z
dd Zdd Zd0ddZdd Zd d! Zd"d# Zddddefd$d%Zd1d&d'Zd(d) Zd*d+ Zd,d- Zd.d/ ZdS )2
CloudFrontPOSTrJ   )methodresourceDELETEz/%(dist_id)sGETz/%(dist_id)s/configPUTz/%(dist_id)s/invalidationz(/%(dist_id)s/invalidation/%(request_id)s)	
CreateDist
DeleteDistGetListGetDistInfoGetDistConfigSetDistConfig
InvalidateGetInvalListGetInvalInfo   Nc             C   s
   || _ d S )N)config)r.   r   r#   r#   r$   r0   U  s    zCloudFront.__init__c             C   s4   | j d}t|d |d< |d jd r0td|S )Nr}   data	dist_listr>   z3List is truncated. Ask s3cmd author to add support.)send_requestr<   r   NotImplementedError)r.   responser#   r#   r$   r}   \  s
    
zCloudFront.GetListc       
      C   s   t  }d|jd< |j |jd d< t||jd< ||jd< |d krR|j |jd< n
||jd< x0|D ](}|jd j|d	krb|jd j| qbW |rt||jd
< t|}td|  | j	d|d}	t
|	d |	d< |	S )NTr1   rP   rQ   rR   rK   rI   r3   r   rM   z&CreateDistribution(): request_body: %sr{   )bodyr   rm   )rC   r   	host_namerW   
public_urlcountrA   r   r   r   rB   )
r.   r8   
cnames_addcommentloggingdefault_root_objectdist_configrG   request_bodyr   r#   r#   r$   CreateDistributiond  s$    



zCloudFront.CreateDistributionc             C   s  |j dkrtd| td|  | j|}|d }	|d krF||	jd< |d krX||	jd< |d krj||	jd< x0|D ](}
|	jd j|
d	krp|	jd j|
 qpW x6|D ].}
x(|	jd j|
d	kr|	jd j|
 qW qW |d kr|d
krd
|	jd< nt||	jd< | j||	|d d }|S )NcfzExpected CFUri instead of: %szChecking current status of %sr   r1   rI   rK   r3   r   FrM   headersetag)	r5   r,   r   r   r   rA   remover   r   )r.   cfurir   cnames_remover   enabledr   r   r   dcrG   r#   r#   r$   ModifyDistributiony  s.    






zCloudFront.ModifyDistributionc             C   s   |j dkrtd| td|  | j|}|d jd rtd d|d jd< | j||d |d d	 }td
 td xN| j|}|d }|jd dkr|jd dkrtd P td tjd q|W t	dd}|d d	 |d< | j
d|j |d}|S )Nr   zExpected CFUri instead of: %szChecking current status of %sr   r1   z)Distribution is ENABLED. Disabling first.Fr   r   z,Waiting for Distribution to become disabled.z+This may take several minutes, please wait.rm   StatusZDeployedzDistribution is now disabledzStill waiting...
   T)ignore_casezif-matchr|   )dist_idr   )r5   r,   r   r   r   r   r~   timesleepr   r   r   )r.   r   r   dr   r#   r#   r$   DeleteDistribution  s0    



zCloudFront.DeleteDistributionc             C   s<   |j dkrtd| | jd|j d}t|d |d< |S )Nr   zExpected CFUri instead of: %sr~   )r   r   rm   )r5   r,   r   r   rB   )r.   r   r   r#   r#   r$   r~     s
    
zCloudFront.GetDistInfoc             C   s<   |j dkrtd| | jd|j d}t|d |d< |S )Nr   zExpected CFUri instead of: %sr   )r   r   r   )r5   r,   r   r   rC   )r.   r   r   r#   r#   r$   r     s
    
zCloudFront.GetDistConfigc             C   sn   |d kr"t d | j|d d }t d|  t|}t d|  tdd}||d< | jd	|j ||d
}|S )Nz1SetDistConfig(): Etag not set. Fetching it first.r   r   zSetDistConfig(): Etag = %sz!SetDistConfig(): request_body: %sT)r   zif-matchr   )r   r   r   )r   r   rW   r   r   r   )r.   r   r   r   r   r   r   r#   r#   r$   r     s    

zCloudFront.SetDistConfigc             C   s  |d k	rx| s|rxg }d| }xT|D ]L}|j |s:||krf|rH|j| |rp|j|d t|   q$|j| q$W |}| j|}	t|dkryZtj }
tt|
d}|jtdj	|d  W d Q R X t
dt|  t
d|
  W n tk
r   Y nX tdg }x|	D ]}t|j |d}td	|  | jd
|j t|d}|j |d< |d dkr~t|d j}|d |d< td|  |j| qW |S )Nrp   i  wr   z2Request to invalidate %d paths (max 999 supported)z"All the paths are now saved in: %szToo many paths to invalidate)rm   rk   z%InvalidateObjects(): request_body: %sr   )r   r   r   status   r   r7   
request_idz!InvalidateObjects(): response: %s)endswithrA   rr   get_dist_name_for_bucketUtils	mktmpfileopenr   r!   joinr   	ExceptionParameterErrorrd   r   r   r   rW   rb   r   )r.   r8   rk   default_index_fileinvalidate_default_index_on_cf#invalidate_default_index_root_on_cfZ	new_pathsZdefault_index_suffixrs   cfuristmp_filenamefp	responsesr   Z
invalbatchr   
inval_infor#   r#   r$   InvalidateObjects  sF    


"
zCloudFront.InvalidateObjectsc             C   s<   |j dkrtd| | jd|j d}t|d |d< |S )Nr   zExpected CFUri instead of: %sr   )r   r   
inval_list)r5   r,   r   r   rc   )r.   r   r   r#   r#   r$   r     s
    
zCloudFront.GetInvalListc             C   sV   |j dkrtd| |j d kr*td| jd|j |j d}t|d |d< |S )Nr   zExpected CFUri instead of: %szExpected CFUri with Request IDr   )r   r   r   inval_status)r5   r,   r   r   r   rb   )r.   r   r   r#   r#   r$   r     s    
zCloudFront.GetInvalInfoc             C   sb  |d krt dd}| j| }|r(d|d< | j||||}| j }	td|d |d f  |	jj|d |d ||d  |	jj }
i }|
j|d	< |
j	|d
< t
|
j |d< |
j |d< tj|	 td|  |d	 dkr:t|}|r6td|  tt| td| j|  tj| j| | j||||d dS ||d	 dk sV|d	 dkr^t||S )NT)r   z
text/plainzcontent-typezsend_request(): %s %srv   rw   r   r   reasonr   zCloudFront: response: %ri  zRetrying failed request: %szWaiting %d sec...r   )r   retries   i+  )r   
operationscreate_requestget_connectionr   crequestgetresponser   r   r   
getheadersreadr   putCloudFrontErrorr   r]   
_fail_waitr   r   r   )r.   Zop_namer   r   r   r   r   	operationr   connhttp_responser   er#   r#   r$   r     s:    





zCloudFront.send_requestc             C   s   t |d ||d  }|s$tdd}d|krFd|kr@|d |d< |d= d|krbtjdtj |d< t| jjdkr| jj  | jj|d	< | j	|}d
| jj
 d | |d< i }||d< ||d< |d |d< |S )Nrw   )r   r   T)r   datez
x-amz-datez%a, %d %b %Y %H:%M:%S +0000r   zx-amz-security-tokenzAWS :Authorizationr   rv   )cloudfront_resourcer   r   rg   gmtimerr   r   access_tokenrole_refreshsign_request
access_key)r.   r   r   r   r   rw   	signaturer   r#   r#   r$   r   2  s(    


zCloudFront.create_requestc             C   s,   |d }t tt|}td||f  |S )Nz
x-amz-datez"CloudFront.sign_request('%s') = %s)r   r   r   r   )r.   r   string_to_signr   r#   r#   r$   r   O  s    zCloudFront.sign_requestc             C   s   t j| jjdd}|S )NT)ssl)r   getr   cloudfront_host)r.   r   r#   r#   r$   r   U  s    zCloudFront.get_connectionc             C   s   | j | d d S )Nr   r   )_max_retries)r.   r   r#   r#   r$   r   Y  s    zCloudFront._fail_waitc             C   sH  |j dkr|gS |j dkr&td| td|  tjd kr| j }i t_x|d jD ]}d}d|jkrt|jd d d	 }n8d
|jkrVt|jd
 d d	 }|d t	|j
  }nqVtjj|d d krt tj|< tj| j|j  qVW tdtj  ytj|j
  S  tk
rB } zt| td| W Y d d }~X nX d S )Nr   s3z,CloudFront or S3 URI required instead of: %sz_get_dist_name_for_bucket(%r)r   rJ   rP   rQ   r   CustomOriginzdist_list: %sz>Unable to translate S3 URI to CloudFront distribution name: %s)r5   r   r   rt   r   r}   r?   r   r   rr   rX   r   setaddr8   r   )r.   r8   r   r   ZdistListIndexr   r#   r#   r$   r   ]  s2    




z#CloudFront.get_dist_name_for_bucket)N)NNN)r9   r:   r;   r   r   r   r0   r}   r   r   r   r~   r   r   r   r   r   r   r   r   r   r   r   r#   r#   r#   r$   rt   D  s<   
.$
rt   c               @   sn   e Zd ZdZG dd deZe Zedd Zedd Z	edd	 Z
ed
d Zedd Zedd ZdS )Cmdz3
    Class that implements CloudFront commands
    c               @   s4   e Zd Zg Zg ZdZdZdZdZdd Z	dd Z
dS )zCmd.OptionsNc             C   s   dd t | D S )Nc             S   s   g | ]}|j d r|qS )Zcf_)
startswith)rF   optr#   r#   r$   rH     s    z+Cmd.Options.option_list.<locals>.<listcomp>)dir)r.   r#   r#   r$   option_list  s    zCmd.Options.option_listc             C   s   t tj|| d S )N)setattrr   options)r.   optionvaluer#   r#   r$   update_option  s    zCmd.Options.update_option)r9   r:   r;   cf_cnames_addcf_cnames_remove
cf_comment	cf_enable
cf_loggingcf_default_root_objectr   r   r#   r#   r#   r$   Options  s   r   c             C   s8   t t }g }x$| D ]}|jt|}|j| qW |S )N)rt   r
   r   r   rn   )argsr   r   argurisr#   r#   r$   _parse_args  s    

zCmd._parse_argsc             C   s  t t }| s|j }x|d jD ]}d|jkrFtj|jd d }n"d|jkrdd|jd d  }nd}td| td|j  td	|jd	  d
|jkrtddj	|jd
  td|jd  td|jd  t
d q"W n0tj| }x"|D ]}|j|}|d }|jd }d|jkr6tj|jd d }n$d|jkrVd|jd d  }nd}td| td|j  td	|jd	  d
|jkrtddj	|jd
  td|jd  td|jd  td|jd  td|jd  td|jd pd td|d d  qW d S )Nr   rP   rQ   r   z
http://%s/z	<unknown>OriginDistId
DomainNamer3   CNAMEsz, r   r1   rJ   rm   rC   rI   ZDfltRootObjectrK   rM   ZDisabledEtagr   r   )rt   r
   r}   r?   r   r   httpurl_to_s3urir)   r8   r   r%   r   r   r~   )r   r   r   r   originr   r   r   r#   r#   r$   r     sL    








zCmd.infoc             C   sp  t t }g }xX| D ]P}t|}|jdkr6td| |j rJtd| |j sZtd|j| qW |sttdx|D ]}td|  |j	|t
jjt
jjt
jjt
jjd}|d }|jd	 }td
 tdtj|jd d  td|j  td|jd  tddj|jd  td|jd  td|jd  td|jd  td|jd  td|d d  qzW d S )Nr   z@Distribution can only be created from a s3:// URI instead of: %sz4Use s3:// URI with a bucket name only instead of: %sz3CloudFront can only handle lowercase-named buckets.zNo valid bucket names foundzCreating distribution from: %s)r   r   r   r   rm   rC   zDistribution created:r   rP   rQ   r   r   r   z, r3   rI   r   r1   rK   r   r   r   )rt   r
   r   r5   r   rY   is_dns_compatiblerA   r   r   r   r   r   r   r   r   r%   r)   r   r   r8   r   )r   r   Zbucketsr   r8   r   r   r   r#   r#   r$   create  s>    




z
Cmd.createc             C   s\   t t }tj| }xB|D ]:}|j|}|d dkrHtd||d f  td|  qW d S )Nr   i  z(Distribution %s could not be deleted: %sr   zDistribution %s deleted)rt   r
   r   r   r   r   r%   )r   r   r   r   r   r#   r#   r$   delete  s    



z
Cmd.deletec             C   sj  t t }t| dkrtdytj| d }W n tk
rL   tdY nX |j|tjj	tjj
tjjtjjtjjtjjd}|d dkrtd||d	 f  td
|  |j|}|d }|jd }tdtj|jd d  td|j  td|jd  td|jd  tddj|jd  td|jd  td|jd  td|jd  td|d d  d S )Nr   z7Too many parameters. Modify one Distribution at a time.r   z No valid Distribution URI found.)r   r   r   r   r   r   r   i  z)Distribution %s could not be modified: %sr   zDistribution modified: %srm   rC   r   rP   rQ   r   r   r   r   z, r3   rI   r1   rK   r   r   r   )rt   r
   rr   r   r   r   
IndexErrorr   r   r   r   r   r   r   r   r   r%   r~   r   r)   r   r   r8   r   )r   r   r   r   r   r   r#   r#   r$   modify  s:    


z
Cmd.modifyc             C   s8  t t }tj| }g }x|D ]x}|j r:|jt| q|j|}y:x4|d jd D ]"}|jdj	d|j
 |d g qVW W q tk
r   wY qX qW x|D ]}t|}|j|}|d j}	|	d d }
t|
trt|
nd	}td
t| td|	d  td|	d  td| td|	d d  td qW d S )Nr   ZInvalidationSummaryrp   zcf:/r7   r   rd   rq   r   URIr   CreatedZ
CreateTimezNr of pathsZ	ReferencerR   rJ   )rt   r
   r   r   r   rA   rW   r   r   r   r   r   r   r   
isinstancer6   rr   r)   r%   )r   r   r   Zrequestsr   r   ireqr   strk   Znr_of_pathsr#   r#   r$   	invalinfo  s0    



&



zCmd.invalinfoN)r9   r:   r;   __doc__rY   r   r   staticmethodr   r   r   r  r  r
  r#   r#   r#   r$   r     s   	,"
 r   )r   r   )7
__future__r   r   r   ri   r   r   r   r   r   r   xml.etree.ElementTreeetreeElementTreerT   ImportErrorZelementtree.ElementTreer	   r
   
Exceptions	BaseUtilsr   r   r   r   r   r   r   r   r   r   r   r   Cryptor   r   r   r   r   version_infor_   ra   r   r%   r)   rY   r*   r<   rB   rC   rb   rc   rd   rt   r   r#   r#   r#   r$   <module>	   sD    
T1  A