3 \me=@s.ddlZddlZddlZddlZddlZddlmZddlZddlm Z ddl m Z ddl m Z ddlmZmZmZmZmZddlmZmZddlmZdd lmZmZdd lmZdd lmZej e!Z"d d gZ#dZ$dZ%dZ&Gdddej'j(Z)ddZ*ddZ+Gdddej,Z-e-ej.ffgZ/ddZ0dS)N)urlparse)ConnectionError)HTTPConnection) PoolManager)dminetsources 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|jf|dS)N)source_addresssuperr__init__)selfrkwargs) __class__(/usr/lib/python3.6/DataSourceScaleway.pyr+szSourceAddressAdapter.__init__FcCs0tjtjtjdfg}t||||j|d|_dS)N)Z num_poolsmaxsizeblockrsocket_options)rZdefault_socket_optionssocketZ SOL_SOCKETZ SO_REUSEPORTrrZ poolmanager)rZ connectionsrr r!rrrinit_poolmanager/sz%SourceAddressAdapter.init_poolmanager)F)__name__ __module__ __qualname____doc__rr# __classcell__rr)rrr&s rcCs`y&tj|d|d|ddd}tj|jStjk rZ}z|jdkrHdSWYdd}~XnXdS)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|jdkot|jtjj S)Ni)code isinstancecauserequests exceptionsr)_excrrrWs z%query_data_api_once..)datatimeoutretriesZsessionZ exception_cbi)r readurlr decode_binarycontentsUrlErrorr)) api_addressr2requests_sessionrespr/rrrquery_data_api_once<s   r;c Cs"xtdt|dD]}ytjd||tj}d}yRt|j}|}|ddkr^|dd}tj |dtj ddd} | tj krd }Wnt k rYnX|j d t||fd t|||d } tjd || Stjk r} z$tjd|| tjd| } wWYdd} ~ XqXqW| dS)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)r2r9z%s-data downloadedz%Error while trying to get %s data: %s)rangemaxLOGdebugr,ZSessionrnetlocr" getaddrinfo IPPROTO_TCPAF_INET6 ValueErrorZmountrr;r r7warningtimeZsleep) Zapi_typer8r3r2Zportr9Z localhostZ url_addressaddress addr_protor1r/last_excrrrquery_data_apids>           rNcseZdZdZejejejej hiZ fddZ ddZ ddZ edd Zd d Zd d ZeddZeddZddZddZdddZeddZeddZZS)DataSourceScalewayScalewaycstt|j|||tjtj|ddgig|_t|jjdt |_ t|jjdt |_ t|jjdt |_d|_tj|_t|_d|_d|_d|_d|_d|jjkr|j|jd7_dS)NZ datasourcerPr3r2max_waitT metadata_urls)rrOrr Z mergemanydictZget_cfg_by_pathZds_cfgintgetDEF_MD_RETRIESr3DEF_MD_TIMEOUTr2DEF_MD_MAX_WAITrQ_fallback_interfacerUNSET_network_config DS_BASE_URLSrR userdata_urlvendordata_urlephemeral_fixed_addresshas_ipv4keys)rZsys_cfgdistropaths)rrrrszDataSourceScaleway.__init__cCs|tj}tj||j|jdd\}}|rZtjd||d|_|d|_|d|_ dStjd|t tj|t dS) zO Define metadata_url based upon api-metadata URL availability. F)urlsrQr2Zconnect_synchronouslyz%s is reachablez/conf?format=jsonz/user_data/cloud-initz/vendor_data/cloud-initNz3Unable to reach api-metadata at %s after %s seconds) rJr Z wait_for_urlrQr2rBrC metadata_urlr\r]rSr)rrcZ start_timeZ avail_urlr.rrr_set_metadata_urls"     z$DataSourceScaleway._set_metadata_urlcCsZtj|j|j|jd}tjtj|j |_ t d|j |j|j|_ t d|j|j|j|_dS)N)r2r3z user-dataz vendor-data)r r4rdr2r3jsonloadsr r5r6metadatarNr\Z userdata_rawr]Zvendordata_raw)rr:rrr_crawl_metadatasz"DataSourceScaleway._crawl_metadatacCs>tjd}|dkrdStjjdr&dStj}d|kr:dSdS)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-manufacturerrPTz/var/run/scalewayZscalewayN)rZ read_dmi_dataospathexistsr Z get_cmdline)Z vendor_nameZcmdlinerrr ds_detects  zDataSourceScaleway.ds_detectcCs|dkrtjd|gSg}x|D]~}t|j}|ddkrH|dd }tj|dtjddd}|tjkr|dkr||g7}q"q"|tjkr"|dkr"||g7}q"q"W|S) Nipv4ipv6zInvalid IP version : %srr<r)r=)rnror?) rBrCrrDr"rErFZAF_INETrG)rr=rcZ filtered_urlsZurlrKrLrrr_set_urls_on_ip_versions$         z*DataSourceScaleway._set_urls_on_ip_versionc!Cs4|jdkrtj|_|jry`t|j|jH}tjtj d|j |j fdtjtj d|j d|d|_ d|jd<WdQRXWn>tttfk r}ztjtt|d|_WYdd}~XnX|js0yVt|j|j>tjtj d |j |j fdtjtj d|j dd |jd<WdQRXWntk r.dSXd S) Nz3Set api-metadata URL depending on IPv4 availability)logfuncmsgfuncargszCrawl of metadata service)rqrrrsz fixed-addressrnZ net_in_useFz3Set api-metadata URL depending on IPv6 availabilityroT)rXrfind_fallback_nicr_rrar Zlog_timerBrCrerRrir^rhr rrZlogexcstrr)rrnerrr _get_data sV        zDataSourceScaleway._get_datac Cs|jdkr tjdtjtj|_|jtjkr2|jS|jdkrFtj|_|jddkrFi}i}x|jdD]}|d|j krd|d<dd d g|d <qjd |j kr|d |dd |df7<n|dd |df|d <|ddkrj|ddd}d |j kr |d |g7<qj|g|d <qjW|||j<d|d|_ndd|jd}ddig}|jdr|dd|jddd|jddddd|jdddgdg7}||d <d!|gd"|_tj d#|j|jS)$z` Configure networking according to data received from the metadata API. Nz5Found None as cached _network_config. Resetting to %sZ private_ipZ public_ipsrKTZdhcp4z169.254.42.42/32z 62.210.0.1)toviaroutesZ addresses/netmaskZfamilyZinet6gatewayz::/0)rzryr)versionZ ethernetsZphysicalz%s)typenamerroZstaticz::0)Znetworkprefixr~)rrKr}r{subnetsr)rconfigznetwork_config : %s) rZrBrIrrYrXrrurhr^r`rC)rZnetcfgZip_cfgZipZrouterrrrnetwork_configMsV         z!DataSourceScaleway.network_configcCsdS)Nr)rrrr launch_indexszDataSourceScaleway.launch_indexcCs |jdS)Nid)rh)rrrrget_instance_idsz"DataSourceScaleway.get_instance_idcCsbdd|jdD}d}t|}x<|jjdgD]*}|j|s@q0|j||djddq0W|S)NcSsg|] }|dqS)keyr).0rrrr sz:DataSourceScaleway.get_public_ssh_keys..Zssh_public_keyszAUTHORIZED_KEY=Ztagsr. )rhlenrT startswithappendreplace)rZssh_keysZakeypreZplentagrrrget_public_ssh_keyss z&DataSourceScaleway.get_public_ssh_keysFcCst|jddS)NZhostnameF)rrh)rZfqdnZ resolve_ipZ metadata_onlyrrr get_hostnameszDataSourceScaleway.get_hostnamecCsdS)Nr)rrrravailability_zonesz$DataSourceScaleway.availability_zonecCsdS)Nr)rrrrregionszDataSourceScaleway.region)FFF)r$r%r&Zdsnamer ZNETWORKr ZBOOT_NEW_INSTANCEZBOOTZ BOOT_LEGACYZdefault_update_eventsrreri staticmethodrmrprxpropertyrrrrrrrr(rr)rrrOs$   A M   rOcCs tj|tS)N)rZlist_from_depends datasources)Zdependsrrrget_datasource_listsr)1rfZloggingrjr"rJZ urllib.parserr,Zrequests.exceptionsrZurllib3.connectionrZurllib3.poolmanagerrZ cloudinitrrrr r Zcloudinit.eventr r Zcloudinit.net.dhcpr Zcloudinit.net.ephemeralrrZcloudinit.sourcesrZcloudinit.subprZ getLoggerr$rBr[rUrWrVZadaptersZ HTTPAdapterrr;rNZ DataSourcerOZDEP_FILESYSTEMrrrrrrs8        (4$