B w\I@sfddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddlmZmZddlZddlZddlZddlmZmZmZmZmZddlmZmZmZddlmZmZddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)e*e+Z,dZ-dZ.d Z/e0d Z1e'e&e(e)fZ2d gZ3d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d(d+d,d-d.d/ddd d0d1d2d3d4d5d6d-d7d8d8d9d3d:d;dd?d4d@dAdBdCdDdEdEdFd%d=dGHZ4dHdIZ5dJdKZ6dLdMZ7dNdOZ8dPdQZ9dRdSZ:ddUdVZ;GdWdXdXe<Z=GdYdZdZe>Z?Gd[d\d\e?Z@dd^d_ZAd`daZBeCfdbdcZDdddeZEe/fdfdgZFe/fdhdiZGdjdkZHdldmZIddndoZJddpdqZKdrdsZLdtduZMGdvdwdwe>ZNGdxdydye>ZOdzd{ZPd|d}ZQdd~dZRdddZSddZTddZUddZVddZWdddZXdddZYddZZddZ[Gddde>Z\Gddde>Z]ddZ^ddZ_dddZ`dS)N)tzlocaltzutc)jsonquote zip_longesturlsplit urlunsplit) OrderedDictsixurlparse) getproxies proxy_bypass) InvalidExpressionErrorConfigNotFoundInvalidDNSNameError ClientErrorMetadataRetrievalErrorEndpointConnectionErrorReadTimeoutErrorConnectionClosedErrorConnectTimeoutErrorzhttp://169.254.169.254/z-._~z-z0-9][a-z0-9\-]*[a-z0-9]Z dualstackzalexa-for-businessZ mediatailorZpricingZ sagemakerz api-gatewayzapplication-auto-scalingZ appstreamz auto-scalingzauto-scaling-plansz cost-explorerz cloudhsm-v2zcloudsearch-domainzcognito-identity-providerzconfig-servicezcost-and-usage-report-serviceziot-data-planeziot-jobs-data-planezmediastore-dataz data-pipelinez device-farmziot-1click-devices-servicezdirect-connectzapplication-discovery-servicezdatabase-migration-servicezdirectory-servicezdynamodb-streamszelastic-beanstalkZefszelastic-load-balancingZemrzelastic-transcoderzelastic-load-balancing-v2Zseszmarketplace-entitlement-servicezelasticsearch-servicezcloudwatch-eventsziot-1click-projectszkinesis-analyticsz kinesis-videozlex-model-building-servicezlex-runtime-servicezcloudwatch-logszmachine-learningzmarketplace-commerce-analyticszmarketplace-meteringz migration-hubZ cloudwatchZmturkZ opsworkscmzresource-groups-tagging-apizroute-53zroute-53-domainszsagemaker-runtimeZsimpledbzsecrets-managerZserverlessapplicationrepositoryzservice-catalogsfnzstorage-gateway)HZa4bZalexaforbusinesszapi.mediatailorz api.pricingz api.sagemakerZ apigatewayzapplication-autoscalingZ appstream2Z autoscalingzautoscaling-plansZceZ cloudhsmv2Zcloudsearchdomainz cognito-idpconfigcurzdata.iotz data.jobs.iotzdata.mediastoreZ datapipelineZ devicefarmzdevices.iot1clickZ directconnectZ discoveryZdmsZdsZdynamodbstreamsZelasticbeanstalkZelasticfilesystemZelasticloadbalancingZelasticmapreduceZelastictranscoderZelbZelbv2emailzentitlement.marketplaceeseventsziot-dataz iot-jobs-dataziot1click-devicesziot1click-projectsZkinesisanalyticsZ kinesisvideoz lex-modelsz lex-runtimeZlogsZmachinelearningzmarketplace-entitlementZmarketplacecommerceanalyticszmetering.marketplaceZmeteringmarketplaceZmghz models.lexZ monitoringzmturk-requesterz opsworks-cmzprojects.iot1clickZresourcegroupstaggingapiZroute53Zroute53domainsz runtime.lexzruntime.sagemakerZsdbZsecretsmanagerZserverlessrepoZservicecatalogZstatesZ stepfunctionsZstoragegatewayzstreams.dynamodbZtaggingcCst|tr|S|dkSdS)z~Ensures a boolean value if a string or boolean is provided For strings, the value for True/False is case insensitive trueN) isinstanceboollower)valr#h/private/var/folders/j5/hv2kzfgs4sl6jnf70fy_2vrc4p3c_b/T/pip-install-d8kq1y21/botocore/botocore/utils.pyensure_booleans r%cCs2t|do0|jddo0|jddko0|jdkS)zDetermines 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 serializationZ jsonvalueFlocationheaderstring)hasattrr&get type_name)shaper#r#r$is_json_value_headers r.cCsD|jd|jd|j}|dd}|dd}tdd|}|S)zvReturns the module name for a service This is the value used in both the documentation and client class name ZserviceAbbreviationZserviceFullNameZAmazonZAWSz\W+)metadatar+Z service_namereplaceresub)Z service_modelnamer#r#r$get_service_module_names   r5cCs|sdSt|S)N/)remove_dot_segments)pathr#r#r$normalize_url_pathsr9cCs|sdS|d}g}x8|D]0}|r|dkr|dkrB|rL|q||qW|ddkrbd}nd}|ddkr||r|d}nd}|d||S)Nr/r6.z..r)splitpopappendjoin)urlZ input_urlZ output_listxfirstlastr#r#r$r7s"     r7cCs:|r |dkrt|dxdD]}||krt|dqWdS)Nr:) expression)[]*)r)rDinvalidr#r#r$validate_jmespath_for_sets    rITcCs||r t||dd}|dt|dkr2|dnd}}|sHt|d|rp||kr\i||<t||||ddS|||<dS)Nr:rrr/)rDF)is_first)rIr<lenrset_value_from_jmespath)sourcerDvaluerJbits current_key remainderr#r#r$rLs " rLc@seZdZdZdS)_RetriesExceededErrorz@Internal exception used when the number of retries are exceeded.N)__name__ __module__ __qualname____doc__r#r#r#r$rRsrRc@sNeZdZeZededdfddZddZddZ d d Z d d Z dddZ dS) IMDSFetcherrNcCsf||_||_||_|dkr$tj}|dd|_|jdk|_||_ t j j |jt |jd|_dS)NZAWS_EC2_METADATA_DISABLEDfalser)timeoutproxies)_timeout _num_attempts _base_urlosenvironcopyr+r! _disabled _user_agentbotocore httpsessionURLLib3Sessionget_environ_proxies_session)selfrYZ num_attemptsbase_urlenv user_agentr#r#r$__init__s  zIMDSFetcher.__init__c Cs|jrtd||dkr&|j}|j|}i}|jdk rH|j|d<xzt|jD]l}y2t j j d||d}|j |}||s|SWqTtk r}ztjd||ddWdd}~XYqTXqTW|dS) aMake 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 taht 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. z)Access to EC2 metadata has been disabled.Nz User-AgentGET)methodr@headerszOCaught retryable HTTP exception while making metadata service request to %s: %sT)exc_info)raloggerdebug_RETRIES_EXCEEDED_ERROR_CLS_default_retryr]rbranger\rc awsrequest AWSRequestrgsendprepareRETRYABLE_HTTP_ERRORS) rhurl_path retry_funcr@roirequestresponseer#r#r$ _get_requests*      "zIMDSFetcher._get_requestcCs||p||S)N)_is_non_ok_response _is_empty)rhrr#r#r$rt8s zIMDSFetcher._default_retrycCs"|jdkr|j|ddddSdS)Nznon-200T)log_bodyF) status_code_log_imds_response)rhrr#r#r$r>s zIMDSFetcher._is_non_ok_responsecCs|js|j|ddddSdS)Nzno bodyT)rF)contentr)rhrr#r#r$rDszIMDSFetcher._is_emptyFcCs>d}||j|jg}|r*|d7}||jtj|f|dS)NzHMetadata service returned %s response with status code of %s for url: %sz, content body: %s)rr@r>rrqrr)rhrZ reason_to_logrZ statementZ logger_argsr#r#r$rJs  zIMDSFetcher._log_imds_response)F) rSrTrUrRrs DEFAULT_METADATA_SERVICE_TIMEOUTMETADATA_BASE_URLrlrrtrrrr#r#r#r$rWs$rWc@sTeZdZdZddddgZddZdd Zd d Zd d ZddZ ddZ ddZ dS)InstanceMetadataFetcherz*latest/meta-data/iam/security-credentials/ AccessKeyIdSecretAccessKeyToken ExpirationcCsy`|}||}||r>||d|d|d|ddSd|krZd|krZtd|iSWn$|jk rtd |jYnXiS) Nrrrr) role_nameZ access_keyZ secret_keytokenZ expiry_timeCodeMessagez7Error response received when retrievingcredentials: %s.z\Max number of attempts exceeded (%s) when attempting to retrieve data from metadata service.) _get_iam_role_get_credentials_contains_all_credential_fieldsrqrrrsr\)rhr credentialsr#r#r$retrieve_iam_role_credentials^s"   z5InstanceMetadataFetcher.retrieve_iam_role_credentialscCs|j|j|jdjS)N)r{r|)r _URL_PATH_needs_retry_for_role_nametext)rhr#r#r$r}sz%InstanceMetadataFetcher._get_iam_rolecCs"|j|j||jd}t|jS)N)r{r|)rr_needs_retry_for_credentialsrloadsr)rhrrr#r#r$rs z(InstanceMetadataFetcher._get_credentialscCs6yt|jdStk r0||ddSXdS)NFz invalid jsonT)rrr ValueErrorr)rhrr#r#r$_is_invalid_jsons   z(InstanceMetadataFetcher._is_invalid_jsoncCs||p||S)N)rr)rhrr#r#r$rs z2InstanceMetadataFetcher._needs_retry_for_role_namecCs||p||p||S)N)rrr)rhrr#r#r$rs  z4InstanceMetadataFetcher._needs_retry_for_credentialscCs,x&|jD]}||krtd|dSqWdS)Nz3Retrieved credentials is missing required field: %sFT)_REQUIRED_CREDENTIAL_FIELDSrqrr)rhrfieldr#r#r$rs z7InstanceMetadataFetcher._contains_all_credential_fieldsN) rSrTrUrrrrrrrrrr#r#r#r$rXs rFcCsx|D]}t||trJ||kr<||krpercent_encoder?)mappingsafeZ encoded_pairspairsrrNelementr#r#r$percent_encode_sequences      rcCs>t|tjtjfst|}t|tjs2|d}t||dS)aUrlencodes 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. zutf-8)r)rr binary_type text_typeencoder)Z input_strrr#r#r$r s    rc Cst|ttfrtj|tSytjt|tSttfk rJYnXytj j |dt idSttfk r}ztd||fWdd}~XYnXdS)zParse a timestamp into a datetime object. Supported formats: * iso8601 * rfc822 * epoch (value is an integer) This will return a ``datetime.datetime`` object. GMT)ZtzinfoszInvalid timestamp "%s": %sN) rintfloatdatetime fromtimestampr TypeErrorrdateutilparserparser)rNrr#r#r$parse_timestamps rcCsDt|tjr|}nt|}|jdkr4|jtd}n |t}|S)aConverted 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)tzinfo)rrrrr1r astimezone)rNZ datetime_objr#r#r$parse_to_aware_datetime<s   rcCs~tddd}|jdkr2|dkr&t}|j|d}|jdd||}t|dr\|S|j|j|j ddddS) awCalculate 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 irN)r total_secondsii@B) rrrr1 utcoffsetr*r microsecondssecondsdays)dtZdefault_timezoneepochdr#r#r$datetime2timestampis    rcsFt}x$tfdddD]}||qW|r:|S|SdS)aCalculate 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 cs dS)Ni)rr#)bodyr#r$sz"calculate_sha256..N)hashlibsha256iterupdate hexdigestdigest)rZas_hexZchecksumchunkr#)rr$calculate_sha256~s rcsg}dtj}x.tfdddD]}|||q$W|sN|dSxXt|dkrg}x>t|D]2\}}|dk r||||qj||qjW|}qPWt |d dS) 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 ics S)N)rr#)rrequired_chunk_sizer#r$rsz%calculate_tree_hash..rrNrascii) rrrr>rrrK _in_pairsbinasciihexlifydecode)rchunksrrZ new_chunksrBsecondr#)rrr$calculate_tree_hashs rcCst|}t||S)N)rr)iterableZ shared_iterr#r#r$rs rc@s eZdZdZddZddZdS)CachedPropertyzA 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. cCs ||_dS)N)_fget)rhfgetr#r#r$rlszCachedProperty.__init__cCs,|dkr |S||}||j|jj<|SdS)N)r__dict__rS)rhobjclsZcomputed_valuer#r#r$__get__s  zCachedProperty.__get__N)rSrTrUrVrlrr#r#r#r$rsrc@sDeZdZdZdddZddZddd Zd d Zd d ZddZ dS)ArgumentGeneratoraGenerate 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) FcCs ||_dS)N)_use_member_names)rhZuse_member_namesr#r#r$rlszArgumentGenerator.__init__cCsg}|||S)zGenerate 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)rhr-stackr#r#r$generate_skeletons z#ArgumentGenerator.generate_skeletonr/cCs||jz|jdkr$|||S|jdkr:|||S|jdkrP|||S|jdkrz|jrd|S|jrvt |jSdS|jdkrdS|jdkrd S|jd krd S|jd krt d dddddSWd| XdS)NZ structurermapr)r/)integerlongrrgbooleanT timestampir) r>r4r,_generate_type_structure_generate_type_list_generate_type_maprenumrandomchoicerr=)rhr-rr4r#r#r$r s.             z$ArgumentGenerator._generate_skeletoncCsJ||jdkriSt}x*|jD]\}}|j|||d||<q&W|S)Nr)r4)countr4r membersrr)rhr-rZskeleton member_nameZ member_shaper#r#r$r#sz*ArgumentGenerator._generate_type_structurecCs$d}|jr|jj}||j||gS)Nr/)rmemberr4r)rhr-rr4r#r#r$r,sz%ArgumentGenerator._generate_type_listcCs0|j}|j}|jdksttd|||fgS)Nr)ZKeyName)rrNr,AssertionErrorr r)rhr-rZ key_shapeZ value_shaper#r#r$r6s z$ArgumentGenerator._generate_type_mapN)F)r/) rSrTrUrVrlrrrrrr#r#r#r$rs    rcCsZt|}|j}|dkrdSt|dkr*dS|ddkrB|dd}tdtj}||S)zVerify 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. NFr;r:z;^((?!-)[A-Z\d-]{1,63}(?|S|f||}||j|<|S)N)tuplesortedrZ_instance_cacher+)rhargsr cache_keyZ kwarg_itemsresult)func func_namer#r$ _cache_guards   z$instance_cache.._cache_guard)rS functoolswraps)r/r1r#)r/r0r$instance_caches r4cKsht|jjd}dd|D}d}t|dkrB|d|d7}|d7}|dkrVdSt||d d dS) z?Switches the current s3 endpoint with an S3 Accelerate endpointr:cSsg|]}|tkr|qSr#)S3_ACCELERATE_WHITELIST).0pr#r#r$ sz-switch_host_s3_accelerate..zhttps://s3-accelerate.rz amazonaws.com)Z ListBucketsZ CreateBucketZ DeleteBucketNF)use_new_scheme)rr@r#r<rKr? _switch_hosts)r~Zoperation_namerrendpointr#r#r$switch_host_s3_accelerates r<cCs2t|jd}||r.||}t||dS)zBSwitches the host using a parameter value from a JSON request bodyzutf-8N)rrdatarr+r:)r~ param_nameZ request_json new_endpointr#r#r$switch_host_with_params r@cCst|j||}||_dS)N)_get_new_endpointr@)r~r?r9final_endpointr#r#r$r:s r:cCsRt|}t|}|j}|r |j}||j|j|jdf}t|}td||f|S)Nr/zUpdating URI from %s to %s)rr%r#r8r&rrqrr)Zoriginal_endpointr?r9Znew_endpoint_componentsZoriginal_endpoint_componentsr%Zfinal_endpoint_componentsrBr#r#r$rA s rAcCsVxP|D]H}||krBt||trBt||trBt||||q||||<qWdS)zDeeply 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)rr deep_merge)baseextrarr#r#r$rCs  rCcCs|ddS)zcTranslate the form used for event emitters. :param service_id: The service_id to convert.  -)r1r!)Z service_idr#r#r$hyphenize_service_id0srHc@s@eZdZdddZdddZddZdd Zd d Zd d ZdS)S3RegionRedirectorNcCs,||_||_|jdkri|_t||_dS)N)_endpoint_resolver_cacheweakrefproxy_client)rhZendpoint_bridgeclientcacher#r#r$rl9s  zS3RegionRedirector.__init__cCs<|p |jjj}|d|j|d|j|d|jdS)Nzneeds-retry.s3zbefore-call.s3zbefore-parameter-build.s3)rNmetarregisterredirect_from_errorset_request_urlredirect_from_cache)rhZ event_emitterZemitterr#r#r$rRCs zS3RegionRedirector.registercKs|dkr dS|didr,tddS|ddi}|d}|ddi}|d kof|jd k}|d ko|jd kod |d ik} |dkod|k} |ddk o|djdk} |dk} t|| | | | gsdS|ddd} |dd}|| |}|dkrtd|| fdStd|| |f|jd|}|d}|| |d}||dd<||j | <| ||dd|dd<dS)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. NrZ s3_redirectedz6S3 request was previously redirected, not redirecting.rErrorrResponseMetadata)Z301Z400Z HeadObjectZ HeadBucketzx-amz-bucket-region HTTPHeadersZAuthorizationHeaderMalformedRegionr)i-i.i3ZPermanentRedirectsigningbucket client_regionzS3 client configured for region %s but the bucket %s is not in that region and the proper region could not be automatically determined.zS3 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.Zs3r)regionr[r;T) r+rqrrr4ranyget_bucket_regionrJresolverKrT)rhZ request_dictrZ operationrerrorZ error_codeZresponse_metadataZis_special_head_objectZis_special_head_bucketZis_wrong_signing_regionZis_redirect_statusis_permanent_redirectr[r\Z new_regionr;signing_contextr#r#r$rSJsX          z&S3RegionRedirector.redirect_from_errorc Cs|d}|dd}d|kr$|dS|didd}|dk rD|Sy|jj|d}|dd}Wn0tk r}z|jdd}Wdd}~XYnX|dd}|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. rrWrXzx-amz-bucket-regionrVrYN)Bucket)r+rNZ head_bucketrr)rhr[rZservice_responseresponse_headersr]rorr#r#r$r_s    z$S3RegionRedirector.get_bucket_regioncKs4|didd}|dk r0t|d|d|d<dS)NrZr;r@F)r+rA)rhparamsrrr;r#r#r$rTsz"S3RegionRedirector.set_request_urlcKs8|d}|j|}|dk r(||d<n d|i|d<dS)z This handler retrieves a given bucket's signing context from the cache and adds it into the request context. rdNrZr[)r+rK)rhrfrrr[rcr#r#r$rUs    z&S3RegionRedirector.redirect_from_cache)N)N) rSrTrUrlrRrSr_rTrUr#r#r#r$rI8s  P!rIc@sreZdZdZdZdZdZeddgZdej fdd Z dd d Z d d Z ddZ ddZdddZddZddZdS)ContainerMetadataFetcherr!rrz 169.254.170.2 localhostz 127.0.0.1NcCs(|dkrtjj|jd}||_||_dS)N)rY)rcrdreTIMEOUT_SECONDSrg_sleep)rhsessionsleepr#r#r$rls  z!ContainerMetadataFetcher.__init__cCs|||||S)zRetrieve 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)rhfull_urlror#r#r$retrieve_full_uris z*ContainerMetadataFetcher.retrieve_full_uricCs:tj|}||j}|s6td|jd|jfdS)NzGUnsupported host '%s'. Can only retrieve metadata from these hosts: %sz, )rccompatr _check_if_whitelisted_hostr rr?_ALLOWED_HOSTS)rhroparsedZis_whitelisted_hostr#r#r$rms z.ContainerMetadataFetcher._validate_allowed_urlcCs||jkrdSdS)NTF)rs)rhr(r#r#r$rrs z3ContainerMetadataFetcher._check_if_whitelisted_hostcCs||}||S)zRetrieve 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. )rorn)rh relative_uriror#r#r$ retrieve_uris z%ContainerMetadataFetcher.retrieve_uric Csddi}|dk r||d}xhy||||jStk r}z4tjd|dd||j|d7}||jkrrWdd}~XYq Xq WdS)NAcceptzapplication/jsonrzAReceived error when attempting to retrieve container metadata: %sT)rpr) r _get_responserirrqrrrj SLEEP_TIMERETRY_ATTEMPTS)rhro extra_headersroattemptsrr#r#r$rns     z.ContainerMetadataFetcher._retrieve_credentialsc Csytjj}|d||d}|j|}|jd}|jdkrRt d|j|fdy t |St k r~t d|dYnXWn4t k r}zd|} t | dWdd}~XYnXdS) Nrm)rnr@rozutf-8rz4Received non 200 response (%s) from ECS metadata: %s) error_msgz3Unable to parse JSON returned from ECS metadata: %sz;Received error when attempting to retrieve ECS metadata: %s)rcrvrwrgrxryrrrrrrrrz) rhrororYrwr~rZ response_textrr}r#r#r$rxs&   z&ContainerMetadataFetcher._get_responsecCsd|j|fS)Nz http://%s%s) IP_ADDRESS)rhrur#r#r$ro+sz!ContainerMetadataFetcher.full_url)N)N)rSrTrUrirzryr~rstimerlrlrprmrrrvrnrxror#r#r#r$rgs    rgcCst|r iStSdS)N)should_bypass_proxiesr )r@r#r#r$rf/srfc Cs6ytt|jrdSWnttjfk r0YnXdS)z: Returns whether we should bypass proxies or not. TF)r r r#rsocketgaierror)r@r#r#r$r6s r ISO-8859-1cCsF|d}|sdSt|\}}d|kr6|ddSd|krB|SdS)zReturns 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-typeNcharsetz'"r)r+cgi parse_headerr)rodefault content_typerfr#r#r$get_encoding_from_headersKs r)T)F)N)F)N)N)T)T)r)ar2rloggingrrrr2rLrr^rrZdateutil.parserrZ dateutil.tzrrrcZbotocore.awsrequestZbotocore.httpsessionZbotocore.compatrrrrrr r r Z*botocore.vendored.six.moves.urllib.requestr r Zbotocore.exceptionsrrrrrrrrr getLoggerrSrqrrZ SAFE_CHARSr rrzr5Z EVENT_ALIASESr%r.r5r9r7rIrL ExceptionrRobjectrWrrropenrrrrrrrrrrrrrrr rr"r4r<r@r:rArCrHrIrgrfrrr#r#r#r$ s,    !XQ   $ -  !`  >   b