o x[h:@s.ddlZddlZddlZddlZddlZddlmZddlZddlm Z ddl m Z ddl m Z ddlmZmZmZmZmZddlmZmZddlmZdd lmZmZdd lmZdd lmZe e!Z"d d gZ#dZ$dZ%dZ&Gdddej'j(Z)ddZ*ddZ+Gdddej,Z-e-ej.ffgZ/ddZ0dS)N)urlparse)ConnectionError)HTTPConnection) PoolManager)dmi performancesources url_helperutil) EventScope EventType)NoDHCPLeaseError)EphemeralDHCPv4EphemeralIPv6Network)DataSourceHostname)ProcessExecutionErrorzhttp://169.254.42.42zhttp://[fd00:42::42] cs*eZdZdZfddZdddZZS)SourceAddressAdapterzF Adapter for requests to choose the local address to bind to. c s ||_tt|jdi|dS)N)source_addresssuperr__init__)selfrkwargs __class__rF/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceScaleway.pyr+szSourceAddressAdapter.__init__FcCs0tjtjtjdfg}t||||j|d|_dS)N) num_poolsmaxsizeblockrsocket_options)rdefault_socket_optionssocket SOL_SOCKET SO_REUSEPORTrr poolmanager)r connectionsr!r"r#rrrinit_poolmanager/s  z%SourceAddressAdapter.init_poolmanager)F)__name__ __module__ __qualname____doc__rr* __classcell__rrrrr&s rc Cs^ztj|d|d|ddd}t|jWStjy.}z |jdkr)WYd}~dSd}~ww)aQ Retrieve user data or vendor data. Scaleway user/vendor data API returns HTTP/404 if user/vendor data is not set. This function calls `url_helper.readurl` but instead of considering HTTP/404 as an error that requires a retry, it considers it as empty user/vendor data. Also, be aware the user data/vendor API requires the source port to be below 1024 to ensure the client is root (since non-root users can't bind ports below 1024). If requests raises ConnectionError (EADDRINUSE), the caller should retry to call this function on an other port. NrcSs|jdko t|jtjj S)N)code isinstancecauserequests exceptionsr)excrrrWs z%query_data_api_once..)datatimeoutretriessession exception_cbr0)r readurlr decode_binarycontentsUrlErrorr1) api_addressr9requests_sessionrespr6rrrquery_data_api_once<s  rDc Cstdt|dD]}z]td||t}d}z)t|j}|}|ddkr,|dd}tj |dtj d dd} | tj kr@d }Wn t yJYnw| d t||fd t|||d } td|| WStjy} ztd|| td| } WYd} ~ qd} ~ ww| )a/Get user or vendor data. Handle the retrying logic in case the source port is used. Scaleway metadata service requires the source port of the client to be a privileged port (<1024). This is done to ensure that only a privileged user on the system can access the metadata service. rrz*Trying to get %s data (bind on port %d)...z0.0.0.0r[N)protoz0::zhttp://)r)r9rBz%s-data downloadedz%Error while trying to get %s data: %s)rangemaxLOGdebugr4Sessionrnetlocr% getaddrinfo IPPROTO_TCPAF_INET6 ValueErrormountrrDr r@warningtimesleep) api_typerAr:r9portrB localhost url_addressaddress addr_protor8r6last_excrrrquery_data_apidsT           r^cseZdZdZejejejej hiZ fddZ de ddffdd Z d d Zd d Zed dZddZeddZeddZddZddZd ddZeddZeddZZS)!DataSourceScalewayScalewaycstt||||tt|ddgig|_t|jdt |_ t|jdt |_ t|jdt |_tj|_t|_d|_d|_d|_d|_d|_d|jvr_|j|jd7_dSdS)N datasourcer`r:r9max_waitT metadata_urls)rr_rr mergemanydictget_cfg_by_pathds_cfgintgetDEF_MD_RETRIESr:DEF_MD_TIMEOUTr9DEF_MD_MAX_WAITrbrUNSET_network_config DS_BASE_URLSrc metadata_url userdata_urlvendordata_urlephemeral_fixed_addresshas_ipv4keys)rsys_cfgdistropathsrrrrs$zDataSourceScaleway.__init__ci_pkl_versionreturnNcsFt|ddttddd}|D]}t||s t||||qdS)NT)rrrsrbrcrprq)r _unpicklerkrnhasattrsetattr)rrx attr_defaultsattrrrrrzs  zDataSourceScaleway._unpicklecCsxt}tj||j|jdd\}}|r-td||d|_|d|_ |d|_ dStd|t t|t ) zO Define metadata_url based upon api-metadata URL availability. F)urlsrbr9connect_synchronouslyz%s is reachablez/conf?format=jsonz/user_data/cloud-initz/vendor_data/cloud-initNz3Unable to reach api-metadata at %s after %s seconds) rU monotonicr wait_for_urlrbr9rKrLrorprqrgr)rr start_time avail_url_rrr_set_metadata_urls&     z$DataSourceScaleway._set_metadata_urlcCsZtj|j|j|jd}tt|j |_ t d|j |j|j|_ t d|j|j|j|_dS)N)r9r:z user-dataz vendor-data)r r=ror9r:jsonloadsr r>r?metadatar^rp userdata_rawrqvendordata_raw)rrCrrr_crawl_metadatas  z"DataSourceScaleway._crawl_metadatacCs>td}|dkr dStjdrdSt}d|vrdSdS)a  There are three ways to detect if you are on Scaleway: * check DMI data: not yet implemented by Scaleway, but the check is made to be future-proof. * the initrd created the file /var/run/scaleway. * "scaleway" is in the kernel cmdline. zsystem-manufacturerr`Tz/var/run/scalewayscalewayN)r read_dmi_dataospathexistsr get_cmdline) vendor_namecmdlinerrr ds_detects  zDataSourceScaleway.ds_detectc Csp|jrgzCt|j|jj1}td||jWdn1s#wY||d|_ d|j d<Wdn1s@wYWn t t t fyf}zttt|d|_WYd}~nd}~ww|jszAt|j|jj.td||jWdn1swY|d|j d<WdWdS1swYWdSt yYdSwdS) Nz7Setting api-metadata URL depending on IPv4 availabilityz fixed-addressipv4 net_in_useFz7Setting api-metadata URL depending on IPv6 availabilityipv6T)rsrrvfallback_interfacerTimedrrcrrrrr rrr logexcrKstrr)rrerrr _get_datas^         zDataSourceScaleway._get_datac Cs|jdurtdtjtj|_|jtjkr|jS|jdduri}i}|jdD]r}|d|jkrRd|d<ddd d }d |vrL|d |g7<q)|g|d <q)d |vrk|d |dd |df7<n|dd |df|d <|ddkr|ddd}d |vr|d |g7<q)|g|d <q)|||jj <d|d|_nBdd|jj d}ddig}|jdr|dd|jddd|jddddd|jdddgdg7}||d <d!|gd"|_t d#|j|jS)$z` Configure networking according to data received from the metadata API. Nz5Found None as cached _network_config. Resetting to %s private_ip public_ipsr[Tdhcp4z169.254.42.42/32z 62.210.0.1)zon-linktoviaroutes addresses/netmaskfamilyinet6gatewayz::/0)rrr)version ethernetsphysicalz%s)typenamerrstaticz::0)networkprefixr)rr[rrsubnetsr)rconfigznetwork_config : %s) rmrKrTrrlrrrrtrvrrL)rnetcfgip_cfgiprouterrrrnetwork_config4sr              z!DataSourceScaleway.network_configcCdSNrrrrr launch_indexzDataSourceScaleway.launch_indexcCs |jdS)Nid)rrrrrget_instance_ids z"DataSourceScaleway.get_instance_idcCs^dd|jdD}d}t|}|jdgD]}||sq|||dddq|S)NcSsg|]}|dqS)keyr).0rrrr sz:DataSourceScaleway.get_public_ssh_keys..ssh_public_keyszAUTHORIZED_KEY=tagsr )rlenrh startswithappendreplace)rssh_keysakeypreplentagrrrget_public_ssh_keyss z&DataSourceScaleway.get_public_ssh_keysFcCst|jddS)NhostnameF)rr)rfqdn resolve_ip metadata_onlyrrr get_hostnameszDataSourceScaleway.get_hostnamecCrrrrrrravailability_zonerz$DataSourceScaleway.availability_zonecCrrrrrrrregionrzDataSourceScaleway.region)FFF)r+r,r-dsnamer NETWORKr BOOT_NEW_INSTANCEBOOT BOOT_LEGACYdefault_update_eventsrrgrzrr staticmethodrrpropertyrrrrrrrr/rrrrr_s4  2 O   r_cCs t|tSr)rlist_from_depends datasources)dependsrrrget_datasource_lists r)1rloggingrr%rU urllib.parserr4requests.exceptionsrurllib3.connectionrurllib3.poolmanagerr cloudinitrrrr r cloudinit.eventr r cloudinit.net.dhcpr cloudinit.net.ephemeralrrcloudinit.sourcesrcloudinit.subpr getLoggerr+rKrnrirkrjadapters HTTPAdapterrrDr^ DataSourcer_DEP_FILESYSTEMrrrrrrs<        (4