
    x[h:                        S SK r S SKrS SKrS SKrS SKrS SKJr  S SKrS SKJ	r	  S SK
Jr  S SKJr  S SKJrJrJrJrJr  S SKJrJr  S SKJr  S S	KJrJr  S S
KJr  S SKJr  \R@                  " \!5      r"SS/r#Sr$Sr%Sr& " S S\RN                  RP                  5      r)S r*S r+ " S S\RX                  5      r-\-\R\                  44/r/S r0g)    N)urlparse)ConnectionError)HTTPConnection)PoolManager)dmiperformancesources
url_helperutil)
EventScope	EventType)NoDHCPLeaseError)EphemeralDHCPv4EphemeralIPv6Network)DataSourceHostname)ProcessExecutionErrorzhttp://169.254.42.42zhttp://[fd00:42::42]      
   c                   6   ^  \ rS rSrSrU 4S jrSS jrSrU =r$ )SourceAddressAdapter&   z>
Adapter for requests to choose the local address to bind to.
c                 :   > Xl         [        [        U ]  " S0 UD6  g )N )source_addresssuperr   __init__)selfr   kwargs	__class__s      F/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceScaleway.pyr   SourceAddressAdapter.__init__+   s    ,"D2<V<    c                     [         R                  [        R                  [        R                  S4/-   n[        UUUU R                  US9U l        g )N   )	num_poolsmaxsizeblockr   socket_options)r   default_socket_optionssocket
SOL_SOCKETSO_REUSEPORTr   r   poolmanager)r   connectionsr'   r(   r)   s        r!   init_poolmanager%SourceAddressAdapter.init_poolmanager/   sR    '>> 3 3Q7B
 
 '!..)
r#   )r.   r   )F)	__name__
__module____qualname____firstlineno____doc__r   r0   __static_attributes____classcell__r    s   @r!   r   r   &   s    =

 

r#   r   c           	           [         R                  " U SUSUS S9n[        R                  " UR                  5      $ ! [         R
                   a  nUR                  S:X  a   SnAge SnAff = f)a%  
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.
Nr   c                     U R                   S:g  =(       a3    [        U R                  [        R                  R
                  5      (       + $ )N  )code
isinstancecauserequests
exceptionsr   )excs    r!   <lambda>%query_data_api_once.<locals>.<lambda>W   s3    SXX_ &syy(*=*=*M*MNN&r#   )datatimeoutretriessessionexception_cbr<   )r
   readurlr   decode_binarycontentsUrlErrorr=   )api_addressrF   requests_sessionresprB   s        r!   query_data_api_oncerQ   <   sk     !! $
 !!$--00 88s?	s   9< A+A&%A&&A+c                    [        S[        US5      5       H  n [        R                  SX5        [        R
                  " 5       nSn [        U5      R                  nUnUS   S:X  a  USS n[        R                  " US[        R                  S	9S   S   n	U	[        R                  :X  a  S
nUR                  S[        Xd4S95        [        XUS9n
[        R                  SU 5        U
s  $    We! [         a     NNf = f! [         R"                   a:  n[        R%                  SX5        [&        R(                  " S5        Un SnAGM2  SnAff = f)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.
r%   r   z*Trying to get %s data (bind on port %d)...z0.0.0.0r   [N)protoz0::zhttp://)r   )rF   rO   z%s-data downloadedz%Error while trying to get %s data: %s   )rangemaxLOGdebugr@   Sessionr   netlocr+   getaddrinfoIPPROTO_TCPAF_INET6
ValueErrormountr   rQ   r
   rM   warningtimesleep)api_typerN   rG   rF   portrO   	localhosturl_addressaddress
addr_protorE   rB   last_excs                r!   query_data_apirl   d   sT    aWa)"	II<h  (//1!I&{3::%q>S()!B/G#//T););
 0 %I ""$Y4EF '?OD II*H5K9 *L N)   "" 	KK?OJJqMH	s<   -D 	A%C0.;D 0
C=:D <C==D  E.E		Ec                     ^  \ rS rSrSr\R                  \R                  \R                  \R                  10rU 4S jrS\SS4U 4S jjrS rS	 r\S
 5       rS r\S 5       r\S 5       rS rS rSS jr\S 5       r\S 5       rSrU =r$ )DataSourceScaleway   Scalewayc                   > [         [        U ]  XU5        [        R                  " [        R
                  " USS/0 5      /5      U l        [        U R                  R                  S[        5      5      U l
        [        U R                  R                  S[        5      5      U l        [        U R                  R                  S[        5      5      U l        [        R                   U l        [$        U l        S U l        S U l        S U l        S U l        SU l        SU R                  R3                  5       ;   a#  U =R&                  U R                  S   -  sl        g g )N
datasourcerp   rG   rF   max_waitTmetadata_urls)r   rn   r   r   mergemanydictget_cfg_by_pathds_cfgintgetDEF_MD_RETRIESrG   DEF_MD_TIMEOUTrF   DEF_MD_MAX_WAITrs   r	   UNSET_network_configDS_BASE_URLSrt   metadata_urluserdata_urlvendordata_urlephemeral_fixed_addresshas_ipv4keys)r   sys_cfgdistropathsr    s       r!   r   DataSourceScaleway.__init__   s    $0%H(($$W|Z.H"M
 4;;??9nEF4;;??9nEFDKKOOJHI&}})  "'+$dkk..00$++o">> 1r#   ci_pkl_versionreturnNc                    > [         TU ]  U5        S S[        [        S S S.nU H#  n[	        X5      (       a  M  [        XX#   5        M%     g )NT)r   r   rs   rt   r   r   )r   	_unpickler|   r   hasattrsetattr)r   r   attr_defaultsattrr    s       r!   r   DataSourceScaleway._unpickle   sM    .)'+') "
 "D4&&M$78 "r#   c                 v   [         R                  " 5       n[        R                  " UU R                  U R
                  SS9u  p4U(       a5  [        R                  SU5        U S3U l        U S3U l	        U S3U l
        g[        R                  SU[        [         R                  " 5       U-
  5      5        [        e)	z?
Define metadata_url based upon api-metadata URL availability.
F)urlsrs   rF   connect_synchronouslyz%s is reachablez/conf?format=jsonz/user_data/cloud-initz/vendor_data/cloud-initNz3Unable to reach api-metadata at %s after %s seconds)rc   	monotonicr
   wait_for_urlrs   rF   rY   rZ   r   r   r   rx   r   )r   r   
start_time	avail_url_s        r!   _set_metadata_url$DataSourceScaleway._set_metadata_url   s    
 ^^%
!..]]LL"'	
	 II'3#,+-> ?D#,+-B CD%.K/F"GDIIEDNN$z12
 "!r#   c                    [         R                  " U R                  U R                  U R                  S9n[
        R                  " [        R                  " UR                  5      5      U l
        [        SU R                  U R                  U R                  5      U l        [        SU R                  U R                  U R                  5      U l        g )N)rF   rG   z	user-datazvendor-data)r
   rJ   r   rF   rG   jsonloadsr   rK   rL   metadatarl   r   userdata_rawr   vendordata_raw)r   rP   s     r!   _crawl_metadata"DataSourceScaleway._crawl_metadata   s    !!t||T\\
 

4#5#5dmm#DE***DLL$,,
 -4..dll
r#   c                      [         R                  " S5      n U S:X  a  g[        R                  R	                  S5      (       a  g[
        R                  " 5       nSU;   a  gg)z
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.
zsystem-manufacturerrp   Tz/var/run/scalewayscalewayN)r   read_dmi_dataospathexistsr   get_cmdline)vendor_namecmdlines     r!   	ds_detectDataSourceScaleway.ds_detect   sU     ''(=>*$77>>-..""$  !r#   c                    U R                   (       a   [        U R                  U R                  R                  5       n[        R
                  " S5         U R                  U R                  5        S S S 5        U R                  5         US   U l	        SU R                  S'   S S S 5        U R                   (       d   [%        U R                  U R                  R                  5         [        R
                  " S5         U R                  U R                  5        S S S 5        U R                  5         SU R                  S'   S S S 5        gg! , (       d  f       N= f! , (       d  f       N= f! [        [        [        4 a6  n[        R                  " [         [#        U5      5        SU l          S nAGNS nAff = f! , (       d  f       N= f! , (       d  f       g= f! [         a     gf = f)	Nz7Setting api-metadata URL depending on IPv4 availabilityzfixed-addressipv4
net_in_useFz7Setting api-metadata URL depending on IPv6 availabilityipv6T)r   r   r   fallback_interfacer   Timedr   rt   r   r   r   r   r   r   r   logexcrY   strr   )r   r   es      r!   	_get_dataDataSourceScaleway._get_data  s   
 ==& %KKKK22 $**9 ..t/A/AB	
 ((*373HD028DMM,/. }})KKKK22 %**, ..t/A/AB	
 ((*28DMM,/ E 	  !% &
 CQ( !&&" 	   # s   *E+ EE	01E!E+ ;*G %G
<F9'G
?G 	
E	E
E($E+ (E+ +F6 +F11F69
G	G


GG G 
G('G(c           	      |   U R                   c9  [        R                  S[        R                  5        [        R                  U l         U R                   [        R                  :w  a  U R                   $ U R
                  S   Gc  0 n0 nU R
                  S    H  nUS   U R                  :X  a7  SUS'   SSSS	.nS
UR                  5       ;   a  US
==   U/-  ss'   ME  U/US
'   MM  SUR                  5       ;   a  US==   US    SUS    34-  ss'   OUS    SUS    34US'   US   S:X  d  M  US   SS.nS
UR                  5       ;   a  US
==   U/-  ss'   M  U/US
'   M     X!U R                  R                  '   SUS.U l         OSSU R                  R                  -  S.nSS0/nU R
                  S   (       aI  USSU R
                  S   S   -  SU R
                  S   S   -  SSSU R
                  S   S   -  S./S./-  nXQS'   S U/S!.U l         [        R                  S"U R                   5        U R                   $ )#zH
Configure networking according to data received from the
metadata API.
z5Found None as cached _network_config. Resetting to %s
private_ip
public_ipsri   Tdhcp4z169.254.42.42/32z
62.210.0.1)zon-linktoviaroutes	addresses/netmaskfamilyinet6gatewayz::/0)r   r   r   )version	ethernetsphysicalz%s)typenamer   r   staticz::0)networkprefixr   )r   ri   r   r   subnetsr%   )r   configznetwork_config : %s)r~   rY   rb   r	   r}   r   r   r   r   r   rZ   )r   netcfgip_cfgiprouter   s         r!   network_config!DataSourceScaleway.network_config4  s    'KKG $+==D 7==0'''==&. FFmmL1i=D$@$@@&*F7O $(0+E
  6;;=0x(UG3(,17x("fkkm3{+!)}oQr)}o>0 +
  ")}oQr)}o>/{+ (|w.(*9V D#v{{}4"8,7,05wF8,9 2: 6<4;;112/0v#FD  #t{{===F ()G}}V$ (#'$--*?	*J#J#'$--*?	*J#J ,0*-+/"&--"7	"B,C#	  !(9/0VH#ED 		')=)=>###r#   c                     g Nr   r   s    r!   launch_indexDataSourceScaleway.launch_index      r#   c                      U R                   S   $ )Nid)r   r   s    r!   get_instance_id"DataSourceScaleway.get_instance_id  s    }}T""r#   c                 (   U R                   S    Vs/ s H  oS   PM	     nnSn[        U5      nU R                   R                  S/ 5       H>  nUR                  U5      (       d  M  UR	                  XTS  R                  SS5      5        M@     U$ s  snf )Nssh_public_keyskeyzAUTHORIZED_KEY=tagsr    )r   lenry   
startswithappendreplace)r   r   ssh_keysakeypreplentags         r!   get_public_ssh_keys&DataSourceScaleway.get_public_ssh_keys  s    *.--8I*JK*J3J*JK#7|==$$VR0C>>'**OOCJ..sC89 1
  Ls   Bc                 4    [        U R                  S   S5      $ )NhostnameF)r   r   )r   fqdn
resolve_ipmetadata_onlys       r!   get_hostnameDataSourceScaleway.get_hostname  s    !$--
";UCCr#   c                     g r   r   r   s    r!   availability_zone$DataSourceScaleway.availability_zone  r   r#   c                     g r   r   r   s    r!   regionDataSourceScaleway.region  r   r#   )r~   rw   r   r   rs   r   r   rt   rG   rF   r   r   r   r   )FFF)r2   r3   r4   r5   dsnamer   NETWORKr   BOOT_NEW_INSTANCEBOOTBOOT_LEGACYdefault_update_eventsr   rx   r   r   r   staticmethodr   r   propertyr   r   r   r   r   r   r   r7   r8   r9   s   @r!   rn   rn      s    F''NN!!
?,9 9 9"4
  (0d M$ M$^  #
D    r#   rn   c                 8    [         R                  " U [        5      $ r   )r	   list_from_dependsdatasources)dependss    r!   get_datasource_listr    s    $$Wk::r#   )1r   loggingr   r+   rc   urllib.parser   r@   requests.exceptionsr   urllib3.connectionr   urllib3.poolmanagerr   	cloudinitr   r   r	   r
   r   cloudinit.eventr   r   cloudinit.net.dhcpr   cloudinit.net.ephemeralr   r   cloudinit.sourcesr   cloudinit.subpr   	getLoggerr2   rY   r   rz   r|   r{   adaptersHTTPAdapterr   rQ   rl   
DataSourcern   DEP_FILESYSTEMr	  r  r   r#   r!   <module>r     s      	   !  / . + A A 1 / I 0 0!&(>?
8,,88 
,%P1hH++ HX '0023
;r#   