o
    f2                  	   @   s.  d dl Z 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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)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+   r2   <   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{}{})r7   
ValueErrorformat)r8   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.)r7   r/   infor    r'   local_stage_should_fetch_data_local_should_fetch_data_networkr8   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.r7   r/   rD   r    r)   r(   rH   r*   r*   r+   rF   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 setuprJ   rH   r*   r*   r+   rG      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   )rE   r   r7   itemsanyr/   warningr   appendr   r:   noop)r8   network_context_managers
interfaces	interfacepreferred_prefixesinfr*   rN   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)rb   rc   rd   re   r   rh   z*Failed to base64 decode userdata due to %sNz1Failed to retrieve metadata using IPv%s due to %s64F)r
   readurlrC   coder/   rD   strjsonloadsr   userdata_rawr   decodebinasciiErrorrS   UrlError)r8   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.)r/   r0   r   rD   r   r   rI   r    r(   r'   r[   rw   getrS   )r8   local_instance_idavailabilityrV   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)r8   r9   r*   r*   r+   check_instance_id[  s   z"DataSourceAkamai.check_instance_idN)F)r#   r$   r%   dsnamerE   r2   rm   boolrC   r    rI   rF   rG   r   r   r   r   r   r[   rw   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&   rE   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   )(rr   rn   loggingbase64r   
contextlibr   rU   enumr   typingr   r   r   r   	cloudinitr	   r
   r   cloudinit.netr   r   cloudinit.net.ephemeralr    cloudinit.sources.helpers.akamair   r   r   	getLoggerr#   r/   r6   r    r1   r,   r   DEP_FILESYSTEMDEP_NETWORKr   r   r*   r*   r*   r+   <module>   sP    
  /
