o
    YZßa–y ã                   @   s´  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlmZ d dlZd dlZd dlZd dlmZmZmZmZmZmZmZmZmZmZmZm Z  d dl!m"Z"m#Z# d dl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: d dl;m<Z< e =e>¡Z?dZ@dZAd	ZBd
ZCdZDe Ed¡ZFe+e*e,e-fZGdgZHi 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(“d)d*“d+d,“d-d.“i d/d0“d1d2“d3d4“d5d6“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“dEdF“dGdH“dIdJ“dKdL“dMdH“dNdO“¥i dPdQ“dRdS“dTdU“dVdW“dXdW“dYd.“dZd0“d[d8“d\d]“d^d_“d`da“dbdc“ddde“dfdg“dhdi“djdS“dkdl“¥i dmdn“dodn“dpdq“drdc“dsdt“dudv“dwdx“dyd]“dzd{“d|d}“d~d“d€de“d�d‚“dƒd„“d…d†“d‡dˆ“d‰dŠ“¥d‹d‹dŒdBd{d�œ¥ZIdŽZJd�ZKd�jLeKeJd‘�ZMeKeMd’œZNg d“¢ZOd”ZPd•d– Qd—d˜„ eOD ƒ¡ d™ ZRdšeP d› ZSdœeR d• eS d� ZTe EdžeT dŸ ¡ZUeVd ƒZWd¡d¢„ ZXd£d¤„ ZYd¥d¦„ ZZd§d¨„ Z[d©dª„ Z\d«d¬„ Z]d­d®„ Z^d¯d°„ Z_d±d²„ Z`�d d´dµ„Zad¶d·„ ZbG d¸d¹„ d¹ecƒZdG dºd»„ d»ecƒZeG d¼d½„ d½efƒZgG d¾d¿„ d¿egƒZh�d!dÁdÂ„ZidÃdÄ„ ZjekfdÅdÆ„ZldÇdÈ„ ZmeDfdÉdÊ„ZneDfdËdÌ„ZodÍdÎ„ ZpdÏdÐ„ ZqdÑdÒ„ Zr�d"dÓdÔ„Zs�d!dÕdÖ„Ztd×dØ„ ZudÙdÚ„ ZvG dÛdÜ„ dÜefƒZwG dÝdÞ„ dÞefƒZxdßdà„ Zydádâ„ Zzdãdä„ Z{dådæ„ Z|dçdè„ Z}	�d"dédê„Z~	�d"dëdì„Zdídî„ Z€dïdð„ Z�dñdò„ Z‚dódô„ Zƒ�d dõdö„Z„�d d÷dø„Z…dùdú„ Z†dûdü„ Z‡G dýdþ„ dþefƒZˆG dÿ�d „ �d e‰ƒZŠG �d�d„ �defƒZ‹G �d�d„ �defƒZŒG �d�d„ �defƒZ�G �d�d„ �defƒZŽG �d	�d
„ �d
efƒZ�G �d�d„ �defƒZ��d�d„ Z‘�d�d„ Z’�d#�d�d„Z“�d�d„ Z”�d�d„ Z•�d�d„ Z–�d�d„ Z—G �d�d„ �defƒZ˜G �d�d„ �defƒZ™dS ($  é    N)Útzutc)ÚjsonÚquoteÚzip_longestÚurlsplitÚ
urlunsplitÚOrderedDictÚsixÚurlparseÚget_tzinfo_optionsÚget_md5ÚMD5_AVAILABLEÚHAS_CRT)Ú
getproxiesÚproxy_bypass)ÚInvalidExpressionErrorÚConfigNotFoundÚInvalidDNSNameErrorÚClientErrorÚMetadataRetrievalErrorÚEndpointConnectionErrorÚReadTimeoutErrorÚConnectionClosedErrorÚConnectTimeoutErrorÚUnsupportedS3ArnErrorÚ*UnsupportedS3AccesspointConfigurationErrorÚSSOTokenLoadErrorÚInvalidRegionErrorÚInvalidIMDSEndpointErrorÚInvalidIMDSEndpointModeErrorÚUnsupportedOutpostResourceErrorÚ&UnsupportedS3ControlConfigurationErrorÚUnsupportedS3ControlArnErrorÚInvalidHostLabelErrorÚHTTPClientErrorÚUnsupportedS3ConfigurationErrorÚMissingDependencyException)ÚLocationParseErroré   zhttp://169.254.169.254/zhttp://[fd00:ec2::254]/)Úipv4Úipv6z-._~z[a-z0-9][a-z0-9\-]*[a-z0-9]Ú	dualstackÚa4bzalexa-for-businessÚalexaforbusinesszapi.mediatailorÚmediatailorzapi.pricingÚpricingzapi.sagemakerÚ	sagemakerÚ
apigatewayzapi-gatewayzapplication-autoscalingzapplication-auto-scalingÚ
appstream2Ú	appstreamÚautoscalingzauto-scalingzautoscaling-planszauto-scaling-plansÚcezcost-explorerÚ
cloudhsmv2zcloudhsm-v2Úcloudsearchdomainzcloudsearch-domainzcognito-idpzcognito-identity-providerÚconfigzconfig-serviceÚcurzcost-and-usage-report-servicezdata.iotziot-data-planezdata.jobs.iotziot-jobs-data-planezdata.mediastorezmediastore-dataÚdatapipelinezdata-pipelineÚ
devicefarmzdevice-farmzdevices.iot1clickziot-1click-devices-serviceÚdirectconnectzdirect-connectÚ	discoveryzapplication-discovery-serviceÚdmszdatabase-migration-serviceÚdszdirectory-serviceÚdynamodbstreamszdynamodb-streamsÚelasticbeanstalkzelastic-beanstalkÚelasticfilesystemÚefsÚelasticloadbalancingzelastic-load-balancingÚelasticmapreduceÚemrÚelastictranscoderzelastic-transcoderÚelbÚelbv2zelastic-load-balancing-v2ÚemailÚseszentitlement.marketplacezmarketplace-entitlement-serviceÚeszelasticsearch-serviceÚeventsÚeventbridgezcloudwatch-eventsziot-dataziot-jobs-dataziot1click-devicesziot1click-projectsziot-1click-projectsÚkinesisanalyticszkinesis-analyticsÚkinesisvideozkinesis-videoz
lex-modelszlex-model-building-servicezlex-runtimezlex-runtime-serviceÚlogszcloudwatch-logsÚmachinelearningzmachine-learningzmarketplace-entitlementÚmarketplacecommerceanalyticszmarketplace-commerce-analyticszmetering.marketplacezmarketplace-meteringÚmeteringmarketplaceÚmghzmigration-hubz
models.lexÚ
monitoringÚ
cloudwatchzmturk-requesterÚmturkzopsworks-cmÚ
opsworkscmzprojects.iot1clickÚresourcegroupstaggingapizresource-groups-tagging-apiÚroute53zroute-53Úroute53domainszroute-53-domainszruntime.lexzruntime.sagemakerzsagemaker-runtimeÚsdbÚsimpledbÚsecretsmanagerzsecrets-managerÚserverlessrepoÚserverlessapplicationrepositoryÚservicecatalogzservice-catalogÚsfnzstorage-gateway)ÚstatesÚstepfunctionsÚstoragegatewayzstreams.dynamodbÚtaggingz(?:[0-9]{1,3}\.){3}[0-9]{1,3}z[0-9A-Fa-f]{1,4}z(?:{hex}:{hex}|{ipv4}))Úhexr)   )rh   Úls32)	z(?:%(hex)s:){6}%(ls32)sz::(?:%(hex)s:){5}%(ls32)sz%(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)sz2(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)sz6(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)sz/(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)sz'(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)sz&(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)sz(?:(?:%(hex)s:){0,6}%(hex)s)?::zDABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._!\-~z(?:ú|c                 C   s   g | ]}|t  ‘qS © )Ú_subs)Ú.0Úxrk   rk   ú0/usr/lib/python3/dist-packages/botocore/utils.pyÚ
<listcomp>­   s    rp   ú)z(?:%25|%)(?:[z]|%[a-fA-F0-9]{2})+z\[z)?\]ú^ú$z	
c                 C   s(   t | tƒr| S t | tƒr|  ¡ dkS dS )z~Ensures a boolean value if a string or boolean is provided

    For strings, the value for True/False is case insensitive
    ÚtrueF)Ú
isinstanceÚboolÚstrÚlower©Úvalrk   rk   ro   Úensure_boolean¶   s
   

r{   c                 C   sP   |   d¡}|dur| ¡ }|tvr|tdœ}tdi |¤Ž‚|S |   d¡r&dS dS )z†Resolving IMDS endpoint mode to either IPv6 or IPv4.

    ec2_metadata_service_endpoint_mode takes precedence over imds_use_ipv6.
    Ú"ec2_metadata_service_endpoint_modeN)ÚmodeÚvalid_modesÚimds_use_ipv6r*   r)   rk   )Úget_config_variablerx   ÚMETADATA_ENDPOINT_MODESr   )ÚsessionÚendpoint_modeÚlendpoint_modeÚerror_msg_kwargsrk   rk   ro   Úresolve_imds_endpoint_modeÃ   s   ÿþ
r†   c                 C   s2   t | dƒo| j dd¡o| j d¡dko| jdkS )zþDetermines if the provided shape is the special header type jsonvalue.

    :type shape: botocore.shape
    :param shape: Shape to be inspected for the jsonvalue trait.

    :return: True if this type is a jsonvalue, False otherwise
    :rtype: Bool
    ÚserializationÚ	jsonvalueFÚlocationÚheaderÚstring)Úhasattrr‡   ÚgetÚ	type_name)Úshaperk   rk   ro   Úis_json_value_headerØ   s   

ÿþür�   c                 C   s<   | du rdS t |tjjƒr| |v S |  ¡ dd„ | ¡ D ƒv S )z&Case-insensitive check for header key.NFc                 S   s   g | ]}|  ¡ ‘qS rk   ©rx   )rm   Úkeyrk   rk   ro   rp   ð   s    ÿzhas_header.<locals>.<listcomp>)ru   ÚbotocoreÚ
awsrequestÚHeadersDictrx   Úkeys)Úheader_nameÚheadersrk   rk   ro   Ú
has_headeré   s   ÿr™   c                 C   sD   | j  d| j  d| j¡¡}| dd¡}| dd¡}t dd|¡}|S )zvReturns the module name for a service

    This is the value used in both the documentation and client class name
    ÚserviceAbbreviationÚserviceFullNameÚAmazonÚ ÚAWSz\W+)Úmetadatar�   Úservice_nameÚreplaceÚreÚsub)Úservice_modelÚnamerk   rk   ro   Úget_service_module_nameõ   s   ÿþr¦   c                 C   s   | sdS t | ƒS )Nú/)Úremove_dot_segments©Úpathrk   rk   ro   Únormalize_url_path  s   r«   c                 C   s   | du r| S t | ƒS )zLReturns None if val is None, otherwise ensure value
    converted to booleanN)r{   ry   rk   rk   ro   Únormalize_boolean
  s   r¬   c                 C   sŽ   | sdS |   d¡}g }|D ]}|r%|dkr%|dkr |r| ¡  q| |¡ q| d dkr/d}nd}| d dkr<|r<d}nd}|d |¡ | S )Nr�   r§   Ú.z..r   éÿÿÿÿ)ÚsplitÚpopÚappendÚjoin)ÚurlÚ	input_urlÚoutput_listrn   ÚfirstÚlastrk   rk   ro   r¨     s&   
€
€r¨   c                 C   s6   | r| dkrt | d�‚dD ]}|| v rt | d�‚qd S )Nr­   ©Ú
expression)ú[ú]Ú*)r   )r¹   Úinvalidrk   rk   ro   Úvalidate_jmespath_for_set.  s   

ÿÿr¾   Tc                 C   s|   |rt |ƒ | dd¡}|d t|ƒdkr|d nd}}|s$t|d�‚|r8|| vr.i | |< t| | ||dd�S || |< d S )Nr­   r(   r   r�   r¸   F)Úis_first)r¾   r¯   Úlenr   Úset_value_from_jmespath)Úsourcer¹   Úvaluer¿   ÚbitsÚcurrent_keyÚ	remainderrk   rk   ro   rÁ   9  s    "
ürÁ   c                 C   s   |   di ¡}|  d¡dk}|S )z9Determine if request is intended for an MRAP accesspoint.Ús3_accesspointÚregionr�   ©r�   )ÚcontextrÇ   Ú	is_globalrk   rk   ro   Úis_global_accesspointZ  s   rÌ   c                   @   s   e Zd ZdZdS )Ú_RetriesExceededErrorz@Internal exception used when the number of retries are exceeded.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rk   rk   rk   ro   rÍ   a  s    rÍ   c                   @   ó   e Zd Zdd„ ZdS )ÚBadIMDSRequestErrorc                 C   ó
   || _ d S ©N©Úrequest©Úselfr×   rk   rk   ro   Ú__init__g  ó   
zBadIMDSRequestError.__init__N)rÎ   rÏ   rÐ   rÚ   rk   rk   rk   ro   rÓ   f  ó    rÓ   c                   @   s‚   e Zd ZeZdZdZededddfdd„Z	dd„ Z
d	d
„ Zdd„ Zddd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zddd„ZdS )ÚIMDSFetcherzlatest/api/tokenÚ21600r(   Nc                 C   sn   || _ || _|  ||¡| _|d u rtj ¡ }| dd¡ ¡ | _	| j	dk| _	|| _
tjj| j t| jƒd�| _d S )NÚAWS_EC2_METADATA_DISABLEDÚfalsert   )ÚtimeoutÚproxies)Ú_timeoutÚ_num_attemptsÚ_select_base_urlÚ	_base_urlÚosÚenvironÚcopyr�   rx   Ú	_disabledÚ_user_agentr“   ÚhttpsessionÚURLLib3SessionÚget_environ_proxiesÚ_session)rÙ   rá   Únum_attemptsÚbase_urlÚenvÚ
user_agentr8   rk   rk   ro   rÚ   q  s   
þzIMDSFetcher.__init__c                 C   s   | j S rÕ   )ræ   ©rÙ   rk   rk   ro   Úget_base_url‚  s   zIMDSFetcher.get_base_urlc                 C   s„   |d u ri }|  d¡dk}|  d¡}|r|rt d¡ d }|tkr$|}n|r)|}n|r.t}nt}t d| ¡ t|ƒs@t|d�‚|S )Nr|   r*   Úec2_metadata_service_endpointzFCustom endpoint and IMDS_USE_IPV6 are both set. Using custom endpoint.zIMDS ENDPOINT: %s)Úendpoint)r�   ÚloggerÚwarningÚMETADATA_BASE_URLÚMETADATA_BASE_URL_IPv6ÚdebugÚis_valid_urir   )rÙ   rñ   r8   Úrequires_ipv6Úcustom_metadata_endpointÚchosen_base_urlrk   rk   ro   rå   …  s0   ÿÿ
ÿ
zIMDSFetcher._select_base_urlc                 C   s  |   ¡  | j| j }d| ji}|  |¡ tjjd||d�}t| j	ƒD ]i}z'| j
 | ¡ ¡}|jdkr8|jW   S |jdv rAW  d S |jdv rJt|ƒ‚W q" tyV   Y  d S  typ } ztjd||dd	� W Y d }~q"d }~w ty‹ } zt|j d
¡tƒr†t||d�‚‚ d }~ww d S )Nz$x-aws-ec2-metadata-token-ttl-secondsÚPUT©Úmethodr³   r˜   éÈ   )i”  i“  i•  )i�  úOCaught retryable HTTP exception while making metadata service request to %s: %sT©Úexc_infoÚerror)r÷   r  )Ú_assert_enabledræ   Ú_TOKEN_PATHÚ
_TOKEN_TTLÚ_add_user_agentr“   r”   Ú
AWSRequestÚrangerä   rï   ÚsendÚprepareÚstatus_codeÚtextrÓ   r   ÚRETRYABLE_HTTP_ERRORSrø   rü   r$   ru   Úkwargsr�   r'   r   )rÙ   r³   r˜   r×   ÚiÚresponseÚerk   rk   ro   Ú_fetch_metadata_token£  sB   ÿ
ÿ


ÿþ€€üz!IMDSFetcher._fetch_metadata_tokenc           
      C   sÄ   |   ¡  |du r| j}| j| }i }|dur||d< |  |¡ t| jƒD ]9}ztjjd||d�}| j	 
| ¡ ¡}||ƒsA|W   S W q$ ty] }	 ztjd||	dd� W Y d}	~	q$d}	~	ww |  ¡ ‚)aZ  Make a get request to the Instance Metadata Service.

        :type url_path: str
        :param url_path: The path component of the URL to make a get request.
            This arg is appended to the base_url that was provided in the
            initializer.

        :type retry_func: callable
        :param retry_func: A function that takes the response as an argument
             and determines if it needs to retry. By default empty and non
             200 OK responses are retried.

        :type token: str
        :param token: Metadata token to send along with GET requests to IMDS.
        Nzx-aws-ec2-metadata-tokenÚGETr  r  Tr  )r	  Ú_default_retryræ   r  r  rä   r“   r”   r  rï   r  r  r  rø   rü   Ú_RETRIES_EXCEEDED_ERROR_CLS)
rÙ   Úurl_pathÚ
retry_funcÚtokenr³   r˜   r  r×   r  r  rk   rk   ro   Ú_get_requestÂ  s2   

ÿ
ÿþ€ÿzIMDSFetcher._get_requestc                 C   s   | j d ur| j |d< d S d S )Nz
User-Agent)rë   )rÙ   r˜   rk   rk   ro   r  ç  s   
ÿzIMDSFetcher._add_user_agentc                 C   s   | j rt d¡ |  ¡ ‚d S )Nz)Access to EC2 metadata has been disabled.)rê   rø   rü   r  rô   rk   rk   ro   r	  ë  s   
þzIMDSFetcher._assert_enabledc                 C   ó   |   |¡p	|  |¡S rÕ   ©Ú_is_non_ok_responseÚ	_is_empty©rÙ   r  rk   rk   ro   r  ð  ó   
þzIMDSFetcher._default_retryc                 C   s"   |j dkr| j|ddd� dS dS )Nr  znon-200T©Úlog_bodyF)r  Ú_log_imds_responser$  rk   rk   ro   r"  ö  s   
zIMDSFetcher._is_non_ok_responsec                 C   s   |j s| j|ddd� dS dS )Nzno bodyTr&  F)Úcontentr(  r$  rk   rk   ro   r#  ü  s   zIMDSFetcher._is_emptyFc                 C   s@   d}||j |jg}|r|d7 }| |j¡ tj|g|¢R Ž  d S )NzHMetadata service returned %s response with status code of %s for url: %sz, content body: %s)r  r³   r±   r)  rø   rü   )rÙ   r  Úreason_to_logr'  Ú	statementÚlogger_argsrk   rk   ro   r(    s   ÿ
ÿzIMDSFetcher._log_imds_responserÕ   ©F)rÎ   rÏ   rÐ   rÍ   r  r
  r  Ú DEFAULT_METADATA_SERVICE_TIMEOUTrú   rÚ   rõ   rå   r  r  r  r	  r  r"  r#  r(  rk   rk   rk   ro   rÝ   k  s$    
þ
%rÝ   c                   @   sT   e Zd ZdZg d¢Zdd„ Zddd„Zddd	„Zd
d„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚInstanceMetadataFetcherz*latest/meta-data/iam/security-credentials/)ÚAccessKeyIdÚSecretAccessKeyÚTokenÚ
Expirationc              
   C   sÄ   z6|   ¡ }|  |¡}|  ||¡}|  |¡r&||d |d |d |d dœW S d|v r4d|v r4t d|¡ i W S  | jyH   t d	| j¡ Y i S  tya } zt d
|j	¡ W Y d }~i S d }~ww )Nr0  r1  r2  r3  )Ú	role_nameÚ
access_keyÚ
secret_keyr  Úexpiry_timeÚCodeÚMessagez7Error response received when retrievingcredentials: %s.z\Max number of attempts exceeded (%s) when attempting to retrieve data from metadata service.zBad IMDS request: %s)
r  Ú_get_iam_roleÚ_get_credentialsÚ_contains_all_credential_fieldsrø   rü   r  rä   rÓ   r×   )rÙ   r  r4  Úcredentialsr  rk   rk   ro   Úretrieve_iam_role_credentials  s4   

ûÿþþ€þz5InstanceMetadataFetcher.retrieve_iam_role_credentialsNc                 C   s   | j | j| j|d�jS ©N)r  r  r  )r  Ú	_URL_PATHÚ_needs_retry_for_role_namer  )rÙ   r  rk   rk   ro   r:  8  s   ýüz%InstanceMetadataFetcher._get_iam_rolec                 C   s$   | j | j| | j|d�}t |j¡S r?  )r  r@  Ú_needs_retry_for_credentialsr   Úloadsr  )rÙ   r4  r  Úrrk   rk   ro   r;  ?  s   ýz(InstanceMetadataFetcher._get_credentialsc                 C   s4   z	t  |j¡ W dS  ty   |  |d¡ Y dS w )NFzinvalid jsonT)r   rC  r  Ú
ValueErrorr(  r$  rk   rk   ro   Ú_is_invalid_jsonG  s   þz(InstanceMetadataFetcher._is_invalid_jsonc                 C   r   rÕ   r!  r$  rk   rk   ro   rA  O  r%  z2InstanceMetadataFetcher._needs_retry_for_role_namec                 C   s   |   |¡p|  |¡p|  |¡S rÕ   )r"  r#  rF  r$  rk   rk   ro   rB  U  s
   
ÿýz4InstanceMetadataFetcher._needs_retry_for_credentialsc                 C   s*   | j D ]}||vrt d|¡  dS qdS )Nz3Retrieved credentials is missing required field: %sFT)Ú_REQUIRED_CREDENTIAL_FIELDSrø   rü   )rÙ   r=  Úfieldrk   rk   ro   r<  \  s   
þüz7InstanceMetadataFetcher._contains_all_credential_fieldsrÕ   )rÎ   rÏ   rÐ   r@  rG  r>  r:  r;  rF  rA  rB  r<  rk   rk   rk   ro   r/    s    
"
r/  Fc                 C   s¤   |D ]M}t || tƒr$|| v r||v rt| | || ƒ q|| | |< qt || tƒrI|rI|| v rBt | | tƒrB| |  || ¡ q|| | |< q|| | |< qdS )zöGiven two dict, merge the second dict into the first.

    The dicts can have arbitrary nesting.

    :param append_lists: If true, instead of clobbering a list with the new
        value, append all of the new values onto the original list.
    N)ru   ÚdictÚmerge_dictsÚlistÚextend)Údict1Údict2Úappend_listsr’   rk   rk   ro   rJ  f  s   îrJ  c                 C   s"   i }| D ]
}| | ||  ¡ < q|S )zECopies the given dictionary ensuring all keys are lowercase strings. r‘   )Úoriginalré   r’   rk   rk   ro   Úlowercase_dictƒ  s   rQ  c                 C   sZ   z || ƒ�}|  ¡ }t|ƒW  d   ƒ W S 1 sw   Y  W d S  ty,   t| d�‚w )Nr©   )ÚreadÚparse_key_val_file_contentsÚOSErrorr   )ÚfilenameÚ_openÚfÚcontentsrk   rk   ro   Úparse_key_val_file‹  s   
(þ
ÿrY  c                 C   sH   i }|   ¡ D ]}d|vrq| dd¡\}}| ¡ }| ¡ }|||< q|S )Nú=r(   )Ú
splitlinesr¯   Ústrip)rX  ÚfinalÚliner’   rz   rk   rk   ro   rS  ”  s   
rS  c                 C   s~   g }t | dƒr|  ¡ }n| }|D ])\}}t|tƒr,|D ]}| dt|ƒt|ƒf ¡ qq| dt|ƒt|ƒf ¡ qd |¡S )af  Urlencode a dict or list into a string.

    This is similar to urllib.urlencode except that:

    * It uses quote, and not quote_plus
    * It has a default list of safe chars that don't need
      to be encoded, which matches what AWS services expect.

    If any value in the input ``mapping`` is a list type,
    then each list element wil be serialized.  This is the equivalent
    to ``urlencode``'s ``doseq=True`` argument.

    This function should be preferred over the stdlib
    ``urlencode()`` function.

    :param mapping: Either a dict to urlencode or a list of
        ``(key, value)`` pairs.

    Úitemsz%s=%sú&)rŒ   r_  ru   rK  r±   Úpercent_encoder²   )ÚmappingÚsafeÚencoded_pairsÚpairsr’   rÃ   Úelementrk   rk   ro   Úpercent_encode_sequence£  s   



ÿÿ
ÿ
rg  c                 C   s>   t | tjtjfƒst | ¡} t | tjƒs|  d¡} t| |d�S )aÂ  Urlencodes a string.

    Whereas percent_encode_sequence handles taking a dict/sequence and
    producing a percent encoded string, this function deals only with
    taking a string (not a dict/sequence) and percent encoding it.

    If given the binary type, will simply URL encode it. If given the
    text type, will produce the binary type by UTF-8 encoding the
    text. If given something else, will convert it to the text type
    first.
    úutf-8)rc  )ru   r	   Úbinary_typeÚ	text_typeÚencoder   )Ú	input_strrc  rk   rk   ro   ra  Ç  s
   

ra  c              
   C   s’   t | ttfƒrtj | |ƒ ¡S ztj t| ƒ|ƒ ¡W S  ttfy%   Y nw ztjj	| dt
ƒ id�W S  ttfyH } ztd| |f ƒ‚d}~ww )z.Parse timestamp with pluggable tzinfo options.ÚGMT)ÚtzinfoszInvalid timestamp "%s": %sN)ru   ÚintÚfloatÚdatetimeÚfromtimestampÚ	TypeErrorrE  ÚdateutilÚparserÚparser   ©rÃ   Útzinfor  rk   rk   ro   Ú_parse_timestamp_with_tzinfoÜ  s   ÿ€ÿry  c                 C   s^   t ƒ D ]%}zt| |ƒW   S  ty( } ztjd|j|d� W Y d}~qd}~ww td|  ƒ‚)zÇParse a timestamp into a datetime object.

    Supported formats:

        * iso8601
        * rfc822
        * epoch (value is an integer)

    This will return a ``datetime.datetime`` object.

    z2Unable to parse timestamp with "%s" timezone info.r  Nz4Unable to calculate correct timezone offset for "%s")r   ry  rT  rø   rü   rÎ   ÚRuntimeErrorrw  rk   rk   ro   Úparse_timestampï  s   
ÿ€ÿÿr{  c                 C   sF   t | tjƒr	| }nt| ƒ}|jdu r|jtƒ d�}|S | tƒ ¡}|S )a•  Converted the passed in value to a datetime object with tzinfo.

    This function can be used to normalize all timestamp inputs.  This
    function accepts a number of different types of inputs, but
    will always return a datetime.datetime object with time zone
    information.

    The input param ``value`` can be one of several types:

        * A datetime object (both naive and aware)
        * An integer representing the epoch time (can also be a string
          of the integer, i.e '0', instead of 0).  The epoch time is
          considered to be UTC.
        * An iso8601 formatted timestamp.  This does not need to be
          a complete timestamp, it can contain just the date portion
          without the time component.

    The returned value will be a datetime object that will have tzinfo.
    If no timezone info was provided in the input value, then UTC is
    assumed, not local time.

    N©rx  )ru   rq  r{  rx  r¡   r   Ú
astimezone)rÃ   Údatetime_objrk   rk   ro   Úparse_to_aware_datetime  s   
ÿr  c                 C   s~   t   ddd¡}| jdu r|du rtƒ }| j|d�} | jdd�|  ¡  | }t|dƒr.| ¡ S |j|j|j	d d  d  d S )	aw  Calculate the timestamp based on the given datetime instance.

    :type dt: datetime
    :param dt: A datetime object to be converted into timestamp
    :type default_timezone: tzinfo
    :param default_timezone: If it is provided as None, we treat it as tzutc().
                             But it is only used when dt is a naive datetime.
    :returns: The timestamp
    é²  r(   Nr|  Útotal_secondsé   i  i@B )
rq  rx  r   r¡   Ú	utcoffsetrŒ   r�  ÚmicrosecondsÚsecondsÚdays)ÚdtÚdefault_timezoneÚepochÚdrk   rk   ro   Údatetime2timestamp2  s   


"r‹  c                    s>   t  ¡ }t‡ fdd„dƒD ]}| |¡ q|r| ¡ S | ¡ S )a²  Calculate a sha256 checksum.

    This method will calculate the sha256 checksum of a file like
    object.  Note that this method will iterate through the entire
    file contents.  The caller is responsible for ensuring the proper
    starting position of the file and ``seek()``'ing the file back
    to its starting location if other consumers need to read from
    the file like object.

    :param body: Any file like object.  The file must be opened
        in binary mode such that a ``.read()`` call returns bytes.
    :param as_hex: If True, then the hex digest is returned.
        If False, then the digest (as binary bytes) is returned.

    :returns: The sha256 checksum

    c                      ó
   ˆ   d¡S ©Né   ©rR  rk   ©Úbodyrk   ro   Ú<lambda>Z  ó   
 z"calculate_sha256.<locals>.<lambda>ó    )ÚhashlibÚsha256ÚiterÚupdateÚ	hexdigestÚdigest)r‘  Úas_hexÚchecksumÚchunkrk   r�  ro   Úcalculate_sha256G  s   rž  c                    sº   g }d‰t j}t‡ ‡fdd„dƒD ]}| ||ƒ ¡ ¡ q|s%|dƒ ¡ S t|ƒdkrSg }t|ƒD ]\}}|durE| ||| ƒ ¡ ¡ q1| |¡ q1|}t|ƒdks+t 	|d ¡ 
d¡S )	a\  Calculate a tree hash checksum.

    For more information see:

    http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html

    :param body: Any file like object.  This has the same constraints as
        the ``body`` param in calculate_sha256

    :rtype: str
    :returns: The hex version of the calculated tree hash

    rŽ  c                      s
   ˆ   ˆ¡S rÕ   r�  rk   ©r‘  Úrequired_chunk_sizerk   ro   r’  s  r“  z%calculate_tree_hash.<locals>.<lambda>r”  r(   Nr   Úascii)r•  r–  r—  r±   rš  r™  rÀ   Ú	_in_pairsÚbinasciiÚhexlifyÚdecode)r‘  Úchunksr–  r�  Ú
new_chunksr¶   Úsecondrk   rŸ  ro   Úcalculate_tree_hashb  s    ø	r©  c                 C   s   t | ƒ}t||ƒS rÕ   )r—  r   )ÚiterableÚshared_iterrk   rk   ro   r¢  ƒ  s   	
r¢  c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚCachedPropertyzÒA read only property that caches the initially computed value.

    This descriptor will only call the provided ``fget`` function once.
    Subsequent access to this property will return the cached value.

    c                 C   rÔ   rÕ   )Ú_fget)rÙ   Úfgetrk   rk   ro   rÚ   œ  rÛ   zCachedProperty.__init__c                 C   s(   |d u r| S |   |¡}||j| j j< |S rÕ   )r­  Ú__dict__rÎ   )rÙ   ÚobjÚclsÚcomputed_valuerk   rk   ro   Ú__get__Ÿ  s
   
zCachedProperty.__get__N)rÎ   rÏ   rÐ   rÑ   rÚ   r³  rk   rk   rk   ro   r¬  ”  s    r¬  c                   @   sD   e Zd ZdZddd„Zdd„ Zddd	„Zd
d„ Zdd„ Zdd„ Z	dS )ÚArgumentGeneratora  Generate sample input based on a shape model.

    This class contains a ``generate_skeleton`` method that will take
    an input/output shape (created from ``botocore.model``) and generate
    a sample dictionary corresponding to the input/output shape.

    The specific values used are place holder values. For strings either an
    empty string or the member name can be used, for numbers 0 or 0.0 is used.
    The intended usage of this class is to generate the *shape* of the input
    structure.

    This can be useful for operations that have complex input shapes.
    This allows a user to just fill in the necessary data instead of
    worrying about the specific structure of the input arguments.

    Example usage::

        s = botocore.session.get_session()
        ddb = s.get_service_model('dynamodb')
        arg_gen = ArgumentGenerator()
        sample_input = arg_gen.generate_skeleton(
            ddb.operation_model('CreateTable').input_shape)
        print("Sample input for dynamodb.CreateTable: %s" % sample_input)

    Fc                 C   rÔ   rÕ   )Ú_use_member_names)rÙ   Úuse_member_namesrk   rk   ro   rÚ   Â  rÛ   zArgumentGenerator.__init__c                 C   s   g }|   ||¡S )zÞGenerate a sample input.

        :type shape: ``botocore.model.Shape``
        :param shape: The input shape.

        :return: The generated skeleton input corresponding to the
            provided input shape.

        )Ú_generate_skeleton)rÙ   r�   Ústackrk   rk   ro   Úgenerate_skeletonÅ  s   
z#ArgumentGenerator.generate_skeletonr�   c                 C   s>  |  |j¡ z“|jdkr|  ||¡W | ¡  S |jdkr'|  ||¡W | ¡  S |jdkr7|  ||¡W | ¡  S |jdkr[| jrF|W | ¡  S |jrTt	 
|j¡W | ¡  S W | ¡  dS |jdv rgW | ¡  dS |jdv rsW | ¡  d	S |jd
krW | ¡  dS |jdkr“t dddddd¡W | ¡  S W | ¡  d S | ¡  w )NÚ	structurerK  Úmapr‹   r�   )ÚintegerÚlongr   )rp  Údoubleg        ÚbooleanTÚ	timestampr€  r(   )r±   r¥   rŽ   Ú_generate_type_structurer°   Ú_generate_type_listÚ_generate_type_maprµ  ÚenumÚrandomÚchoicerq  ©rÙ   r�   r¸  r¥   rk   rk   ro   r·  Ò  sD   


í

ï

ñ
ô
ö

÷
ù
û
ý
ýz$ArgumentGenerator._generate_skeletonc                 C   sF   |  |j¡dkr
i S tƒ }|j ¡ D ]\}}| j|||d�||< q|S )Nr(   )r¥   )Úcountr¥   r   Úmembersr_  r·  )rÙ   r�   r¸  ÚskeletonÚmember_nameÚmember_shaperk   rk   ro   rÁ  ì  s   ÿz*ArgumentGenerator._generate_type_structurec                 C   s$   d}| j r	|jj}|  |j||¡gS )Nr�   )rµ  Úmemberr¥   r·  rÇ  rk   rk   ro   rÂ  õ  s
   ÿz%ArgumentGenerator._generate_type_listc                 C   s0   |j }|j}|jdksJ ‚td|  ||¡fgƒS )Nr‹   ÚKeyName)r’   rÃ   rŽ   r   r·  )rÙ   r�   r¸  Ú	key_shapeÚvalue_shaperk   rk   ro   rÃ  ÿ  s   ÿz$ArgumentGenerator._generate_type_mapNr-  )r�   )
rÎ   rÏ   rÐ   rÑ   rÚ   r¹  r·  rÁ  rÂ  rÃ  rk   rk   rk   ro   r´  ¨  s    

	
r´  c                 C   s,   t  | ¡rdS d t| ƒj¡}t |¡d uS )NFz[{}])ÚUNSAFE_URL_CHARSÚintersectionÚformatr
   ÚhostnameÚIPV6_ADDRZ_REÚmatch)Úendpoint_urlrÔ  rk   rk   ro   Úis_valid_ipv6_endpoint_url  s   
rØ  c                 C   sh   t  | ¡rdS t| ƒ}|j}|du rdS t|ƒdkrdS |d dkr(|dd… }t dtj¡}| |¡S )zèVerify the endpoint_url is valid.

    :type endpoint_url: string
    :param endpoint_url: An endpoint_url.  Must have at least a scheme
        and a hostname.

    :return: True if the endpoint url is valid. False otherwise.

    FNéÿ   r®   r­   z;^((?!-)[A-Z\d-]{1,63}(?<!-)\.)*((?!-)[A-Z\d-]{1,63}(?<!-))$)	rÑ  rÒ  r   rÔ  rÀ   r¢   ÚcompileÚ
IGNORECASErÖ  )r×  ÚpartsrÔ  Úallowedrk   rk   ro   Úis_valid_endpoint_url  s   
þ
rÞ  c                 C   s   t | ƒpt| ƒS rÕ   )rÞ  rØ  )r×  rk   rk   ro   rý   +  ó   rý   c                 C   s2   | du rdS t  d¡}| | ¡}|st| d�‚dS )z0Provided region_name must be a valid host label.Nz)^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)$)Úregion_name)r¢   rÚ  rÖ  r   )rà  Úvalid_host_labelÚvalidrk   rk   ro   Úvalidate_region_name/  s   


ÿrã  c                 C   sR   d| v rdS t | ƒ}|dk s|dkrdS t | ¡}|du s%| ¡ t | ƒkr'dS dS )až  
    Check to see if the ``bucket_name`` complies with the
    restricted DNS naming conventions necessary to allow
    access via virtual-hosting style.

    Even though "." characters are perfectly valid in this DNS
    naming scheme, we are going to punt on any name containing a
    "." character because these will cause SSL cert validation
    problems if we try to use virtual-hosting style addressing.
    r­   Fé   é?   NT)rÀ   ÚLABEL_RErÖ  Úend)Úbucket_nameÚnrÖ  rk   rk   ro   Úcheck_dns_name9  s   
rê  c              
   K   sb   | j  dd¡r	d}z	t| ||ƒ W dS  ty0 } z|jd }t d|¡ W Y d}~dS d}~ww )ar  
    This handler looks at S3 requests just before they are signed.
    If there is a bucket name on the path (true for everything except
    ListAllBuckets) it checks to see if that bucket name conforms to
    the DNS naming conventions.  If it does, it alters the request to
    use ``virtual hosting`` style addressing rather than ``path-style``
    addressing.

    Úuse_global_endpointFzs3.amazonaws.comrè  z2Not changing URI, bucket is not DNS compatible: %sN)rÊ   r�   Úswitch_to_virtual_host_styler   r  rø   rü   )r×   Úsignature_versionrà  Údefault_endpoint_urlr  r  rè  rk   rk   ro   Úfix_s3_hostP  s   
ÿ
ÿ€þrï  c                 K   s  | j durdS t| ƒrt d¡ dS t| jƒ}|j| _ |j d¡}|du r(|j}t	|ƒdkr†|d }|s6dS t d| j¡ t
|ƒr�t	|ƒdkrU| j d dkrU|  j d7  _ | |¡ d |¡p`d}|}|d | }	|j|	||jd	f}
t|
ƒ}|| _t d
|¡ dS t|d�‚dS )a)  
    This is a handler to force virtual host style s3 addressing no matter
    the signature version (which is taken in consideration for the default
    case). If the bucket is not DNS compatible an InvalidDNSName is thrown.

    :param request: A AWSRequest object that is about to be sent.
    :param signature_version: The signature version to sign with
    :param default_endpoint_url: The endpoint to use when switching to a
        virtual style. If None is supplied, the virtual host will be
        constructed from the url of the request.
    NzKRequest is GetBucketLocation operation, not checking for DNS compatibility.r§   r(   z*Checking for DNS compatible bucket for: %sé   r®   r­   r�   zURI updated to: %s)rè  )Ú	auth_pathÚ_is_get_bucket_location_requestrø   rü   r   r³   rª   r¯   ÚnetlocrÀ   rê  Úremover²   ÚschemeÚqueryr   r   )r×   rí  rî  r  rÜ  Ú
path_partsrè  rª   Úglobal_endpointÚhostÚ	new_tupleÚnew_urirk   rk   ro   rì  f  sB   


ÿ
ÿ
årì  c                 C   s   | j  d¡S )Nz	?location)r³   ÚendswithrÖ   rk   rk   ro   rò  ¥  ó   rò  c                    s"   ˆ j ‰t ˆ ¡‡ ‡fdd„ƒ}|S )a  Method decorator for caching method calls to a single instance.

    **This is not a general purpose caching decorator.**

    In order to use this, you *must* provide an ``_instance_cache``
    attribute on the instance.

    This decorator is used to cache method calls.  The cache is only
    scoped to a single instance though such that multiple instances
    will maintain their own cache.  In order to keep things simple,
    this decorator requires that you provide an ``_instance_cache``
    attribute on your instance.

    c                    sb   ˆ|f}|rt t| ¡ ƒƒ}ˆ||f}| j |¡}|d ur|S ˆ | g|¢R i |¤Ž}|| j|< |S rÕ   )ÚtupleÚsortedr_  Ú_instance_cacher�   )rÙ   Úargsr  Ú	cache_keyÚkwarg_itemsÚresult©ÚfuncÚ	func_namerk   ro   Ú_cache_guardº  s   

z$instance_cache.<locals>._cache_guard)rÎ   Ú	functoolsÚwraps)r  r  rk   r  ro   Úinstance_cache©  s   r  c                 K   sh   t | jƒj d¡}dd„ |D ƒ}d}t|ƒdkr!|d |¡d 7 }|d7 }|dv r+dS t| |d	d
� dS )z?Switches the current s3 endpoint with an S3 Accelerate endpointr­   c                 S   s   g | ]}|t v r|‘qS rk   ©ÚS3_ACCELERATE_WHITELIST©rm   Úprk   rk   ro   rp   Ñ  s    z-switch_host_s3_accelerate.<locals>.<listcomp>zhttps://s3-accelerate.r   úamazonaws.com)ÚListBucketsÚCreateBucketÚDeleteBucketNF)Úuse_new_scheme)r   r³   ró  r¯   rÀ   r²   Ú_switch_hosts)r×   Úoperation_namer  rÜ  r÷   rk   rk   ro   Úswitch_host_s3_accelerateÉ  s   r  c                 C   s6   t  | j d¡¡}| |¡r|| }t| |ƒ dS dS )zBSwitches the host using a parameter value from a JSON request bodyrh  N)r   rC  Údatar¥  r�   r  )r×   Ú
param_nameÚrequest_jsonÚnew_endpointrk   rk   ro   Úswitch_host_with_paramÜ  s
   
þr  c                 C   s   t | j||ƒ}|| _d S rÕ   )Ú_get_new_endpointr³   )r×   r  r  Úfinal_endpointrk   rk   ro   r  ä  s   ÿ
r  c                 C   sR   t |ƒ}t | ƒ}|j}|r|j}||j|j|jdf}t|ƒ}t d| |f ¡ |S ©Nr�   zUpdating URI from %s to %s)r   rõ  ró  rª   rö  r   rø   rü   )Úoriginal_endpointr  r  Únew_endpoint_componentsÚoriginal_endpoint_componentsrõ  Úfinal_endpoint_componentsr  rk   rk   ro   r  ê  s    ûÿr  c                 C   sR   |D ]$}|| v r t | | tƒr t || tƒr t| | || ƒ q|| | |< qdS )zõDeeply two dictionaries, overriding existing keys in the base.

    :param base: The base dictionary which will be merged into.
    :param extra: The dictionary to merge into the base. Keys from this
        dictionary will take precedence.
    N)ru   rI  Ú
deep_merge)ÚbaseÚextrar’   rk   rk   ro   r$  ý  s   ÿør$  c                 C   s   |   dd¡ ¡ S )zcTranslate the form used for event emitters.

    :param service_id: The service_id to convert.
    ú ú-)r¡   rx   )Ú
service_idrk   rk   ro   Úhyphenize_service_id  s   r*  c                   @   sH   e Zd Zddd„Zddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dS )ÚS3RegionRedirectorNc                 C   s,   || _ || _| jd u ri | _t |¡| _d S rÕ   )Ú_endpoint_resolverÚ_cacheÚweakrefÚproxyÚ_client)rÙ   Úendpoint_bridgeÚclientÚcacherk   rk   ro   rÚ     s
   
zS3RegionRedirector.__init__c                 C   s<   |p| j jj}| d| j¡ | d| j¡ | d| j¡ d S )Nzneeds-retry.s3zbefore-call.s3úbefore-parameter-build.s3)r0  ÚmetarM   ÚregisterÚredirect_from_errorÚset_request_urlÚredirect_from_cache)rÙ   Úevent_emitterÚemitterrk   rk   ro   r6  "  s   ÿzS3RegionRedirector.registerc                 K   s¦  |du rdS |   | di ¡¡rt d¡ dS | di ¡ d¡r&t d¡ dS |d  di ¡}| d¡}|d  d	i ¡}|d
v oC|jdk}|d
v oT|jdkoTd| di ¡v }	|dko\d|v }
|d duoi|d jdv }|dk}t||
||	|gƒsydS |d d d }|d  d¡}|  ||¡}|du r�t d||f ¡ dS t d|||f ¡ | j 	d|¡}|d }|||dœ}||d d< || j
|< |  ||d ¡ d|d d< dS )a  
        An S3 request sent to the wrong region will return an error that
        contains the endpoint the request should be sent to. This handler
        will add the redirect information to the signing context and then
        redirect the request.
        NrÊ   z=S3 request was previously to an accesspoint, not redirecting.Ús3_redirectedz6S3 request was previously redirected, not redirecting.r(   ÚErrorr8  ÚResponseMetadata)Ú301Ú400Ú
HeadObjectÚ
HeadBucketúx-amz-bucket-regionÚHTTPHeadersÚAuthorizationHeaderMalformedÚRegionr   )i-  i.  i3  ÚPermanentRedirectÚsigningÚbucketÚclient_regionz‡S3 client configured for region %s but the bucket %s is not in that region and the proper region could not be automatically determined.z¦S3 client configured for region %s but the bucket %s is in region %s; Please configure the proper region to avoid multiple unnecessary redirects and signing attempts.Ús3r×  )rÈ   rI  r÷   T)Ú_is_s3_accesspointr�   rø   rü   r¥   r  ÚanyÚget_bucket_regionr,  Úresolver-  r8  )rÙ   Úrequest_dictr  Ú	operationr  r  Ú
error_codeÚresponse_metadataÚis_special_head_objectÚis_special_head_bucketÚis_wrong_signing_regionÚis_redirect_statusÚis_permanent_redirectrI  rJ  Ú
new_regionr÷   Úsigning_contextrk   rk   ro   r7  )  s|   ÿÿ
þÿýþÿþþÿÿþÿý
z&S3RegionRedirector.redirect_from_errorc              
   C   s¦   |d }|d d }d|v r|d S |  di ¡  dd¡}|dur"|S z| jj|d�}|d d }W n tyJ } z|jd d }W Y d}~nd}~ww |  dd¡}|S )	a.  
        There are multiple potential sources for the new region to redirect to,
        but they aren't all universally available for use. This will try to
        find region from response elements, but will fall back to calling
        HEAD on the bucket if all else fails.

        :param bucket: The bucket to find the region for. This is necessary if
            the region is not available in the error response.
        :param response: A response representing a service request that failed
            due to incorrect region configuration.
        r(   r>  rD  rC  r=  rF  N)ÚBucket)r�   r0  Úhead_bucketr   r  )rÙ   rI  r  Úservice_responseÚresponse_headersrÈ   r˜   r  rk   rk   ro   rN    s    €ÿz$S3RegionRedirector.get_bucket_regionc                 K   s8   |  di ¡  dd ¡}|d urt|d |dƒ|d< d S d S )NrH  r÷   r³   F)r�   r  )rÙ   ÚparamsrÊ   r  r÷   rk   rk   ro   r8     s   ÿz"S3RegionRedirector.set_request_urlc                 K   sH   |   |¡rdS | d¡}| j |¡}|dur||d< dS d|i|d< dS )z†
        This handler retrieves a given bucket's signing context from the cache
        and adds it into the request context.
        Nr[  rH  rI  )rL  r�   r-  )rÙ   r_  rÊ   r  rI  rZ  rk   rk   ro   r9  ¥  s   

z&S3RegionRedirector.redirect_from_cachec                 C   s   d|v S ©NrÇ   rk   )rÙ   rÊ   rk   rk   ro   rL  ³  s   z%S3RegionRedirector._is_s3_accesspointrÕ   )
rÎ   rÏ   rÐ   rÚ   r6  r7  rN  r8  r9  rL  rk   rk   rk   ro   r+    s    


V!r+  c                   @   s   e Zd ZdS )ÚInvalidArnExceptionN)rÎ   rÏ   rÐ   rk   rk   rk   ro   ra  ·  s    ra  c                   @   rÒ   )Ú	ArnParserc                 C   sH   |  dd¡}t|ƒdk rtd| ƒ‚|d |d |d |d |d d	œS )
Nú:é   é   zUProvided ARN: %s must be of the format: arn:partition:service:region:account:resourcer(   rð  rä  é   )Ú	partitionÚservicerÈ   ÚaccountÚresource)r¯   rÀ   ra  )rÙ   ÚarnÚ	arn_partsrk   rk   ro   Ú	parse_arn¼  s   ÿÿûzArnParser.parse_arnN)rÎ   rÏ   rÐ   rm  rk   rk   rk   ro   rb  »  rÜ   rb  c                   @   s`   e Zd Ze d¡Ze d¡ZdgZddd„Zdd„ Z	d	d
„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚS3ArnParamHandlerzA^(?P<resource_type>accesspoint|outpost)[/:](?P<resource_name>.+)$zc^(?P<outpost_name>[a-zA-Z0-9\-]{1,63})[/:]accesspoint[/:](?P<accesspoint_name>[a-zA-Z0-9\-]{1,63}$)r  Nc                 C   ó   || _ |d u rtƒ | _ d S d S rÕ   ©Ú_arn_parserrb  ©rÙ   Ú
arn_parserrk   rk   ro   rÚ   Ø  ó   ÿzS3ArnParamHandler.__init__c                 C   ó   |  d| j¡ d S )Nr4  ©r6  Ú
handle_arn©rÙ   r:  rk   rk   ro   r6  Ý  ó   zS3ArnParamHandler.registerc                 K   sf   |j | jv rd S |  |¡}|d u rd S |d dkr"|  |||¡ d S |d dkr1|  |||¡ d S d S )NÚresource_typeÚaccesspointÚoutpost)r¥   Ú_BLACKLISTED_OPERATIONSÚ"_get_arn_details_from_bucket_paramÚ_store_accesspointÚ_store_outpost)rÙ   r_  ÚmodelrÊ   r  Úarn_detailsrk   rk   ro   rw  à  s   
ÿzS3ArnParamHandler.handle_arnc                 C   sH   d|v r"z|d }| j  |¡}|  ||¡ |W S  ty!   Y d S w d S )Nr[  )rq  rm  Ú_add_resource_type_and_namera  )rÙ   r_  rk  r‚  rk   rk   ro   r~  ë  s   þz4S3ArnParamHandler._get_arn_details_from_bucket_paramc                 C   s>   | j  |d ¡}|r| d¡|d< | d¡|d< d S t|d�‚)Nrj  rz  Úresource_name)rk  )Ú_RESOURCE_REGEXrÖ  Úgroupr   )rÙ   rk  r‚  rÖ  rk   rk   ro   rƒ  ö  s
   
z-S3ArnParamHandler._add_resource_type_and_namec                 C   s8   |d |d< |d |d |d |d |d dœ|d< d S )	Nr„  r[  ri  rg  rÈ   rh  )r¥   ri  rg  rÈ   rh  rÇ   rk   )rÙ   r_  rÊ   r‚  rk   rk   ro   r  þ  s   ûz$S3ArnParamHandler._store_accesspointc                 C   sd   |d }| j  |¡}|st|d�‚| d¡}||d< | d¡||d |d |d |d	 d
œ|d< d S )Nr„  )r„  Úaccesspoint_namer[  Úoutpost_nameri  rg  rÈ   rh  )rˆ  r¥   ri  rg  rÈ   rh  rÇ   )Ú_OUTPOST_RESOURCE_REGEXrÖ  r    r†  )rÙ   r_  rÊ   r‚  r„  rÖ  r‡  rk   rk   ro   r€    s   

úz S3ArnParamHandler._store_outpostrÕ   )rÎ   rÏ   rÐ   r¢   rÚ  r…  r‰  r}  rÚ   r6  rw  r~  rƒ  r  r€  rk   rk   rk   ro   rn  Ì  s     ÿÿÿ
rn  c                   @   sð   e Zd ZdZdZ			d7d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„ 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*„ Zd+d,„ Zd-d.„ Zd/d0„ Zed1d2„ ƒZed3d4„ ƒZed5d6„ ƒZdS )8ÚS3EndpointSetterÚawsr  NFc                 C   óJ   || _ || _|| _|| _|d u ri | _|| _|| _|d u r#| j| _d S d S rÕ   ©r,  Ú_regionÚ
_s3_configÚ_use_fips_endpointÚ_endpoint_urlÚ
_partitionÚ_DEFAULT_PARTITION©rÙ   Úendpoint_resolverrÈ   Ú	s3_configr×  rg  Úuse_fips_endpointrk   rk   ro   rÚ   '  s   ÿzS3EndpointSetter.__init__c                 C   s.   |  d| j¡ |  d| j¡ |  d| j¡ d S )Nzbefore-sign.s3zchoose-signer.s3z%before-call.s3.WriteGetObjectResponse)r6  Úset_endpointÚ
set_signerÚ#update_endpoint_to_s3_object_lambdarx  rk   rk   ro   r6  6  s   þzS3EndpointSetter.registerc                 K   sh   | j rtdd�‚|  |d¡ | jrd S | j}| d| j¡}dj|d |d d�}t|d |d	ƒ|d< d S )
NzOS3 client does not support accelerate endpoints for S3 Object Lambda operations©Úmsgús3-object-lambdazhttps://{host_prefix}{hostname}Úhost_prefixrÔ  )rž  rÔ  r³   F)	Ú_use_accelerate_endpointr%   Ú_override_signing_namer‘  r,  Úconstruct_endpointrŽ  rÓ  r  )rÙ   r_  rÊ   r  ÚresolverÚresolvedr  rk   rk   ro   rš  >  s   ÿþz4S3EndpointSetter.update_endpoint_to_s3_object_lambdac                 K   sœ   |   |¡r&|  |¡ |  |¡ |  |¡ |  |¡}|  |¡ |  ||¡ d S | jr=| jr4t	d| j
 d�‚tdd|i|¤Ž | jrL| jdd|i|¤Ž d S d S )Nz{Client is configured to use the FIPS psuedo region for "%s", but S3 Accelerate does not have any FIPS compatible endpoints.r›  r×   rk   )Ú_use_accesspoint_endpointÚ_validate_accesspoint_supportedÚ_validate_fips_supportedÚ_validate_global_regionsÚ(_resolve_region_for_accesspoint_endpointÚ._resolve_signing_name_for_accesspoint_endpointÚ_switch_to_accesspoint_endpointrŸ  r�  r%   rŽ  r  Ú_s3_addressing_handler)rÙ   r×   r  rà  rk   rk   ro   r˜  W  s.   



ÿÿþþÿzS3EndpointSetter.set_endpointc                 C   ó
   d|j v S r`  ©rÊ   rØ   rk   rk   ro   r¤  o  rÛ   z*S3EndpointSetter._use_accesspoint_endpointc                 C   sˆ   | j sd S d|jd d v rtdhd�‚d|jd v r#td| j d�‚|jd d }|| jkr@| j dd	¡sBtd
| j|f d�‚d S d S )NÚfipsrÇ   rÈ   ú,Invalid ARN, FIPS region not allowed in ARN.r›  rˆ  zhClient is configured to use the FIPS psuedo-region "%s", but outpost ARNs do not support FIPS endpoints.Úuse_arn_regionTzÛClient is configured to use the FIPS psuedo-region for "%s", but the access-point ARN provided is for the "%s" region. For clients using a FIPS psuedo-region calls to access-point ARNs in another region are not allowed.)r�  rÊ   r   rŽ  r�  r�   ©rÙ   r×   Úaccesspoint_regionrk   rk   ro   r¦  r  s2   ÿÿþþ
ÿüþüz)S3EndpointSetter._validate_fips_supportedc                 C   s0   | j  dd¡r	d S | jdv rtd| j d�‚d S )Nr°  T)z
aws-globalzs3-external-1z‚Client is configured to use the global psuedo-region "%s". When providing access-point ARNs a regional endpoint must be specified.r›  )r�  r�   rŽ  r   rØ   rk   rk   ro   r§  ”  s   
þþÿz)S3EndpointSetter._validate_global_regionsc                 C   s¢   | j rtdd�‚|jd d }|| jkrtd| j|f d�‚|jd  d¡}|dkr5| j d¡r5td	d�‚|jd  d
¡}|rJ| j d¡rJtdd�‚|  |¡ d S )NzZClient does not support s3 accelerate configuration when an access-point ARN is specified.r›  rÇ   rg  z–Client is configured for "%s" partition, but access-point ARN provided is for "%s" partition. The client and  access-point partition must be the same.rh  r�  Úuse_dualstack_endpointzjClient does not support s3 dualstack configuration when an S3 Object Lambda access point ARN is specified.rˆ  zTClient does not support s3 dualstack configuration when an outpost ARN is specified.)rŸ  r   rÊ   r’  r�   r�  Ú_validate_mrap_s3_config)rÙ   r×   Úrequest_partitionÚ
s3_servicerˆ  rk   rk   ro   r¥     s.   þ
ÿþþþþz0S3EndpointSetter._validate_accesspoint_supportedc                 C   s>   t |jƒsd S | j d¡rtdd�‚| j d¡rtdd�‚d S )NÚ$s3_disable_multiregion_access_pointszCInvalid configuration, Multi-Region Access Point ARNs are disabled.r›  r³  zeClient does not support s3 dualstack configuration when a Multi-Region Access Point ARN is specified.)rÌ   rÊ   r�  r�   r   rØ   rk   rk   ro   r´  Ä  s   
þþÿz)S3EndpointSetter._validate_mrap_s3_configc                 C   sN   t |jƒr|  |d¡ | jS | j dd¡r$|jd d }|  ||¡ |S | jS )Nr¼   r°  TrÇ   rÈ   )rÌ   rÊ   Ú_override_signing_regionr�  r�   rŽ  r±  rk   rk   ro   r¨  Ö  s   
ùz9S3EndpointSetter._resolve_region_for_accesspoint_endpointc                 K   s   t |ƒrtrdS tdd�‚d S )NÚs3v4azzUsing S3 with an MRAP arn requires an additional dependency. You will need to pip install botocore[crt] before proceeding.r›  )rÌ   r   r&   )rÙ   rÊ   r  rk   rk   ro   r™  ã  s   ÿüzS3EndpointSetter.set_signerc                 C   s    |j d d }|  |j |¡ d S )NrÇ   rh  ©rÊ   r   )rÙ   r×   Úaccesspoint_servicerk   rk   ro   r©  î  s   z?S3EndpointSetter._resolve_signing_name_for_accesspoint_endpointc                 C   sT   t |jƒ}t|j|  |j|¡|  |j|j¡|jdfƒ}t	 
d|j|f ¡ ||_d S r  )r   r³   r   rõ  Ú_get_netlocrÊ   Ú_get_accesspoint_pathrª   rö  rø   rü   )rÙ   r×   rà  Úoriginal_componentsÚaccesspoint_endpointrk   rk   ro   rª  ò  s   
ÿúÿ
z0S3EndpointSetter._switch_to_accesspoint_endpointc                 C   s   t |ƒr	|  |¡S |  ||¡S rÕ   )rÌ   Ú_get_mrap_netlocÚ_get_accesspoint_netloc)rÙ   Úrequest_contextrà  rk   rk   ro   r¼     s   
zS3EndpointSetter._get_netlocc                 C   s\   |d }d}|d g}| j rt| j ƒj}| |¡ n|d }| d||  |¡g¡ d |¡S )NrÇ   z	s3-globalr¥   rg  r{  r­   )r‘  r   ró  r±   rL  Ú_get_partition_dns_suffixr²   )rÙ   rÂ  rÇ   rà  Úmrap_netloc_componentsÚendpoint_url_netlocrg  rk   rk   ro   rÀ    s   ÿýÿ
z!S3EndpointSetter._get_mrap_netlocc           	      C   sÚ   |d }d|d |d f g}|  d¡}| jr*|r| |¡ t| jƒj}| |¡ n>|r6|dg}| |¡ n|d dkrH|  d|¡}| |¡ n|  d	|¡}| |¡ | j  d
¡r^| d¡ | ||  |¡g¡ d 	|¡S )NrÇ   z%s-%sr¥   ri  rˆ  ús3-outpostsrh  r�  zs3-accesspointr³  r+   r­   )
r�   r‘  r±   r   ró  rL  Ú_inject_fips_if_neededr�  Ú_get_dns_suffixr²   )	rÙ   rÂ  rà  rÇ   Úaccesspoint_netloc_componentsrˆ  rÅ  Úoutpost_hostÚ	componentrk   rk   ro   rÁ    s:   ÿ

ÿÿ

þÿ
z(S3EndpointSetter._get_accesspoint_netlocc                 C   s   | j rd| S |S )Nz%s-fips©r�  )rÙ   rË  rÂ  rk   rk   ro   rÇ  ;  s   z'S3EndpointSetter._inject_fips_if_neededc                 C   s"   |d d }|  d| dd¡pdS )NrÇ   r¥   r§   r�   r(   )r¡   )rÙ   Úoriginal_pathrÂ  r¥   rk   rk   ro   r½  @  s   z&S3EndpointSetter._get_accesspoint_pathc                 C   s   | j  |¡}|d u r| j}|S rÕ   )r,  Úget_partition_dns_suffixÚ_DEFAULT_DNS_SUFFIX)rÙ   Úpartition_nameÚ
dns_suffixrk   rk   ro   rÃ  I  s   ÿz*S3EndpointSetter._get_partition_dns_suffixc                 C   ó,   | j  d|¡}| j}|rd|v r|d }|S ©NrK  Ú	dnsSuffix©r,  r¡  rÏ  ©rÙ   rà  r£  rÑ  rk   rk   ro   rÈ  Q  ó   ÿz S3EndpointSetter._get_dns_suffixc                 C   ó$   |j  di ¡}||d< ||j d< d S ©NrH  rÈ   ©rÊ   r�   ©rÙ   r×   rà  rZ  rk   rk   ro   r¸  Y  ó   z)S3EndpointSetter._override_signing_regionc                 C   s    |  di ¡}||d< ||d< d S ©NrH  Úsigning_namerÉ   )rÙ   rÊ   rÞ  rZ  rk   rk   ro   r   b  s   z'S3EndpointSetter._override_signing_namec                 C   sˆ   | j  d¡rdS | jd u rdS t| jƒj}| d¡sdS | d¡}|d dkr)dS |dd	… }t|ƒtt|ƒƒkr;dS t	d
d„ |D ƒƒS )NÚuse_accelerate_endpointTFr  r­   r   zs3-accelerater(   éþÿÿÿc                 s   s   � | ]}|t v V  qd S rÕ   r  r  rk   rk   ro   Ú	<genexpr>Œ  s   € z<S3EndpointSetter._use_accelerate_endpoint.<locals>.<genexpr>)
r�  r�   r‘  r   ró  rü  r¯   rÀ   ÚsetÚall)rÙ   ró  rÜ  Úfeature_partsrk   rk   ro   rŸ  k  s   


z)S3EndpointSetter._use_accelerate_endpointc                 C   s"   | j rdS | j d¡}|r|S d S )NÚvirtualÚaddressing_style)rŸ  r�  r�   )rÙ   Úconfigured_addressing_stylerk   rk   ro   Ú_addressing_styleŽ  s   ÿz"S3EndpointSetter._addressing_stylec                 C   sH   | j dkrt d¡ tS | j dks| jd urt d¡ d S t d¡ tS )Nrå  z'Using S3 virtual host style addressing.rª   zUsing S3 path style addressing.zSDefaulting to S3 virtual host style addressing with path style addressing fallback.)rè  rø   rü   rì  r‘  rï  rô   rk   rk   ro   r«  š  s   



z'S3EndpointSetter._s3_addressing_handler©NNNNF)rÎ   rÏ   rÐ   r“  rÏ  rÚ   r6  rš  r˜  r¤  r¦  r§  r¥  r´  r¨  r™  r©  rª  r¼  rÀ  rÁ  rÇ  r½  rÃ  rÈ  r¸  r   r¬  rŸ  rè  r«  rk   rk   rk   ro   rŠ  #  sD    
þ"$!			
"
rŠ  c                   @   sæ   e Zd ZdZdZe d¡Z			d6d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„ 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+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ ZdS )7ÚS3ControlEndpointSetterr‹  r  z^[a-zA-Z0-9\-]{1,63}$NFc                 C   rŒ  rÕ   r�  r”  rk   rk   ro   rÚ   ¶  s   ÿz S3ControlEndpointSetter.__init__c                 C   ru  )Nzbefore-sign.s3-control)r6  r˜  rx  rk   rk   ro   r6  Ä  ry  z S3ControlEndpointSetter.registerc                 K   s‚   |   |¡r!|  |¡ |  |¡}|  |¡ |  ||¡ |  |¡ d S |  |¡r?|  |¡ |  |d¡ |  	| j
¡}|  ||¡ d S d S ©NrÆ  )Ú_use_endpoint_from_arn_detailsÚ-_validate_endpoint_from_arn_details_supportedÚ _resolve_region_from_arn_detailsÚ&_resolve_signing_name_from_arn_detailsÚ"_resolve_endpoint_from_arn_detailsÚ_add_headers_from_arn_detailsÚ_use_endpoint_from_outpost_idÚ#_validate_outpost_redirection_validr   Ú_construct_outpost_endpointrŽ  Ú_update_request_netloc)rÙ   r×   r  rà  Ú
new_netlocrk   rk   ro   r˜  Ç  s   





üz$S3ControlEndpointSetter.set_endpointc                 C   r¬  )Nr‚  r­  rØ   rk   rk   ro   rì  Ô  rÛ   z6S3ControlEndpointSetter._use_endpoint_from_arn_detailsc                 C   r¬  )NÚ
outpost_idr­  rØ   rk   rk   ro   rò  ×  rÛ   z5S3ControlEndpointSetter._use_endpoint_from_outpost_idc                 C   sÊ   d|j d d v rt|j d d dhd�‚| j dd¡s4|j d d }|| jkr4d	|| jf }t|d
�‚|j d d }|| jkrJtd| j|f d
�‚| j d¡rUtdd
�‚d|j d v rc|  |¡ d S d S )Nr®  r‚  rÈ   rP  r¯  ©rk  rœ  r°  FzpThe use_arn_region configuration is disabled but received arn for "%s" when the client is configured to use "%s"r›  rg  zClient is configured for "%s" partition, but arn provided is for "%s" partition. The client and arn partition must be the same.rß  z7S3 control client does not support accelerate endpointsrˆ  )rÊ   r"   r�  r�   rŽ  r!   r’  ró  )rÙ   r×   Ú
arn_regionÚ	error_msgÚrequest_partionrk   rk   ro   rí  Ú  s8   ÿþ
ü

ÿþþÿÿzES3ControlEndpointSetter._validate_endpoint_from_arn_details_supportedc                 C   s   | j  d¡rtdd�‚d S )Nr³  zPClient does not support s3 dualstack configuration when an outpost is specified.r›  )r�  r�   r!   rØ   rk   rk   ro   ró  ü  s
   þÿz;S3ControlEndpointSetter._validate_outpost_redirection_validc                 C   s2   | j  dd¡r|jd d }|  ||¡ |S | jS )Nr°  Fr‚  rÈ   )r�  r�   rÊ   r¸  rŽ  )rÙ   r×   rù  rk   rk   ro   rî    s
   z8S3ControlEndpointSetter._resolve_region_from_arn_detailsc                 C   s   |j d d }|  ||¡ |S )Nr‚  rh  rº  )rÙ   r×   Úarn_servicerk   rk   ro   rï    s   z>S3ControlEndpointSetter._resolve_signing_name_from_arn_detailsc                 C   s   |   ||¡}|  ||¡ d S rÕ   )Ú _resolve_netloc_from_arn_detailsrõ  )rÙ   r×   rà  rö  rk   rk   ro   rð    s   z:S3ControlEndpointSetter._resolve_endpoint_from_arn_detailsc                 C   s@   t |jƒ}t|j||j|jdfƒ}t d|j|f ¡ ||_d S r  )r   r³   r   rõ  rª   rö  rø   rü   )rÙ   r×   rö  r¾  Úarn_details_endpointrk   rk   ro   rõ    s   
ûÿ
z.S3ControlEndpointSetter._update_request_netlocc                 C   s0   |j d }d|v r|  |¡S |d }|  ||¡S )Nr‚  rˆ  ri  )rÊ   rô  Ú_construct_s3_control_endpoint)rÙ   r×   rà  r‚  ri  rk   rk   ro   rý  %  s
   

z8S3ControlEndpointSetter._resolve_netloc_from_arn_detailsc                 C   s   | j  |¡S rÕ   )Ú_HOST_LABEL_REGEXrÖ  )rÙ   Úlabelrk   rk   ro   Ú_is_valid_host_label,  rý  z,S3ControlEndpointSetter._is_valid_host_labelc                 G   s"   |D ]}|   |¡st|d�‚qd S )N)r  )r  r#   )rÙ   Úlabelsr  rk   rk   ro   Ú_validate_host_labels/  s
   

ÿÿz-S3ControlEndpointSetter._validate_host_labelsc                 C   s\   |   ||¡ | jrt| jƒj}||g}n|dg}|  |¡ |  |¡}| ||g¡ |  |¡S )Nz
s3-control)r  r‘  r   ró  Ú_add_dualstackrÈ  rL  Ú_construct_netloc)rÙ   rà  ri  rÅ  ró  rÑ  rk   rk   ro   rÿ  4  s   
þ


z6S3ControlEndpointSetter._construct_s3_control_endpointc                 C   s@   |   |¡ | jrt| jƒjS d||  |¡g}|  |¡ |  |¡S rë  )r  r‘  r   ró  rÈ  Ú	_add_fipsr  )rÙ   rà  ró  rk   rk   ro   rô  C  s   
ý

z3S3ControlEndpointSetter._construct_outpost_endpointc                 C   s
   d  |¡S )Nr­   )r²   ©rÙ   ró  rk   rk   ro   r  P  rÛ   z)S3ControlEndpointSetter._construct_netlocc                 C   s   | j r|d d |d< d S d S )Nr   z-fipsrÌ  r  rk   rk   ro   r  S  s   ÿz!S3ControlEndpointSetter._add_fipsc                 C   s   | j  d¡r| d¡ d S d S )Nr³  r+   )r�  r�   r±   r  rk   rk   ro   r  W  s   ÿz&S3ControlEndpointSetter._add_dualstackc                 C   rÒ  rÓ  rÕ  rÖ  rk   rk   ro   rÈ  [  r×  z'S3ControlEndpointSetter._get_dns_suffixc                 C   rØ  rÙ  rÚ  rÛ  rk   rk   ro   r¸  c  rÜ  z0S3ControlEndpointSetter._override_signing_regionc                 C   rØ  rÝ  rÚ  )rÙ   r×   rÞ  rZ  rk   rk   ro   r   l  rÜ  z.S3ControlEndpointSetter._override_signing_namec                 C   s,   |j d }| d¡}|r|  ||¡ d S d S )Nr‚  rˆ  )rÊ   r�   Ú_add_outpost_id_header)rÙ   r×   r‚  rˆ  rk   rk   ro   rñ  u  s
   

ÿz5S3ControlEndpointSetter._add_headers_from_arn_detailsc                 C   s   ||j d< d S )Nzx-amz-outpost-id)r˜   )rÙ   r×   rˆ  rk   rk   ro   r	  {  ó   z.S3ControlEndpointSetter._add_outpost_id_headerré  ) rÎ   rÏ   rÐ   r“  rÏ  r¢   rÚ  r   rÚ   r6  r˜  rì  rò  rí  ró  rî  rï  rð  rõ  rý  r  r  rÿ  rô  r  r  r  rÈ  r¸  r   rñ  r	  rk   rk   rk   ro   rê  ±  s>    

þ"				rê  c                   @   s€   e Zd Ze d¡Zd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„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚS3ControlArnParamHandlerz[/:]Nc                 C   ro  rÕ   rp  rr  rk   rk   ro   rÚ   ‚  rt  z!S3ControlArnParamHandler.__init__c                 C   ru  )Nz!before-parameter-build.s3-controlrv  rx  rk   rk   ro   r6  ‡  s   þz!S3ControlArnParamHandler.registerc                 K   s<   |j dv r|  |||¡ d S |  |||¡ |  |||¡ d S )N)r  ÚListRegionalBuckets)r¥   Ú_handle_outpost_id_paramÚ_handle_name_paramÚ_handle_bucket_param)rÙ   r_  r�  rÊ   r  rk   rk   ro   rw  �  s   
z#S3ControlArnParamHandler.handle_arnc                 C   sR   ||vrd S z|| }| j  |¡}||d< |  |¡|d< |W S  ty(   Y d S w )NrP  Ú	resources)rq  rm  Ú_split_resourcera  )rÙ   r_  r  rk  r‚  rk   rk   ro   Ú_get_arn_details_from_param—  s   ÿz4S3ControlArnParamHandler._get_arn_details_from_paramc                 C   s   | j  |d ¡S )Nrj  )Ú_RESOURCE_SPLIT_REGEXr¯   )rÙ   r‚  rk   rk   ro   r  £  rß  z(S3ControlArnParamHandler._split_resourcec                 C   sD   |d }d|v r|d |krd|d  }t |d |d�‚||d< d S )Nri  Ú	AccountIdzGAccount ID in arn does not match the AccountId parameter provided: "%s"rP  rø  )r"   )rÙ   r_  r‚  Ú
account_idrú  rk   rk   ro   Ú_override_account_id_param¦  s   ýþz3S3ControlArnParamHandler._override_account_id_paramc                 C   s   d|vrd S |d |d< d S )NÚ	OutpostIdr÷  rk   )rÙ   r_  r�  rÊ   rk   rk   ro   r  ³  s   z1S3ControlArnParamHandler._handle_outpost_id_paramc                 C   sV   |j dkrd S |  |d¡}|d u rd S |  |¡r!|  |||¡ d S d}t|d |d�‚)NÚCreateAccessPointÚNamez4The Name parameter does not support the provided ARNrP  rø  )r¥   r  Ú_is_outpost_accesspointÚ_store_outpost_accesspointr"   ©rÙ   r_  r�  rÊ   r‚  rú  rk   rk   ro   r  ¸  s   

þz+S3ControlArnParamHandler._handle_name_paramc                 C   ó@   |d dkrdS |d }t |ƒdkrdS |d dko|d d	kS )
Nrh  rÆ  Fr  rf  r   r|  rð  r{  ©rÀ   ©rÙ   r‚  r  rk   rk   ro   r  È  ó   z0S3ControlArnParamHandler._is_outpost_accesspointc                 C   óD   |   ||¡ |d d }||d< ||d< |d d |d< ||d< d S )Nr  rä  r  r‡  r(   rˆ  r‚  ©r  )rÙ   r_  rÊ   r‚  r‡  rk   rk   ro   r  Ñ  ó   z3S3ControlArnParamHandler._store_outpost_accesspointc                 C   sH   |   |d¡}|d u rd S |  |¡r|  |||¡ d S d}t|d |d�‚)Nr[  z6The Bucket parameter does not support the provided ARNrP  rø  )r  Ú_is_outpost_bucketÚ_store_outpost_bucketr"   r  rk   rk   ro   r  Ù  s   
ÿþz-S3ControlArnParamHandler._handle_bucket_paramc                 C   r  )
Nrh  rÆ  Fr  rf  r   r|  rð  rI  r  r  rk   rk   ro   r$  è  r   z+S3ControlArnParamHandler._is_outpost_bucketc                 C   r!  )Nr  rä  r[  rè  r(   rˆ  r‚  r"  )rÙ   r_  rÊ   r‚  rè  rk   rk   ro   r%  ñ  r#  z.S3ControlArnParamHandler._store_outpost_bucketrÕ   )rÎ   rÏ   rÐ   r¢   rÚ  r  rÚ   r6  rw  r  r  r  r  r  r  r  r  r$  r%  rk   rk   rk   ro   r    s    


		r  c                   @   sr   e Zd ZdZdZdZdZeddgZdej	fdd	„Z
dd
d„Zdd„ Zdd„ Zdd„ Zddd„Zdd„ Zdd„ ZdS )ÚContainerMetadataFetcherrð  rä  r(   z169.254.170.2Ú	localhostz	127.0.0.1Nc                 C   s(   |d u rt jj| jd�}|| _|| _d S )N)rá   )r“   rì   rí   ÚTIMEOUT_SECONDSrï   Ú_sleep)rÙ   r‚   Úsleeprk   rk   ro   rÚ   	  s   ÿ
z!ContainerMetadataFetcher.__init__c                 C   s   |   |¡ |  ||¡S )zôRetrieve JSON metadata from container metadata.

        :type full_url: str
        :param full_url: The full URL of the metadata service.
            This should include the scheme as well, e.g
            "http://localhost:123/foo"

        )Ú_validate_allowed_urlÚ_retrieve_credentials)rÙ   Úfull_urlr˜   rk   rk   ro   Úretrieve_full_uri
	  s   
	z*ContainerMetadataFetcher.retrieve_full_uric                 C   s:   t j |¡}|  |j¡}|std|jd | j¡f ƒ‚d S )NzGUnsupported host '%s'.  Can only retrieve metadata from these hosts: %sz, )r“   Úcompatr
   Ú_check_if_whitelisted_hostrÔ  rE  r²   Ú_ALLOWED_HOSTS)rÙ   r-  ÚparsedÚis_whitelisted_hostrk   rk   ro   r+  	  s   ÿþÿÿz.ContainerMetadataFetcher._validate_allowed_urlc                 C   s   || j v rdS dS )NTF)r1  )rÙ   rù  rk   rk   ro   r0   	  s   
z3ContainerMetadataFetcher._check_if_whitelisted_hostc                 C   s   |   |¡}|  |¡S )zÃRetrieve JSON metadata from ECS metadata.

        :type relative_uri: str
        :param relative_uri: A relative URI, e.g "/foo/bar?id=123"

        :return: The parsed JSON response.

        )r-  r,  )rÙ   Úrelative_urir-  rk   rk   ro   Úretrieve_uri%	  s   
	
z%ContainerMetadataFetcher.retrieve_uric              
   C   sŠ   ddi}|d ur|  |¡ d}	 z	|  ||| j¡W S  tyC } ztjd|dd� |  | j¡ |d7 }|| jkr9‚ W Y d }~nd }~ww q)NÚAcceptzapplication/jsonr   TzAReceived error when attempting to retrieve container metadata: %sr  r(   )	r˜  Ú_get_responser(  r   rø   rü   r)  Ú
SLEEP_TIMEÚRETRY_ATTEMPTS)rÙ   r-  Úextra_headersr˜   Úattemptsr  rk   rk   ro   r,  1	  s*   
ÿÿ
ÿ€ûüz.ContainerMetadataFetcher._retrieve_credentialsc           
   
   C   s¶   zEt jj}|d||d�}| j | ¡ ¡}|j d¡}|jdkr)t	d|j|f d�‚zt
 |¡W W S  tyE   d}t d||¡ t	|d�‚w  tyZ }	 z	d	|	 }t	|d�‚d }	~	ww )
Nr  r  rh  r  z4Received non 200 response (%s) from ECS metadata: %s©rú  z8Unable to parse JSON returned from ECS metadata servicesz%s:%sz;Received error when attempting to retrieve ECS metadata: %s)r“   r”   r  rï   r  r  r)  r¥  r  r   r   rC  rE  rø   rü   r  )
rÙ   r-  r˜   rá   r  r×   r  Úresponse_textrú  r  rk   rk   ro   r7  B	  s4   
þÿÿ
ûÿ
€ýz&ContainerMetadataFetcher._get_responsec                 C   s   d| j |f S )Nzhttp://%s%s)Ú
IP_ADDRESS)rÙ   r4  rk   rk   ro   r-  Z	  r
  z!ContainerMetadataFetcher.full_urlrÕ   )rÎ   rÏ   rÐ   r(  r9  r8  r>  r1  Útimer*  rÚ   r.  r+  r0  r5  r,  r7  r-  rk   rk   rk   ro   r&  ú  s    



r&  c                 C   s   t | ƒri S tƒ S rÕ   )Úshould_bypass_proxiesr   ©r³   rk   rk   ro   rî   ^	  s   rî   c              	   C   s6   zt t| ƒjƒrW dS W dS  ttjfy   Y dS w )z:
    Returns whether we should bypass proxies or not.
    TF)r   r
   ró  rs  ÚsocketÚgaierrorrA  rk   rk   ro   r@  e	  s   ÿýýr@  ú
ISO-8859-1c                 C   sF   |   d¡}|s	dS t |¡\}}d|v r|d  d¡S d|v r!|S dS )z®Returns encodings from given HTTP Header Dict.

    :param headers: dictionary to extract encoding from.
    :param default: default encoding if the content-type is text
    zcontent-typeNÚcharsetz'"r  )r�   ÚcgiÚparse_headerr\  )r˜   ÚdefaultÚcontent_typer_  rk   rk   ro   Úget_encoding_from_headersz	  s   
ÿrJ  c                 K   s0   t | ttfƒrt| ƒ}nt| ƒ}t |¡ d¡S )Nr¡  )ru   ÚbytesÚ	bytearrayÚ_calculate_md5_from_bytesÚ_calculate_md5_from_fileÚbase64Ú	b64encoder¥  )r‘  r  Ú
binary_md5rk   rk   ro   Úcalculate_md5�	  s   
rR  c                 C   s   t | ƒ}| ¡ S rÕ   )r   rš  )Ú
body_bytesÚmd5rk   rk   ro   rM  —	  s   rM  c                    sB   ˆ   ¡ }tƒ }t‡ fdd„dƒD ]}| |¡ qˆ  |¡ | ¡ S )Nc                      rŒ  r�  r�  rk   ©Úfileobjrk   ro   r’  Ÿ	  r“  z*_calculate_md5_from_file.<locals>.<lambda>r”  )Útellr   r—  r˜  Úseekrš  )rV  Ústart_positionrT  r�  rk   rU  ro   rN  œ	  s   
rN  c                 K   sP   | d }| d }t r"|dur$d|vr&t|fi |¤Ž}|| d d< dS dS dS dS )z1Only add a Content-MD5 if the system supports it.r˜   r‘  NzContent-MD5)r   rR  )r_  r  r˜   r‘  Ú
md5_digestrk   rk   ro   Úconditionally_calculate_md5¥	  s   þr[  c                   @   s    e Zd Zefdd„Zdd„ ZdS )ÚFileWebIdentityTokenLoaderc                 C   s   || _ || _d S rÕ   )Ú_web_identity_token_pathrV  )rÙ   Úweb_identity_token_pathrV  rk   rk   ro   rÚ   ¯	  s   
z#FileWebIdentityTokenLoader.__init__c                 C   s8   |   | j¡�}| ¡ W  d   ƒ S 1 sw   Y  d S rÕ   )rV  r]  rR  )rÙ   Ú
token_filerk   rk   ro   Ú__call__³	  s   $ÿz#FileWebIdentityTokenLoader.__call__N)rÎ   rÏ   rÐ   ÚopenrÚ   r`  rk   rk   rk   ro   r\  ®	  s    r\  c                   @   s&   e Zd Zddd„Zdd„ Zdd„ ZdS )	ÚSSOTokenLoaderNc                 C   s   |d u ri }|| _ d S rÕ   )r-  )rÙ   r3  rk   rk   ro   rÚ   ¹	  s   
zSSOTokenLoader.__init__c                 C   s   t  | d¡¡ ¡ S )Nrh  )r•  Úsha1rk  r™  )rÙ   Ú	start_urlrk   rk   ro   Ú_generate_cache_key¾	  s   z"SSOTokenLoader._generate_cache_keyc                 C   sJ   |   |¡}z
| j| }|d W S  ty$   tjddd� d}t|d�‚w )NÚaccessTokenzFailed to load SSO token:Tr  z@The SSO access token has either expired or is otherwise invalid.r<  )re  r-  ÚKeyErrorrø   rü   r   )rÙ   rd  r  r  rú  rk   rk   ro   r`  Á	  s   


ÿ
úzSSOTokenLoader.__call__rÕ   )rÎ   rÏ   rÐ   rÚ   re  r`  rk   rk   rk   ro   rb  ¸	  s    
rb  )Tr-  rÕ   )rD  )šrO  r¢   r?  Úloggingrq  r•  r£  r	  r.  rÅ  rç   rB  rF  Údateutil.parserrt  Údateutil.tzr   r“   Úbotocore.awsrequestÚbotocore.httpsessionÚbotocore.compatr   r   r   r   r   r   r	   r
   r   r   r   r   Úsix.moves.urllib.requestr   r   Úbotocore.exceptionsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   Úurllib3.exceptionsr'   Ú	getLoggerrÎ   rø   r.  rú   rû   r�   Ú
SAFE_CHARSrÚ  ræ  r  r  ÚEVENT_ALIASESÚIPV4_PATÚHEX_PATrÓ  ÚLS32_PATrl   Ú_variationsÚUNRESERVED_PATr²   ÚIPV6_PATÚZONE_ID_PATÚIPV6_ADDRZ_PATrÕ  Ú	frozensetrÑ  r{   r†   r�   r™   r¦   r«   r¬   r¨   r¾   rÁ   rÌ   Ú	ExceptionrÍ   rÓ   ÚobjectrÝ   r/  rJ  rQ  ra  rY  rS  rg  ra  ry  r{  r  r‹  rž  r©  r¢  r¬  r´  rØ  rÞ  rý   rã  rê  rï  rì  rò  r  r  r  r  r  r$  r*  r+  rE  ra  rb  rn  rŠ  rê  r  r&  rî   r@  rJ  rR  rM  rN  r[  r\  rb  rk   rk   rk   ro   Ú<module>   s  8`


þÿþýüûúùø	÷
öõôóòñðïîíìëêéèçæåäãâá à!ß"Þ#Ý$Ü%Û&Ú'Ù(Ø)×*Ö+Õ,Ô-Ó.Ò/Ñ0Ð1Ï2Î3Í4Ì5Ë6Ê7É8È9Ç:Æ;Å<Ä=Ã>Â?Á@ÀA¿B¾C½D¼E·N
	! &V	$-!`
ÿÿ?  !W    O{d		
