FRTc@sdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddlZ ddlZ ddlZ ddlZ ddlZddlZddlZddlmZmZmZmZddlmZddlmZmZeZddlm Z yddl!m"Z"Wne#k rie$Z"nXdd d d d d ddddddddddddddddddd d!d"d#gZ%e j&d$Z'e j&d%Z(e j&d&Z)d'Z*ddd(Z,dd)Z-dd*Z.e/d+dd,Z0dd-Z1d.e2fd/YZ3d0Z4d1d2d3dd4d5Z5d1d2dd4d6Z6d1dd2dd4d7Z7d8Z8d9Z9d:Z:ej;Z<ed;Z=dd<Z>d=Z?dd>Z@d?ZAdddd@ZBdAeCfdBYZDdCejEjFfdDYZGdEe2fdFYZHdGeCfdHYZIdddde/dIZJdJZKdKZLdLZMeNdMdNdOZOdPZPdQddRZQdQdedSZRdTZSdUZTdVeCfdWYZUdS(Xs7 Some handy utility functions used by several classes. iN(tsixtStringIOturllibt encodebytes(tcontextmanager(tmd5tsha512(tjson(tJSONDecodeErrortacltcorstdefaultObjectAcltlocationtloggingt partNumbertpolicytrequestPaymentttorrentt versioningt versionIdtversionstwebsitetuploadstuploadIdsresponse-content-typesresponse-content-languagesresponse-expiressresponse-cache-controlsresponse-content-dispositionsresponse-content-encodingtdeletet lifecyclettaggingtrestoret storageClasst websiteConfigtcomposes(.)([A-Z][a-z]+)s([a-z])([0-9]+)s([a-z0-9])([A-Z])cCs8t|dkr|S|dtjj|dfSdS(Nii(tlenRtparsetunquote(tnv((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt unquote_vdscCs_|stjj}ni}xe|D]]}|j}||dk r%|dkse|j|jr%t||j||sN(s content-md5s content-typesdate(tbototprovidert get_defaulttlowertNonet startswitht header_prefixtstrtstript date_headertsortedtkeystsplitRtqsa_of_interestR#tsorttjoin(tmethodtpaththeaderstexpiresR-tinteresting_headersR)tlktsorted_header_keystbuftvaltttqsata((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytcanonical_stringksH   !        %/" cCs|stjj}n|j}|j}xU|jD]G}|jtjjj j kro||||tmetadataR-RIt final_headerstk((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt merge_metas  cCs|stjj}n|j}i}x|jD]}|jj|r4tjj ||}t |t ry|j d}Wqt k rqXn|||t|<||=q4q4W|S(Nsutf-8(R,R-R.RIR7R/R1RR R!t isinstancetbytestdecodetUnicodeDecodeErrorR(R>R-RIRNthkeyRD((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytget_aws_metadatas  i c CsaxJtd|D]9}ytjji}tjj|}tjj|}|j|d|}|j} t| t j  rt | dr| j d} n| SWnNtj jk r} | j} | dkr| rdSntk r} nXtjjd|d|krtjtd |tjjd d d qqWtjj d dS(s Retry a url. This is specifically used for accessing the metadata service on an instance. Since this address should never be proxied (for security reasons), we create a ProxyHandler with a NULL dictionary to override any proxy settings in the environment. ittimeoutRTsutf-8iR%s&Caught exception reading instance dataiitBototmax_retry_delayi<s'Unable to read instance data, giving up(trangeRtrequestt ProxyHandlert build_openertRequesttopentreadRRRt string_typesthasattrRTterrort HTTPErrortgetcodet ExceptionR,tlogt exceptionttimetsleeptmintconfigtget( turlt retry_on_404t num_retriesRXtit proxy_handlertopenertreqtrtresulttetcode((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt retry_urls.  #cCst|||S(N(tLazyLoadMetadata(RoRqRX((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt_get_instance_metadatasR{cBsVeZddZdZdZddZdZdZdZ dZ RS( c Cs||_||_i|_g|_||_tjj|jd|jd|j}|r |jd}x|D]}|j dr|dd!}|jj |nT|j d}|dkr||d}|d|!d } n |}} | |j|>> _build_instance_metadata_url('http://169.254.169.254', 'latest', 'meta-data/') http://169.254.169.254/latest/meta-data/ :type url: string :param url: URL to metadata service, e.g. 'http://169.254.169.254' :type version: string :param version: Version of the metadata to get, e.g. 'latest' :type path: string :param path: Path of the metadata to get, e.g. 'meta-data/'. If a trailing slash is required it must be passed in with the path. :return: The full metadata URL s%s/%s/%s((RotversionR=((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt_build_instance_metadata_urlcstlatestshttp://169.254.169.254s meta-data/icCsKy,t|||}t|d|d|SWntjjk rFdSXdS(s Returns the instance metadata as a nested Python dictionary. Simple values (e.g. local_hostname, hostname, etc.) will be stored as string values. Values such as ancestor-ami-ids will be stored in the dict as a list of string values. More complex fields such as public-keys and will be stored as nested dicts. If the timeout is specified, the connection to the specified url will time out after the specified number of seconds. RqRXN(RR|RRdtURLErrorR0(RRoRRXRqt metadata_url((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytget_instance_metadata{s c Csi}t||d}yt|d|d|}|jd}xg|D]_}t|d|dd|d|} | ddkrtj| } n|rI| |||D]3}|jd} | dj|| dj>> cache = LRUCache(3) >>> cache['A'] = 0 >>> cache['B'] = 1 >>> cache['C'] = 2 >>> len(cache) 3 >>> cache['A'] 0 Adding new items to the cache does not increase its size. Instead, the least recently used item is dropped: >>> cache['D'] = 3 >>> len(cache) 3 >>> 'B' in cache False Iterating over the cache returns the keys, starting with the most recently used: >>> for key in cache: ... print key D A C This code is based on the LRUCache class from Genshi which is based on `Myghty `_'s LRUCache from ``myghtyutils.util``, written by Mike Bayer and released under the MIT license (Genshi uses the BSD License). t_ItemcBseZdZdZRS(cCs&d|_|_||_||_dS(N(R0tprevioustnextR)R(RR)R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs cCs t|jS(N(treprR(R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs(RRRR(((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR%s cCs+t|_||_d|_d|_dS(N(tdictt_dicttcapacityR0theadttail(RR+((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs   cCs ||jkS(N(R*(RR)((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt __contains__sccs+|j}x|r&|jV|j}q WdS(N(R,R)R'(Rtcur((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt__iter__s  cCs t|jS(N(RR*(R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt__len__scCs!|j|}|j||jS(N(R*t _update_itemR(RR)titem((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs  cCsq|jj|}|dkrM|j||}||j|<|j|n ||_|j||jdS(N(R*RnR0R%t _insert_itemRR2t _manage_size(RR)RR3((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt __setitem__s    cCs t|jS(N(R(R*(R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRscCsSd|_|j|_|jdk r3||j_n ||_||_|jdS(N(R0R&R,R'R-R5(RR3((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR4s    cCssxlt|j|jkrn|j|jj=|j|jkr[|jj|_d|j_qd|_|_qWdS(N( RR*R+R-R)R,R&R0R'(R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR5s cCs{|j|krdS|j}|j|_|jdk rF||j_n ||_d|_|j|_||j_|_dS(N(R,R&R'R0R-(RR3R&((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR2s     (RRR#tobjectR%RR.R0R1RR6RR4R5R2(((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR$s$       tPasswordcBsGeZdZeZdddZdZdZdZ dZ RS(sp Password object that stores itself as hashed. Hash defaults to SHA512 if available, MD5 otherwise. cCs||_|r||_ndS(sh Load the string from an initial value, this should be the raw hashed password. N(R3thashfunc(RR3R9((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs cCs=t|ts!|jd}n|j|j|_dS(Nsutf-8(RRRStencodeR9t hexdigestR3(RR((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytsetscCs t|jS(N(R3(R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR scCsY|dkrtSt|ts1|jd}nt|j|jt|jkS(Nsutf-8(R0RRRRSR:R3R9R;(Rtother((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt__eq__s  cCs|jrt|jSdSdS(Ni(R3R(R((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR1s  N( RRR#t_hashfnR9R0RR<RR>R1(((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR8s   c Cs|p g}|r4dtjjdd|f}n|sUtjjddd}n|r}ytjjddd}tjjj}||d<||d <||d 'camel_case' pythonize_name('already_pythonized') -> 'already_pythonized' pythonize_name('HTTPRequest') -> 'http_request' pythonize_name('HTTPStatus200Ok') -> 'http_status_200_ok' pythonize_name('UPPER') -> 'upper' pythonize_name('') -> '' s\1_\2(t_first_cap_regextsubt_number_cap_regext_end_cap_regexR/(Rts1ts2((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytpythonize_nameks s text/plaint:cCs7tjjj}x|D]\}}t||}|jdd\}} |dkrvtjjj|d| } n5tjjj || } | j |tj j | | j ddd||j| qW|j} |r3t} tjdd d | } z| j| Wd | jX| j} n| S( sDescription: :param content: A list of tuples of name-content pairs. This is used instead of a dict to ensure that scripts run in order :type list of tuples: :param compress: Use gzip to compress the scripts, defaults to no compression :type bool: :param deftype: The type that should be assumed if nothing else can be figured out :type str: :param delimiter: mime delimiter :type str: :return: Final mime multipart :rtype: str: R}iRIt_subtypesContent-Dispositiont attachmenttfilenametmodetwbtfileobjN(RRRRSRTtguess_mime_typeR8RIRVRWRXRYRZR[t add_headerRUR`RtgziptGzipFileRtcloseR(tcontenttcompresstdeftypet delimitertwrapperRtcont definite_typetmaintypetsubtypetmime_contrcontentRCtgz((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytwrite_mime_multipart}s(     cCspidd6dd6dd6dd6d d 6d d 6}|}x3|jD]%\}}|j|rC|}PqCqCW|S( sDescription: Guess the mime type of a block of text :param content: content we're finding the type of :type str: :param deftype: Default mime type :type str: :rtype: : :return: stext/x-include-urls#includestext/x-shellscripts#!stext/cloud-configs #cloud-configstext/upstart-jobs #upstart-jobstext/part-handlers #part-handlerstext/cloud-boothooks#cloud-boothook(RR1(RRtstarts_with_mappingstrtypet possible_typetmimetype((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyR~s  i cCst|||dtS(s Compute MD5 hash on passed file and return results in a tuple of values. :type fp: file :param fp: File pointer to the file to MD5 hash. The file pointer will be reset to its current location before the method returns. :type buf_size: integer :param buf_size: Number of bytes per read request. :type size: int :param size: (optional) The Maximum number of bytes to read from the file pointer (fp). This is useful when uploading a file in multiple parts where the file is being split inplace into different parts. Less bytes may be available. :rtype: tuple :return: A tuple containing the hex digest version of the MD5 hash as the first element, the base64 encoded version of the plain digest as the second element and the data size as the third element. thash_algorithm(t compute_hashR(tfptbuf_sizetsize((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt compute_md5sc CsP|}|j}|r9||kr9|j|}n|j|}x|rt|tsr|jd}n|j||r|t|8}|dkrPqn|r||kr|j|}qK|j|}qKW|j}t|j j d}|ddkr&|dd!}n|j|} |j |||| fS(Nsutf-8iis ( ttellRaRRRSR:tupdateRR;RtdigestRTR( RRRRthash_objtsposRt hex_digestt base64_digestt data_size((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs.       cCs/g|D]$}|j|jkr|^qS(s Takes a specific header name and a dict of headers {"name": "value"}. Returns a list of matching header names, case-insensitive. (R/(RR>th((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytfind_matching_headersscs,t|}djfd|DS(s Takes a specific header name and a dict of headers {"name": "value"}. Returns a string of all header values, comma-separated, that match the input header name, case-insensitive. Rc3s/|]%}|dk rt|VqdS(N(R0R3(t.0R(R>(s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pys s(RR;(RR>tmatching_headers((R>s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pytmerge_headers_by_namest RequestHookcBseZdZedZRS(s This can be extended and supplied to the connection object to gain access to request and response object after the request completes. One use for this would be to implement some specific request logging. cCsdS(N((RR\tresponseRd((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pythandle_request_datas(RRR#RR(((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyRs(VR#RRjtlogging.handlersR R,t boto.providerRRRRtretemail.mime.multipartRtemail.mime.basetemail.mime.textt email.utilstemail.encodersRt threadingRt boto.compatRRRRt contextlibRthashlibRRR?Rtboto.compat.jsonRt ImportErrorRR9tcompileRpRrRsR#R0RHRQRWRRzR|R)R{RRRRRRRtLockRRRRRRRR7Rthandlerst SMTPHandlerR R$R8RiRlRoRvRRR~RRRRR(((s7/opt/freeware/lib/python2.7/site-packages/boto/utils.pyt(s                  "         9  # v       #07w& 7 -