
    }f>                        d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZmZ d dlmZmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ  ej>                  e       Z!ddgZ"dZ#dZ$dZ% G d dejL                  jN                        Z(d Z)d Z* G d dejV                        Z,e,ejZ                  ffgZ.d Z/y)    N)urlparse)ConnectionError)HTTPConnection)PoolManager)dmisources
url_helperutil)
EventScope	EventType)NoDHCPLeaseError)EphemeralDHCPv4EphemeralIPv6Network)DataSourceHostname)ProcessExecutionErrorzhttp://169.254.42.42zhttp://[fd00:42::42]      
   c                   *     e Zd ZdZ fdZddZ xZS )SourceAddressAdapterzF
    Adapter for requests to choose the local address to bind to.
    c                 :    || _         t        t        |   di | y )N )source_addresssuperr   __init__)selfr   kwargs	__class__s      F/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceScaleway.pyr   zSourceAddressAdapter.__init__+   s    ,"D2<V<    c                     t         j                  t        j                  t        j                  dfgz   }t        |||| j                  |      | _        y )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_poolmanagerz%SourceAddressAdapter.init_poolmanager/   sR    '>> 3 3Q7B
 
 '!..)
r    )F)__name__
__module____qualname____doc__r   r-   __classcell__r   s   @r   r   r   &   s    =

r    r   c                     	 t        j                  | d|d|d       }t        j                  |j                        S # t         j
                  $ r}|j                  dk(  rY d}~y d}~ww xY w)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.
    Nr   c                     |j                   dk7  xr/ t        |j                  t        j                  j
                         S )N  )code
isinstancecauserequests
exceptionsr   )_excs     r   <lambda>z%query_data_api_once.<locals>.<lambda>W   s3    C )syy(*=*=*M*MNN r    )datatimeoutretriessessionexception_cbr6   )r	   readurlr
   decode_binarycontentsUrlErrorr7   )api_addressr@   requests_sessionrespr=   s        r   query_data_api_oncerK   <   sk     !! $
 !!$--00 88s?	s   := A*A%$A%%A*c                    t        dt        |d            D ]  }	 t        j                  d| |       t	        j
                         }d}	 t        |      j                  }|}|d   dk(  r|dd }t        j                  |dt        j                  	      d   d   }	|	t        j                  k(  rd
}|j                  dt        ||f             t        |||      }
t        j                  d|        |
c S  # t        $ r Y Tw xY w# t         j"                  $ r9}t        j%                  d| |       t'        j(                  d       |}Y d}~6d}~ww xY w)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   )r@   rI   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   rK   r	   rG   warningtimesleep)api_typerH   rA   r@   portrI   	localhosturl_addressaddress
addr_protor?   r=   last_excs                r   query_data_apirg   d   sa    aWa) #"	II<h  (//1!I&{3::%q>S()!B/G#//T););
 0 %I ""$Y4EF 'W?OD II*H5K9#L N)   "" 	KK?3OJJqMH	s=   -D	A%C7.AD7	D DDDE.EEc                       e Zd ZdZej
                  ej                  ej                  ej                  hiZ
 fdZdeddf fdZd Zd Zed	        Zd
 Zd Zed        Zed        Zd Zd ZddZed        Zed        Z xZS )DataSourceScalewayScalewayc                    t         t        |   |||       t        j                  t        j
                  |ddgi       g      | _        t        | j                  j                  dt                    | _
        t        | j                  j                  dt                    | _        t        | j                  j                  dt                    | _        t        j                   | _        t$        | _        d | _        d | _        d | _        d | _        d| _        d| j                  j3                         v r#| xj&                  | j                  d   z  c_        y y )N
datasourcerj   rA   r@   max_waitTmetadata_urls)r   ri   r   r
   mergemanydictget_cfg_by_pathds_cfgintgetDEF_MD_RETRIESrA   DEF_MD_TIMEOUTr@   DEF_MD_MAX_WAITrm   r   UNSET_network_configDS_BASE_URLSrn   metadata_urluserdata_urlvendordata_urlephemeral_fixed_addresshas_ipv4keys)r   sys_cfgdistropathsr   s       r   r   z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         |   |       d dt        t        d d d}|D ]  }t	        | |      rt        | |||          ! y )NT)r}   r~   rm   rn   r{   r|   )r   	_unpicklerv   ry   hasattrsetattr)r   r   attr_defaultsattrr   s       r   r   zDataSourceScaleway._unpickle   sU    .)'+') "
 " 	9D4&dM$$78	9r    c                 n   t        j                         }t        j                  || j                  | j
                  d      \  }}|r5t        j                  d|       | d| _        | d| _	        | d| _
        yt        j                  d|t        t        j                         |z
               t        )	zO
        Define metadata_url based upon api-metadata URL availability.
        F)urlsrm   r@   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)r^   	monotonicr	   wait_for_urlrm   r@   rT   rU   rz   r{   r|   rr   r   )r   r   
start_time	avail_urlr<   s        r   _set_metadata_urlz$DataSourceScaleway._set_metadata_url   s    
 ^^%
!..]]LL"'	
	1 II'3#,+-> ?D#,+-B CD%.K/F"GDIIEDNN$z12
 "!r    c                    t        j                  | j                  | j                  | j                        }t        j                  t        j                  |j                              | _
        t        d| j                  | j                  | j                        | _        t        d| j                  | j                  | j                        | _        y )N)r@   rA   z	user-datazvendor-data)r	   rD   rz   r@   rA   jsonloadsr
   rE   rF   metadatarg   r{   userdata_rawr|   vendordata_raw)r   rJ   s     r   _crawl_metadataz"DataSourceScaleway._crawl_metadata   s    !!t||T\\
 

4#5#5dmm#DE***DLL$,,
 -4..dll
r    c                      t        j                  d      } | dk(  ryt        j                  j	                  d      ryt        j                         }d|v ryy)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.
        zsystem-manufacturerrj   Tz/var/run/scalewayscalewayN)r   read_dmi_dataospathexistsr
   get_cmdline)vendor_namecmdlines     r   	ds_detectzDataSourceScaleway.ds_detect   sR     ''(=>*$77>>-.""$  !r    c                 j   |dvrt         j                  d|       g S g }|D ]  }t        |      j                  }|d   dk(  r|dd }t	        j
                  |d t        j                        d   d   }|t        j                  k(  r|dk(  r||gz  }p|t        j                  k(  s|d	k(  s||gz  } |S )
N)ipv4ipv6zInvalid IP version : %sr   rM   r"   rN   rO   r   r   )	rT   rU   r   rW   r(   rX   rY   AF_INETrZ   )r   rP   r   filtered_urlsurlrd   re   s          r   _set_urls_on_ip_versionz*DataSourceScaleway._set_urls_on_ip_version  s    ((II/7I 	Csm**GqzS !!B-++V%7%7J V^^+#&v.5F?#&	 r    c                    | j                   r	 t        | j                  | j                  j                        5 }t	        j
                  t        j                  d| j                  | j                  f       t	        j
                  t        j                  d| j                         |d   | _        d| j                  d<   d d d        | j                   s	 t%        | j                  | j                  j                        5  t	        j
                  t        j                  d	| j                  | j                  f       t	        j
                  t        j                  d| j                         d
| j                  d<   d d d        yy# 1 sw Y   xY w# t        t        t        f$ r5}t	        j                   t        t#        |             d| _         Y d }~d }~ww xY w# 1 sw Y   yxY w# t        $ r Y yw xY w)Nz3Set api-metadata URL depending on IPv4 availability)logfuncmsgfuncargszCrawl of metadata service)r   r   r   zfixed-addressr   
net_in_useFz3Set api-metadata URL depending on IPv6 availabilityr   T)r~   r   r   fallback_interfacer
   log_timerT   rU   r   rn   r   r}   r   r   r   r   logexcstrr   )r   r   es      r   	_get_datazDataSourceScaleway._get_data  s   
 ==& %KKKK22 9 MM #		,!33"002 MM #		7!11
 483HD028DMM,/#9: }})KKKK22 9 MM #		,!33"002 MM #		7!11
 39DMM,/!9& e9 9& !% &
 CQ( !&&9&  $ s`   *F BF>F *G' =A<G9G' FF G#*GGG$ G' $G' '	G32G3c           	      
   | j                   9t        j                  dt        j                         t        j                  | _         | j                   t        j                  k7  r| j                   S | j
                  d   i }i }| j
                  d   D ]  }|d   | j                  k(  rd|d<   ddd	g|d
<   $d|j                         v r|dxx   |d    d|d    fz  cc<   n|d    d|d    f|d<   |d   dk(  sj|d   dd}d
|j                         v r|d
xx   |gz  cc<   |g|d
<    ||| j                  j                  <   d|d| _         ndd| j                  j                  z  d}ddig}| j
                  d   rI|dd| j
                  d   d   z  d| j
                  d   d   z  ddd| j
                  d   d   z  dgdgz  }||d<   d |gd!| _         t        j                  d"| j                          | j                   S )#z`
        Configure networking according to data received from the
        metadata API.
        z5Found None as cached _network_config. Resetting to %s
private_ip
public_ipsrd   Tdhcp4z169.254.42.42/32z
62.210.0.1)toviaroutes	addresses/netmaskfamilyinet6gatewayz::/0)r   r   r   )version	ethernetsphysicalz%s)typenamer   r   staticz::0)networkprefixr   )r   rd   r   r   subnetsr"   )r   configznetwork_config : %s)rx   rT   r]   r   rw   r   r}   r   r   r   rU   )r   netcfgip_cfgiprouter   s         r   network_configz!DataSourceScaleway.network_configX  sd    'KKG $+==D 7==0'''==&. FFmmL1 7i=D$@$@@&*F7O  2,G(F8$ #fkkm3{+!)}oQr)}o>0 +
  ")}oQr)}o>/{+ (|w.(*9V D#v{{}4"8,7,05wF8,-7. 6<F4;;112/0v#FD  #t{{===F ()G}}V$ (#'$--*?	*J#J#'$--*?	*J#J ,0*-+/"&--"7	"B,C#	  !(F9/0VH#ED 		')=)=>###r    c                      y Nr   r   s    r   launch_indexzDataSourceScaleway.launch_index      r    c                      | j                   d   S )Nid)r   r   s    r   get_instance_idz"DataSourceScaleway.get_instance_id  s    }}T""r    c                    | j                   d   D cg c]  }|d   	 }}d}t        |      }| j                   j                  dg       D ]8  }|j                  |      s|j	                  ||d  j                  dd             : |S c c}w )Nssh_public_keyskeyzAUTHORIZED_KEY=tagsr<    )r   lenrs   
startswithappendreplace)r   r   ssh_keysakeypreplentags         r   get_public_ssh_keysz&DataSourceScaleway.get_public_ssh_keys  s    *.--8I*JK3CJKK#7|==$$VR0 	:C>>'*OOCJ..sC89	:
  Ls   Bc                 4    t        | j                  d   d      S )NhostnameF)r   r   )r   fqdn
resolve_ipmetadata_onlys       r   get_hostnamezDataSourceScaleway.get_hostname  s    !$--
";UCCr    c                      y r   r   r   s    r   availability_zonez$DataSourceScaleway.availability_zone  r   r    c                      y r   r   r   s    r   regionzDataSourceScaleway.region  r   r    )FFF)r.   r/   r0   dsnamer   NETWORKr   BOOT_NEW_INSTANCEBOOTBOOT_LEGACYdefault_update_eventsr   rr   r   r   r   staticmethodr   r   r   propertyr   r   r   r   r   r   r   r2   r3   s   @r   ri   ri      s    F''NN!!
?,9 9 9"4
  (0<| G$ G$R  #
D    r    ri   c                 6    t        j                  | t              S r   )r   list_from_dependsdatasources)dependss    r   get_datasource_listr     s    $$Wk::r    )0r   loggingr   r(   r^   urllib.parser   r:   requests.exceptionsr   urllib3.connectionr   urllib3.poolmanagerr   	cloudinitr   r   r	   r
   cloudinit.eventr   r   cloudinit.net.dhcpr   cloudinit.net.ephemeralr   r   cloudinit.sourcesr   cloudinit.subpr   	getLoggerr.   rT   ry   rt   rv   ru   adaptersHTTPAdapterr   rK   rg   
DataSourceri   DEP_FILESYSTEMr   r   r   r    r   <module>r     s      	   !  / . + 4 4 1 / I 0 0g!&(>?
8,,88 
,%P1hf++ fT	 '0023
;r    