o x[h<@sddlZddlZddlmZmZddlmZmZddlmZ ddlm Z ddl m Z m Z ddlmZddlmZdd lmZdd lmZmZeeZd ZGd d d ejZddZddZGdddeZeej ffeej ej!ffgZ"ddZ#dS)N)ListUnion)dmisources) url_helper)util) EventScope EventType)NoDHCPLeaseError)EphemeralIPNetwork)DataSourceHostname)aliyunec2zAlibaba Cloud ECScsDeZdZUdZdgZdZgZeee d<dZ dZ dZ e jZeeefe d<d Zed d Zfd d Zdeddffdd Zd;ddZddZddZeddZeddZeddZeddZed d!Zed"d#Z d$d%Z!d&d'Z"d(d)Z#d*d+Z$d,d-Z%d.d/Z&d0d1Z'd2d3Z(dDataSourceAliYunAliYunzhttp://100.100.100.200z 2016-01-01extended_metadata_versions2N_network_configFcCdS)NzX-aliyun-ecs-metadata-tokenselfrrD/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceAliYun.pyimdsv2_token_put_header+z(DataSourceAliYun.imdsv2_token_put_headercs:tt||||t|j|_|jtjt j dSN) superr__init__copydeepcopydefault_update_eventsrNETWORKaddr BOOT)rsys_cfgdistropaths __class__rrr/szDataSourceAliYun.__init__ci_pkl_versionreturncst|dSr)r _unpickle)rr*r(rrr,4szDataSourceAliYun._unpicklecCs*|jd}d}|durd}d}t||S)NhostnameFzlocalhost.localdomainT)metadatagetr )rfqdn resolve_ip metadata_onlyr- is_defaultrrr get_hostname7s  zDataSourceAliYun.get_hostnamecCst|jdiS)Nz public-keys)parse_public_keysr.r/rrrrget_public_ssh_keys?sz$DataSourceAliYun.get_public_ssh_keyscCstr|jSdS)NNO_ALIYUN_METADATA) _is_aliyundsnamelowerrrrr_get_cloud_nameBs z DataSourceAliYun._get_cloud_namecCs |jSr)r9r:rrrrplatformG zDataSourceAliYun.platformcCr)Nzlatest/api/tokenrrrrrapi_token_routeLrz DataSourceAliYun.api_token_routecCr)N21600rrrrrimdsv2_token_ttl_secondsPrz)DataSourceAliYun.imdsv2_token_ttl_secondscCs |j|jgSr)rimdsv2_token_req_headerrrrrimdsv2_token_redactTs z$DataSourceAliYun.imdsv2_token_redactcCs |jdS)Nz -ttl-seconds)rrrrrrAXr=z(DataSourceAliYun.imdsv2_token_req_headercCsn|jtjkr |jSi}|jj}|jd}t|tr)t j ||t |j ddd}ntd||S||_|jS)z@Return a network config dict for rendering ENI or netplan files.networkapply_full_imds_network_configT) fallback_nicfull_network_configz%Metadata 'network' key not valid: %s.)rrUNSETr&fallback_interfacer.r/ isinstancedictr #convert_ecs_metadata_network_configrget_cfg_option_boolds_cfgLOGwarning)rresultifacenet_mdrrrnetwork_config\s"    zDataSourceAliYun.network_configc Csg}i}|j}d}|D]}d||}|||||<q tdd}d}|} ztj|| j| j tj |j |j ||j dd \}}Wn tjyLYnw|rX|rX||_||SdS)a=Get an API token for ECS Instance Metadata Service. On ECS. IMDS will always answer an API token, set HttpTokens=optional (default) when create instance will not forcefully use the security-enhanced mode (IMDSv2). https://api.alibabacloud.com/api/Ecs/2014-05-26/RunInstances PUTz{0}/{1}zFetching Ecs IMDSv2 API TokenNF) urlsmax_waittimeout status_cb headers_cb exception_cbrequest_methodheaders_redactconnect_synchronously)r>formatappendrNdebugget_url_paramsuhelp wait_for_urlmax_wait_secondstimeout_secondsrO _get_headers_imds_exception_cbrBUrlError _api_token) rmdurlsrUurl2baseurl_pathr[urlcurresponse url_paramsrrr_maybe_fetch_api_tokenss>      z'DataSourceAliYun._maybe_fetch_api_tokencCsP|j}|d|j}||}|r||_td|jt|Stdt|S)N metadata_urlszUsing metadata source: '%s'z)IMDS's HTTP endpoint is probably disabled) rMr/rrrqmetadata_addressrNr`rObool)rmcfgrjrsrrrwait_for_metadata_services  z*DataSourceAliYun.wait_for_metadata_servicec Cs|siS|j}i}|j}|j}d}|j}zYtj|j|j|j ||dd|d<tj|j|j|j ||dd|d<ztj |j|j|j ||d}||d<WW|St yot td|jtj|j|j|j |||d|d<YW|Swt yt td |jiYSw) zCrawl metadata service when available. @returns: Dictionary of crawled metadata content containing the keys: meta-data, user-data, vendor-data and dynamic. N user-data)rYr\rZ item_name vendor-data)rYr\rZ meta-dataz@Faild read json meta-data from %s fall back directory tree style)rYr\rZretrieval_exception_ignore_cbz'Failed reading from metadata address %s)rvrB_refresh_stale_aliyun_token_cb&_skip_or_refresh_stale_aliyun_token_cb#_skip_json_path_meta_path_aliyun_cbr get_instance_datamin_metadata_versionrsrfget_instance_meta_data ExceptionrlogexcrNrget_instance_metadata)rredactcrawled_metadataexc_cb exc_cb_udskip_cbexe_cb_whole_metarPrrrcrawl_metadatasv     zDataSourceAliYun.crawl_metadatacCs*t|tjr|jdkrtdd|_dS)z=Exception handler for Ecs to refresh token if token is stale.iz+Clearing cached Ecs API token due to expiryNT)rIrbrhcoderNr`rirmsg exceptionrrrr|s z/DataSourceAliYun._refresh_stale_aliyun_token_cbcCs |j|vS)z/Returns False if cause.code is in status_codes.)r)r status_codescauserrr_skip_retry_on_codesr=z%DataSourceAliYun._skip_retry_on_codescCs"|tj|}|s dS|||S)z^Callback will not retry on SKIP_USERDATA_VENDORDATA_CODES or if no token is available.F)rrSKIP_USERDATA_CODESr|)rrrretryrrrr}s z7DataSourceAliYun._skip_or_refresh_stale_aliyun_token_cbcCs0t|tjr|jdkrtddS|||S)z7Callback will not retry of whole meta_path is not foundiz&whole meta_path is not found, skippingF)rIrbrhrrNrOr|rrrrr~s  z4DataSourceAliYun._skip_json_path_meta_path_aliyun_cbcCs|j|jkr dS|jrTtrtddSz1t|j |j j ddd}| |_ td|j r6d|j ndWdn1sCwYWntySYdSw| |_ |j rbt|j tsddS|j di|_|j d i|_|j d i|_dS) NFz1FreeBSD doesn't support running dhclient with -sfT)ipv4ipv6zCrawled metadata service%s rzrwry) cloud_namer9r:perform_dhcp_setupr is_FreeBSDrNr`r r&rHr_crawled_metadata state_msgr rIrJr/r. userdata_rawvendordata_raw)rnetwrrr _get_datasB    zDataSourceAliYun._get_datac Cs|dur|j}td|j|i}d|j|j}ztj|||j dd}W|j Stj yB}zt d||WYd}~dSd}~ww)zRequest new metadata API token. @param seconds: The lifetime of the token in seconds @return: The API token or None if unavailable. Nz!Refreshing Ecs metadata API tokenz{}/{}rT)headersr\r[z/Unable to get API token: %s raised exception %s) r@rNr`rAr^rsr>rbreadurlrBrhrOcontents)rsecondsrequest_header token_urlroerrr_refresh_api_token/s(   z#DataSourceAliYun._refresh_api_tokenrcCs@|j|ji}|j|vr |S|js||_|jsiS|j|jiS)zReturn a dict of headers for accessing a url. If _api_token is unset on AWS, attempt to refresh the token via a PUT and then return the updated token header. )rAr@r>rirr)rrmrequest_token_headerrrrrfJs   zDataSourceAliYun._get_headerscCsFt|tjr!|jr!|jdkr!|jdkrtd|td|dS)a2Fail quickly on proper AWS if IMDSv2 rejects API token request Guidance from Amazon is that if IMDSv2 had disabled token requests by returning a 403, or cloud-init malformed requests resulting in other 40X errors, we want the datasource detection to fail quickly without retries as those symptoms will likely not be resolved by retries. Exceptions such as requests.ConnectionError due to IMDS being temporarily unroutable or unavailable will still retry due to the callsite wait_for_url. iizLEcs IMDS endpoint returned a 403 error. HTTP endpoint is disabled. Aborting.z2Fatal error while requesting Ecs IMDSv2 API tokensT)rIrbrhrrNrO)rrrrrrg_s  z#DataSourceAliYun._imds_exception_cb)FFFr)r)-__name__ __module__ __qualname__r9rrrrrstr__annotations__ url_max_wait url_timeoutrirrGrrrJrpropertyrrintr,r4r6r;r<r>r@rBrArSrqrvrr|rr}r~rrrfrg __classcell__rrr(rrsP          2@ ! rcCstdtkS)Nzsystem-product-name)r read_dmi_dataALIYUN_PRODUCTrrrrr8|sr8cCsg}|D]>\}}t|tr||qt|tr"||qt|trD|dg}t|tr:||qt|trD||q|S)Nz openssh-key) itemsrIrr_striplistextendrJr/) public_keyskeys_key_idkey_bodykeyrrrr5s        r5c@seZdZdZdZdS)DataSourceAliYunLocalayDatasource run at init-local which sets up network to query metadata. In init-local, no network is available. This subclass sets up minimal networking with dhclient on a viable nic so that it can talk to the metadata service. If the metadata service provides network configuration then render the network configuration for that instance based on metadata. TN)rrr__doc__rrrrrrsrcCs t|tSr)rlist_from_depends datasources)dependsrrrget_datasource_lists r)$rloggingtypingrr cloudinitrrrrbrcloudinit.eventrr cloudinit.net.dhcpr cloudinit.net.ephemeralr cloudinit.sourcesr cloudinit.sources.helpersr r getLoggerrrNr DataSourcerr8r5rDEP_FILESYSTEM DEP_NETWORKrrrrrrs.      i