U
    Ld2                  	   @   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'eej" d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eeedddZe	dd	d
Z
e	dddZe	dddZeeeeef ef  dddZdeedddZedddZed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 DataSourceZ
datasourcer.   )LOGdebugr
   
DataSource__init__dictr   r   Zmergemanydictr   Zget_cfg_by_pathBUILTIN_DS_CONFIGds_cfg)selfsys_cfgdistror   r+   r+   r,   r2   <   s    
zDataSourceAkamai.__init__)	path_nameuse_v6returnc                 C   sZ   || j d krtd|d}|s.| j d s2d}| 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{}{})r5   
ValueErrorformat)r6   r9   r:   Zversion_keyZbase_urlpathr+   r+   r,   
_build_urlN   s    zDataSourceAkamai._build_urlr;   c                 C   sR   | j d s| j d r(| j d s8| j d s8td tjS | jrF|  S |  S d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.N)r5   r/   infor!   r(   local_stage_should_fetch_data_local_should_fetch_data_networkr6   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.r5   r/   rA   r!   r*   r)   rE   r+   r+   r,   rC   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 setuprG   rE   r+   r+   r,   rD      s    

z+DataSourceAkamai._should_fetch_data_networkc                    s   g }| j rt }d}| jd }| D ]&\ }t fdd|D r&|} qNq&|dkrftd t }g }| jd r|t	| j
|ddd	df | jd
 r| jd r|t	| j
|dddf n4| jd r|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Z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   )rB   r   r5   itemsanyr/   warningr   appendr   r8   noop)r6   network_context_managersZ
interfacesZ	interfaceZpreferred_prefixesinfr+   rK   r,   _get_network_context_managers   sh    




z.DataSourceAkamai._get_network_context_managers)r:   r;   c              
   C   s>  zt j| jd|dddddddid	}|jd
krDt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 n0 tjk
r } ztd| W 5 d}~X Y nX W nD t jk
r8 } z"td|rdnd| W Y dS d}~X Y nX dS )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:   ZPUT   r#      zMetadata-Token-Expiry-SecondsZ300)Zrequest_methodtimeoutsec_betweenretriesheaders   z-Fetching token returned %s; not fetching dataTr   zapplication/json)ZAcceptMetadata-Token)rX   rY   rZ   r[   r   r]   z*Failed to base64 decode userdata due to %sNz1Failed to retrieve metadata using IPv%s due to %s64F)r   Zreadurlr?   coder/   rA   strjsonloadsr   Zuserdata_rawr   decodebinasciiErrorrO   ZUrlError)r6   r:   Ztoken_responser   r   r   er+   r+   r,   _fetch_metadata   sd     


 	
"z DataSourceAkamai._fetch_metadatac              
   C   s   t d t st d dS t }d|i| _|  }|tjkrf|tj	krXt d dS t d dS | 
 }|D ]J\}}|8 | j|d}|r| jd	|| jd< W 5 Q R   qW 5 Q R X qrt 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.rU   idzHFailed to contact metadata service, falling back to local metadata only.)r/   r0   r   rA   r   r   rF   r!   r)   r(   rT   rh   getrO   )r6   Zlocal_instance_idZavailabilityrR   Zmanagerr:   Zdoner+   r+   r,   	_get_data'  sB    

 


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
   Zinstance_id_matches_system_uuidZget_instance_id)r6   r7   r+   r+   r,   check_instance_id[  s     z"DataSourceAkamai.check_instance_idN)F)F)r$   r%   r&   ZdsnamerB   r2   ra   boolr?   r!   rF   rC   rD   r   r   r   r   r   rT   rh   rk   rl   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'   rB   r+   r+   r+   r,   rn   e  s   rn   r@   c                 C   s   t | tS )N)r
   Zlist_from_dependsdatasources)Zdependsr+   r+   r,   get_datasource_list  s    rp   ))re   rb   base64r   
contextlibr   rQ   enumr   typingr   r   r   r   Z	cloudinitr	   Zloggingr
   r   r   Zcloudinit.netr   r   Zcloudinit.net.ephemeralr   Z cloudinit.sources.helpers.akamair   r   r   Z	getLoggerr$   r/   r4   r!   r1   r-   rn   ZDEP_FILESYSTEMZDEP_NETWORKro   rp   r+   r+   r+   r,   <module>   sN   
  /
