a '¡DgЊã@s„ddlZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z ddl m Z ddlmZddlmZddlmZddlmZddlmZmZmZmZmZmZmZdd lmZm Z m!Z!m"Z"ddl#Z#dd l#m$Z$dd l%m&Z&m'Z'm(Z(e )e*¡Z+d Z,d d„Z-dd„Z.e/dœdd„Z0dBe1e2e3ddœdd„Z4e1ddœdd„Z5eddœdd„Z6Gd d!„d!ƒZ7Gd"d„de7ƒZ8Gd#d„de7ƒZ9Gd$d%„d%ƒZ:Gd&d'„d'e;ƒZe:d.œd/d0„Z?dDed1efe1e/ej@ee2ed2œd3d4„ZAdEed1efee1e2e/ed7œd8d9„ZBe2d:ƒde+jCdddddd-d+d5f e2ee2eeeee2eeeeee2ge2fe1e>e2d;œ dd?„d?ƒZEdFd@dA„ZFdS)GéN)ÚThreadPoolExecutorÚ TimeoutErrorÚ as_completed)Ú parsedate)Úpartial)Ú NOT_FOUND)Úcount)Úcreate_default_context)ÚAnyÚCallableÚIteratorÚListÚOptionalÚTupleÚUnion)ÚquoteÚurlparseÚurlsplitÚ urlunparse)Ú exceptions)Ú performanceÚutilÚversionÚREDACTEDcCs<tt|dd�ƒ}|ds4|dr4|d|d<d|d<t|ƒS)NÚhttp)ÚschemeééÚ)Úlistrr)ÚurlZ parsed_url©r!ú8/usr/lib/python3.9/site-packages/cloudinit/url_helper.pyÚ _cleanurl&s  r#cGs$dd„}|}|D]}|||ƒ}q|S)NcSsNtt|ƒƒ}|d}|r*| d¡s*|d7}|tt|ƒdd�7}||d<t|ƒS)Nrú/z/:)Úsafe)rrÚendswithrÚstrr)r Úadd_onZ url_parsedÚpathr!r!r"Úcombine_single1s z#combine_url..combine_singler!)ÚbaseZadd_onsr*r r(r!r!r"Ú combine_url0s   r,©Úreturnc CsVtjdtjdtjdtjdtdi}| t|ƒ¡}|sRt|t ƒrD|j }nt   d¡d}|S)z4helper for read_ftps to map return codes to a numberé,é�éôiXi¼z9Unexpected exception type while connecting to ftp server.i�ÿÿÿ) ÚftplibZ error_replyZ error_tempÚ error_permZ error_protoÚEOFErrorÚgetÚtypeÚ isinstanceÚOSErrorÚerrnoÚLOGÚwarning)ÚexcZftp_error_codesÚcoder!r!r"Ú"ftp_get_return_code_from_exception@sû ÿr>ç@Ú FtpResponse)r ÚtimeoutÚkwargsr.c Ksrt|ƒ}|jstdtd|d�‚t ¡��4}|jp2d}|jpZloginÚpasswordZprot_pr3r;r)Z retrbinaryÚwriter@ÚgetvalueÚcloseZFTP) r rArBZ url_partsÚbufferrJrLZftp_tlsÚer=Úftpr!r!r"Ú read_ftpsWsöÿ    ÿýý ÿÿùø þ  ÿø ÷ ÿ òÿÿùø  ÿ ÿý  þ òÿÿùø  ÿ r\Ú FileResponse)r)r.c Ksž| d¡rt d|¡zt |¡}t||ƒWStyb}zt|td|d�|‚WYd}~n@d}~0t y˜}z t||j d|d�|‚WYd}~n d}~00dS)zmread a binary file and return a FileResponse matches function signature with read_ftps and read_url Údataz'Unable to post data to file resource %sNrC) r5r:r;rZload_binary_filer]ÚFileNotFoundErrorrPrÚIOErrorr9)r)rBÚcontentsrZr!r!r"Ú _read_fileÙs    &rb)r]Ú UrlResponser@c KsÈ| ¡}z t|ƒ}Wn2tyF}zt||d�|‚WYd}~n d}~00|j}|dksf|rxd|dkrxt|jfi|¤ŽS|dvr�t|fi|¤ŽS|dvr¨t|fi|¤ŽSt   d|¡t|fi|¤ŽSdS) a0Wrapper function around readurl to allow passing a file path as url. When url is not a local file path, passthrough any kwargs to readurl. In the case of parameter passthrough to readurl, default values for some parameters. See: call-signature of readurl in this module for param docs. )rDr NÚfiler$r)r[rG)rÚhttpszAttempting unknown protocol %s) ÚlstriprÚ ValueErrorrPrrbr)r\Úreadurlr:r;)r rBÚparsedrZrr!r!r"Úread_file_or_urlés  $ rjc@s&eZdZd dd„Zdd„Zdd„ZdS) ÚStringResponseéÈcCs||_i|_||_||_dS©N)r=rErar ©Úselfrar r=r!r!r"Ú__init__szStringResponse.__init__cOs |jdkS)Nrl©r=©roÚargsrBr!r!r"ÚokszStringResponse.okcCs |j d¡S)Nzutf-8)raÚdecode©ror!r!r"Ú__str__szStringResponse.__str__N)rl)Ú__name__Ú __module__Ú __qualname__rprtrwr!r!r!r"rks rkcs&eZdZdeedœ‡fdd„ Z‡ZS)r]rl©rar cstƒj|||d�dS)Nrq©Úsuperrprn©Ú __class__r!r"rpszFileResponse.__init__)rl©rxryrzÚbytesr'rpÚ __classcell__r!r!r~r"r]scs$eZdZeedœ‡fdd„ Z‡ZS)r@r{cstƒ ||¡dSrmr|)rorar r~r!r"rpszFtpResponse.__init__r€r!r!r~r"r@sc@s’eZdZejdœdd„Zeedœdd„ƒZee dœdd„ƒZ de dœd d „Z ed d „ƒZ eedœdd„ƒZdd„Zdeee eedœdd„ZdS)rc)ÚresponsecCs ||_dSrm)Ú _response)rorƒr!r!r"rp szUrlResponse.__init__r-cCs|jjdurdS|jjS)Nó)r„Úcontentrvr!r!r"ra#s zUrlResponse.contentscCs|jjSrm)r„r rvr!r!r"r )szUrlResponse.urlFcCs2d}|r d}d|jkr"|kr*nndSdSdS)Nr/r0rlTFrq)roZ redirects_okÚupperr!r!r"rt-s zUrlResponse.okcCs|jjSrm)r„rErvr!r!r"rE6szUrlResponse.headerscCs|jjSrm)r„Ú status_codervr!r!r"r=:szUrlResponse.codecCs|jjSrm)r„Útextrvr!r!r"rw>szUrlResponse.__str__r)Ú chunk_sizeÚdecode_unicoder.ccs|j ||¡EdHdS)atIterates over the response data. When stream=True is set on the request, this avoids reading the content at once into memory for large responses. :param chunk_size: Number of bytes it should read into memory. :param decode_unicode: If True, content will be decoded using the best available encoding based on the response. N)r„Ú iter_content)rorŠr‹r!r!r"rŒAs zUrlResponse.iter_contentN)F)rF)rxryrzÚrequestsZResponserpÚpropertyr�rar'r ÚboolrtrEÚintr=rwrr rŒr!r!r!r"rcs   ÿþrcc@seZdZddd„ZdS)rPNcCs<t |t|ƒ¡||_||_||_|jdur2i|_||_dSrm)r`rpr'rDr=rEr )rorDr=rEr r!r!r"rpQs zUrlError.__init__)NNN)rxryrzrpr!r!r!r"rPPsrPcCs‚i}t|ƒj}|dkr~|r~d|vr8|dr8|d|d<nd|d<d|vrfd|vrf|d|dg|d<nd|vr~t|dƒ|d<|S)NreZca_certsZverifyTZ cert_fileZkey_fileZcert)rrr')r Ú ssl_detailsZssl_argsrr!r!r"Ú _get_ssl_args[s  þ r’rTFr)Ústreamr.c st|ƒ}||dœ}| t||ƒ¡| |d<|s:|r6dnd}||d<|durpt|tƒr^||d<ntt|ƒdƒ|d<|dur|g}d }|r–tt|ƒd d ƒ}d t  ¡}|dur´|  ¡}ni}|rÄ||d <|durÐd }| duràt   ¡} t ƒD�] }|rø||ƒ}d |v�r ||d <||d<i}| ¡D]p\}‰|d k�r4�q|dk�r„|�r„‡fdd„|Dƒ}|�rŒt  ˆ¡||<|D]}t|||<�qnnˆ||<�qzl|�r´t d|| �rªdn|||¡| jfi|¤Ž}| �rÒ| ¡t d||jt|jƒ|d ¡t|ƒWStj�y2}zt||d�|‚WYd}~qæd}~0tj�y}zºt|tjƒ�r†t|dƒ�r†t|jdƒ�r†t||jj|jj |d�}n t||d�}| �r®| |  ¡|ƒ�s®||‚| �p¾|d |k}|�sÌ||‚|dk�rò|�rèt d|¡t! "|¡WYd}~qæd}~00qæt#dƒ‚dS)a�Wrapper around requests.Session to read the url and retry if necessary :param url: Mandatory url to request. :param data: Optional form data to post the URL. Will set request_method to 'POST' if present. :param timeout: Timeout in seconds to wait for a response. May be a tuple if specifying (connection timeout, read timeout). :param retries: Number of times to retry on exception if exception_cb is None or exception_cb returns True for the exception caught. Default is to fail with 0 retries on exception. :param sec_between: Default 1: amount of seconds passed to time.sleep between retries. None or -1 means don't sleep. :param headers: Optional dict of headers to send during request :param headers_cb: Optional callable returning a dict of values to send as headers during request :param headers_redact: Optional list of header names to redact from the log :param ssl_details: Optional dict providing key_file, ca_certs, and cert_file keys for use on in ssl connections. :param check_status: Optional boolean set True to raise when HTTPError occurs. Default: True. :param allow_redirects: Optional boolean passed straight to Session.request as 'allow_redirects'. Default: True. :param exception_cb: Optional callable which accepts the params msg and exception and returns a boolean True if retries are permitted. :param session: Optional exiting requests.Session instance to reuse. :param infinite: Bool, set True to retry indefinitely. Default: False. :param log_req_resp: Set False to turn off verbose debug messages. :param request_method: String passed as 'method' to Session.request. Typically GET, or POST. Default: POST if data is provided, GET otherwise. :param stream: if False, the response content will be immediately downloaded. )r r“Úallow_redirectsZPOSTZGETÚmethodNrArrz Cloud-Init/%sr^éÿÿÿÿz User-AgentrEcsg|]}ˆ |¡r|‘qSr!)r5)Ú.0Úk©Úvr!r"Ú Ór…zreadurl..z'[%s/%s] open '%s' with %s configurationÚinfinitez(Read from %s (%s, %sb) after %s attempts©r rƒrˆ©r=rEr ú1Please wait %s seconds while we wait to try againz"This path should be unreachable...)$r#Úupdater’r7ÚtupleÚmaxÚfloatr�rZversion_stringÚcopyr�ZSessionrÚitemsÚdeepcopyrr:rTZrequestZraise_for_statusrˆÚlenr†rcrZSSLErrorrPZRequestExceptionZ HTTPErrorÚhasattrrƒrEÚtimeÚsleepÚ RuntimeError)r r^rAZretriesZ sec_betweenrEÚ headers_cbÚheaders_redactr‘Ú check_statusr”Ú exception_cbZsessionrœZ log_req_respÚrequest_methodr“Zreq_argsZ manual_triesZ user_agentÚiZfiltered_req_argsr˜Zmatched_headersÚkeyÚrrZZ url_errorZ will_retryr!r™r"rhmsÀ4þ          ûû " ÿþÿýü  þ"rh.)ÚfuncÚaddrrAÚeventÚdelayr.cCs|r|j|d�rdS|||ƒS)z Execute func with optional delay©rAN©Úwait©r´rµrAr¶r·r!r!r"Ú_run_func_with_delays r¼ç333333Ã?é )r´Ú addressesÚ stagger_delayrAr.c s8d}d}d}g}t ¡‰tt|ƒd�‰zúz´‡‡‡‡‡fdd„t|ƒDƒ}t|ˆd�D]X} || }|  ¡} | r|| }| |¡qT|  ¡}|rTˆ  ¡||fWWˆj dd�SqT|rÆt   d||¡|‚nt   d |¡td ƒ‚Wn4t�yt   d d  |¡d  tt|ƒ¡¡Yn0Wˆj dd�nˆj dd�0||fS) aexecute multiple callbacks in parallel Run blocking func against two different addresses staggered with a delay. The first call to return successfully is returned from this function and remaining unfinished calls are cancelled if they have not yet started N)Ú max_workersc s,i|]$\}}ˆjtˆ|ˆˆ|ˆd�|“qS)r»)Zsubmitr¼)r—r±rµ©Úexecutorr´Zis_donerÀrAr!r"Ú Is øúzdual_stack..r¸Fr¹z.default_sleep_timer©rÒÚ start_timerÔcSs0|tdƒdfvrdS|dkp.t ¡|||kS)z4Check if time is up based on start time and max waitrÑNFr)r£r©Ú monotonicrÜr!r!r"Útimeup¾s ÿzwait_for_url..timeupcSsf|js*d|j}tt|ƒ|j|j|d�}n4| ¡sVd|j}tt|ƒ|j|j|d�}nd}d}||fS)z?Map requests response code/contents to internal "UrlError" typezempty response [%s]ržzbad status code [%s]rN)rar=rPrgrErt)rƒr ÚreasonÚurl_excr!r!r"Úhandle_url_responseÆs& ü üz)wait_for_url..handle_url_responsec sìd}d}z,||ƒ\}}ˆ||ƒ\}}|s2||fWSWn^tyd} zd| }| }WYd} ~ n8d} ~ 0ty’} zd| }| }WYd} ~ n d} ~ 00tt ¡|ƒ} ˆr°dˆnd} d|pÄt|ddƒ| | |f} || ƒ|rè|| |d �dS) z:Execute request, handle response, optionally log exceptionrNzrequest error [%s]zunexpected error [%s]z%ssZ unlimitedzCalling '%s' failed [%s/%s]: %sr )ÚmsgrÉ)rPÚ Exceptionr�r©rÞÚgetattr) Z url_reader_cbÚurlsrÝÚexc_cbÚlog_cbràr rƒrárZZ time_takenZ max_wait_strZ status_msg)rârÒr!r"Úread_url_handle_exceptionsÝs0 üz0wait_for_url..read_url_handle_exceptionscs$t|ˆdurinˆ|ƒˆ|dˆd�S)NF)rEr­rAr®r°)rh)r rA)r¬r­r°r!r"Ú read_url_cbýsúz!wait_for_url..read_url_cbcs„‡‡fdd„}ˆD]l}t ¡}ˆdkrbˆˆ|ƒr6dSˆdurbˆrb|ˆ|ˆkrbt|ˆ|ƒ‰ˆ|||||ƒ}|r|SqdS)z|iterate over list of urls, request each one and handle responses and thrown exceptions individually per url cs|ˆ|ˆƒfSrmr!r�)rêrAr!r"Úurl_reader_serial sz@wait_for_url..read_url_serial..url_reader_serialrN)r©rÞr�)rÝrArçrèrër ZnowÚout)Úloop_nrÒrêrérßrær¸r"Úread_url_serials$ ÿþý ÿz%wait_for_url..read_url_serialcs,ttˆˆ|d�}ˆ|ˆ|||ƒ}|r(|SdS)z‘pass list of urls to dual_stack which sends requests in parallel handle response and exceptions of the first endpoint to respond )rÀrAN)rrÐ)rÝrArçrèZurl_reader_parallelrì)r×rêrérær!r"Úread_url_parallel"sü ÿz'wait_for_url..read_url_parallelz3sleep_time and sleep_time_cb are mutually exclusiveNrrŸz$Timed out, no response from urls: %s)FN)r) r�r£r©rÞrgrar:rTrªrÍ)rærÒrArÓr¬r­rÔr¯rÕr°rÖr×rÛrîrïrÝZ do_read_urlZcalculate_sleep_timerƒZcurrent_sleep_timer ÚaddressZ current_timer!) r×râr¬r­rírÒrêrér°rÔrßrær"Ú wait_for_url‚sF9   ÿ   þ   rñc@s^eZdZddd„Zdd„Zdd„Zd d „Zd d „Zd d„Zdd„Z dd„Z dd„Z dd„Z dS)ÚOauthUrlHelperNú/run/oauth_skew.jsoncCst||_|p d|_||_||_||_d|_d|_|j|j|jf}t|ƒsNd|_nt|ƒs^t dƒ‚|  ¡}|pli|_ dS)NrTrÙFzBall or none of token_key, token_secret, or consumer_key can be set) Ú consumer_keyÚconsumer_secretÚ token_keyÚ token_secretÚskew_data_fileÚ _do_oauthÚskew_change_limitÚanyÚallrgÚread_skew_fileÚ skew_data)rorôrör÷rõrøÚrequiredÚoldr!r!r"rpbs  ÿzOauthUrlHelper.__init__c Cs�|jrŒtj |j¡rŒt d|j›�¡�Vt|jdd��(}t |¡WdƒWdƒS1sd0YWdƒn1s‚0YdS)NzReading r³©Úmode) røÚosr)ÚisfilerÚTimedÚopenÚjsonÚload)roÚfpr!r!r"rý}sÿTzOauthUrlHelper.read_skew_filec Csš|js dS| ¡}|duri}|||<t d|j›�¡�Nt|jdd�� }| t |¡¡Wdƒn1sn0YWdƒn1sŒ0YdS)NzWriting Úwr)rørýrrrrVrÚdumps)rorIÚvalueZcurr r!r!r"Úupdate_skew_file…sÿzOauthUrlHelper.update_skew_filec Csôt|tƒr|jdks"|jdks"dSd|jvr>t d|j¡dS|jd}zt t|ƒ¡}Wn4t yŽ}zt d||¡WYd}~dSd}~00t |t ¡ƒ}t |j ƒj }|j |d¡}t||ƒ|jkræ| ||¡t d||¡||j|<dS)Ni“i‘Údatez$Missing header 'date' in %s responsez#Failed to convert datetime '%s': %srz$Setting oauth clockskew for %s to %d)r7rPr=rEr:r;r©Úmktimerrär�rr Únetlocrþr5Úabsrúr ) rorãrÉrZ remote_timerZZskewrIZold_skewr!r!r"r¯’s0ÿþþ     zOauthUrlHelper.exception_cbcCsZ|js iSd}t|ƒj}|jr>||jvr>tt ¡ƒ|j|}t||j|j|j |j |d�S)N)r rôrör÷rõÚ timestamp) rùrrrþr�r©Ú oauth_headersrôrör÷rõ)ror rrIr!r!r"r¬®s úzOauthUrlHelper.headers_cbcCs:t|j| d¡ƒ|d<t|j| d¡ƒ|d<||i|¤ŽS)Nr¬r¯)rÚ _headers_cbr5Ú _exception_cb)roZ wrapped_funcrsrBr!r!r"Ú_wrappedÀs ÿ ÿzOauthUrlHelper._wrappedcOs| t||¡Srm)rrñrrr!r!r"rñÉszOauthUrlHelper.wait_for_urlcOs| t||¡Srm)rrhrrr!r!r"rhÌszOauthUrlHelper.readurlc Cs6d}z|r|||ƒ}W| ||¡n| ||¡0|Srm)r¯)roZextra_exception_cbrãrÉÚretr!r!r"rÏs  zOauthUrlHelper._exception_cbcCs$i}|r||ƒ}| | |¡¡|Srm)r r¬)roZextra_headers_cbr rEr!r!r"rØs zOauthUrlHelper._headers_cb)NNNNró) rxryrzrprýr r¯r¬rrñrhrrr!r!r!r"ròasú    ròc Cs~zddlm}Wn.ty>}ztdƒ|‚WYd}~n d}~00|rNt|ƒ}nd}|j|||||j|d�}| |¡\} } } | S)Nrzoauth support is not available)Z client_secretZresource_owner_keyZresource_owner_secretZsignature_methodr)Zoauthlib.oauth1Úoauth1Ú ImportErrorÚNotImplementedErrorr'ZClientZSIGNATURE_PLAINTEXTÚsign) r rôrör÷rõrrrZZclientZ_uriZsigned_headersZ_bodyr!r!r"ràs"  úr)r?)NNrrNNNNTTNNFTrF)N)r½r¾)N)Gr¤r2rQrZloggingrrÆr©Úconcurrent.futuresrrrZ email.utilsrÚ functoolsrZ http.clientrÚ itertoolsrZsslr Útypingr r r r rrrÚ urllib.parserrrrr�rZ cloudinitrrrZ getLoggerrxr:rr#r,r�r>r'r£Údictr\rbrjrkr]r@rcr`rPr’r�rhrÇr¼rÐrTrñròrr!r!r!r"Ú sÊ     $   þ 1 ïî 6û ú ü û Uôô `ÿ