o
    w7e2                  	   @   s2  d dl 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 d dl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mZ eeZdddddddddddddgdZ G dd deZ!G dd dej"Z#G dd de#Z$e$ej%ffe#ej%ej&ffgZ'deej" fddZ(dS )    N)	b64decode)suppress)Enum)AnyListTupleUnion)log)sources
url_helperutil)find_fallback_nicget_interfaces_by_mac)EphemeralIPNetwork)get_dmi_configget_local_instance_idis_on_akamaizhttp://169.254.169.254zhttp://[fd00:a9fe:a9fe::1]ipv4ipv6z	/v1/tokenz/v1/instancez/v1/user-data)tokenmetadatauserdataTzf2:3)	base_urlspathsallow_local_stageallow_init_stage
allow_dhcp
allow_ipv4
allow_ipv6preferred_mac_prefixesc                   @   s   e Zd ZdZdZdZdZdS )MetadataAvailabilityResultzj
    Used to indicate how this instance should behave based on the availability
    of metadata to it
    r         N)__name__
__module____qualname____doc__NOT_AVAILABLE	AVAILABLEDEFER r+   r+   D/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceAkamai.pyr!   -   s
    r!   c                   @   s   e Zd ZdZdZdd Zddededefdd	Zde	fd
dZ
de	fddZde	fddZdeeeeef ef  fddZddedefddZdefddZdefddZdS )DataSourceAkamaiAkamaiFc                 C   sJ   t d tj| ||| t | _tt	 t
|ddgi tg| _d S )NzSetting up Akamai DataSource
datasourcer.   )LOGdebugr
   
DataSource__init__dictr   r   mergemanydictr   get_cfg_by_pathBUILTIN_DS_CONFIGds_cfg)selfsys_cfgdistror   r+   r+   r,   r3   <   s   

zDataSourceAkamai.__init__	path_nameuse_v6returnc                 C   sZ   || j d vrtd|d}|s| j d sd}| j d | }| j d | }d||S )z
        Looks up the path for a given name and returns a full url for it.  If
        use_v6 is passed in, the IPv6 base url is used; otherwise the IPv4 url
        is used unless IPv4 is not allowed in ds_cfg
        r   zUnknown path name {}r   r   r   r   z{}{})r8   
ValueErrorformat)r9   r<   r=   version_keybase_urlpathr+   r+   r,   
_build_urlN   s   zDataSourceAkamai._build_urlc                 C   sN   | j d s
| j d r| j d s| j d std tjS | jr#|  S |  S )z
        Returns whether metadata should be retrieved at this stage, at the next
        stage, or never, in the form of a MetadataAvailabilityResult.
        r   r   r   r   z*Configuration prohibits fetching metadata.)r8   r0   infor!   r(   local_stage_should_fetch_data_local_should_fetch_data_networkr9   r+   r+   r,   _should_fetch_data`   s   
z#DataSourceAkamai._should_fetch_datac                 C   sD   | j d std tjS | j d s| j d std tjS tjS )z
        Returns whether metadata should be retrieved during the local stage, or
        if it should wait for the init stage.
        r   z)Configuration prohibits local stage setupr   r   z9Configuration does not allow for ephemeral network setup.r8   r0   rE   r!   r*   r)   rI   r+   r+   r,   rG   t   s   

z)DataSourceAkamai._should_fetch_data_localc                 C   s    | j d std tjS tjS )zS
        Returns whether metadata should be fetched during the init stage.
        r   z1Configuration does not allow for init stage setuprK   rI   r+   r+   r,   rH      s   

z+DataSourceAkamai._should_fetch_data_networkc                    s   g }| j rat }d}| jd }| D ]\ }t fdd|D r&|} nq|du r3td t }g }| jd rH|t	| j
|ddd	df | jd
 r_| jd r_|t	| j
|dddf |S | jd rn|t df | jd
 r{|t df |S )z
        Returns a list of context managers which should be tried when setting
        up a network context.  If we're running in init mode, this return a
        noop since networking should already be configured.
        Nr    c                    s   g | ]}  |qS r+   )
startswith).0prefixmacr+   r,   
<listcomp>   s    zBDataSourceAkamai._get_network_context_managers.<locals>.<listcomp>zGFailed to find default interface, attempting DHCP on fallback interfacer   FTr   r   r   )r   )rF   r   r8   itemsanyr0   warningr   appendr   r;   noop)r9   network_context_managers
interfaces	interfacepreferred_prefixesinfr+   rO   r,   _get_network_context_managers   sl   




z.DataSourceAkamai._get_network_context_managersc              
   C   s:  z}t j| jd|dddddddid	}|jd
kr"td|j W dS t|}t j| jd|ddddd|dd}tt|| _	t j| jd|ddddd|id}t|| _
zt| j
 | _
W W dS  tjy} } ztd| W Y d}~W dS d}~ww  t jy } ztd|rdnd| W Y d}~dS d}~ww )z
        Runs through the sequence of requests necessary to retrieve our
        metadata and user data, creating a token for use in doing so, capturing
        the results.
        r   r=   PUT   r#      zMetadata-Token-Expiry-Seconds300)request_methodtimeoutsec_betweenretriesheaders   z-Fetching token returned %s; not fetching dataTr   zapplication/json)AcceptMetadata-Token)rc   rd   re   rf   r   ri   z*Failed to base64 decode userdata due to %sNz1Failed to retrieve metadata using IPv%s due to %s64F)r   readurlrD   coder0   rE   strjsonloadsr   userdata_rawr   decodebinasciiErrorrT   UrlError)r9   r=   token_responser   r   r   er+   r+   r,   _fetch_metadata   sj   



	
z DataSourceAkamai._fetch_metadatac              	   C   s   t d t st d dS t }d|i| _|  }|tjkr3|tj	kr,t d dS t d dS | 
 }|D ]2\}}|$ | j|d}|r\| jd	|| jd< 	 W d
    dS W d
   n1 sfw   Y  q9t d dS )zW
        Overrides _get_data in the DataSource class to actually retrieve data
        z#Getting data from Akamai DataSourcez#Not running on Akamai, not running.Fzinstance-idz5Metadata is not available, returning local data only.TzFConfigured not to fetch data at this stage; waiting for a later stage.r]   idNzHFailed to contact metadata service, falling back to local metadata only.)r0   r1   r   rE   r   r   rJ   r!   r)   r(   r\   rx   getrT   )r9   local_instance_idavailabilityrW   managerr=   doner+   r+   r,   	_get_data'  sJ   




zDataSourceAkamai._get_datac                 C   s   t |  dS )zj
        A local-only check to see if the instance id matches the id we see on
        the system
        zsystem-serial-number)r
   instance_id_matches_system_uuidget_instance_id)r9   r:   r+   r+   r,   check_instance_id[  s   z"DataSourceAkamai.check_instance_idN)F)r$   r%   r&   dsnamerF   r3   rn   boolrD   r!   rJ   rG   rH   r   r   r   r   r   r\   rx   r   r   r+   r+   r+   r,   r-   8   s    
OD4r-   c                   @   s   e Zd ZdZdZdS )DataSourceAkamaiLocalz
    A subclass of DataSourceAkamai that runs the same functions, but during the
    init-local stage.  This allows configuring networking via cloud-init, as
    networking hasn't been configured yet.
    TN)r$   r%   r&   r'   rF   r+   r+   r+   r,   r   e  s    r   r>   c                 C   s   t | tS )N)r
   list_from_dependsdatasources)dependsr+   r+   r,   get_datasource_list  s   r   ))rs   ro   base64r   
contextlibr   rV   enumr   typingr   r   r   r   	cloudinitr	   loggingr
   r   r   cloudinit.netr   r   cloudinit.net.ephemeralr    cloudinit.sources.helpers.akamair   r   r   	getLoggerr$   r0   r7   r!   r2   r-   r   DEP_FILESYSTEMDEP_NETWORKr   r   r+   r+   r+   r,   <module>   sP    
  /
