U
    Ӈgg(                     @   s  d dl Z d dl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 d dlmZ d dlmZ e eZdZd	eiZd
ZdZeegZdZdZdZeZeeeeg7 ZG dd dejej Z!G dd de!Z"dddZ#e"ej$ffe!ej$ej%ffgZ&dd Z'dS )    N)dmisources
url_helperutil)
EventScope	EventType)NoDHCPLeaseError)EphemeralDHCPv4)DataSourceOracle)	openstackziid-dsopenstackzinstance-idzOpenStack NovazOpenStack ComputeZOpenTelekomCloudzSAP CCloud VMZHUAWEICLOUDc                       s   e Zd ZdZejZdZej	e
je
je
je
jhiZ fddZdd Zdd Zd	d
 Zedd Zdd Zdd Zdd Z  ZS )DataSourceOpenStackZ	OpenStackFc                    sH   t t| ||| d | _t| j| _d | _i | _	t
j| _t
j| _d S N)superr   __init__metadata_addressr   Zfetch_ssl_detailspathsssl_detailsversionfilesr   UNSETec2_metadatanetwork_json)selfsys_cfgdistror   	__class__ G/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceOpenStack.pyr   <   s    zDataSourceOpenStack.__init__c                 C   s"   t j| }d|| j| jf }|S )Nz%s [%s,ver=%s])r   
DataSource__str__dsmoder   )r   rootZmstrr   r   r   r    E   s    zDataSourceOpenStack.__str__c                 C   s  dj | jjddg}| jd|}dd |D }t|t|kr\tdtt|t|  t	|rj|}nt
d |}g }i }|D ]"}t|d	}|| |||< q|  }t }	tj||j|jd
d\}
}|
rtd||
  ntd|tt |	  ||
| _t|
S )Nz"http://[fe80::a9fe:a9fe%25{iface}])Zifacezhttp://169.254.169.254Zmetadata_urlsc                 S   s   g | ]}t |r|qS r   )r   Zis_resolvable_url).0xr   r   r   
<listcomp>R   s     
 zADataSourceOpenStack.wait_for_metadata_service.<locals>.<listcomp>z,Removed the following from metadata urls: %sz+Empty metadata url list! using default listr   F)urlsZmax_waittimeoutZconnect_synchronouslyzUsing metadata source: '%s'z2Giving up on OpenStack md from %s after %s seconds)formatr   fallback_interfaceds_cfggetsetLOGdebuglistlenwarningr   Zcombine_urlappendget_url_paramstime	monotonicZwait_for_urlZmax_wait_secondstimeout_secondsintr   bool)r   ZDEF_MD_URLSr&   ZfilteredZmd_urlsZurl2baseZurlZmd_url
url_paramsZ
start_timeZ	avail_urlZ	_responser   r   r   wait_for_metadata_serviceJ   sN    



z-DataSourceOpenStack.wait_for_metadata_servicec                 C   s   t |  S r   )r   Zinstance_id_matches_system_uuidZget_instance_id)r   r   r   r   r   check_instance_idy   s    z%DataSourceOpenStack.check_instance_idc                 C   sn   | j tjkr| j S t| jddr2d| _ | j S | jtjkrLt	d dS t
d tj| jdd| _ | j S )z@Return a network config dict for rendering ENI or netplan files.Zapply_network_configTNz<Unexpected call to network_config when network_json is None.z(network config provided via network_json)Z
known_macs)_network_configr   r   r   Zis_falser*   r+   r   r-   r1   r.   r   Zconvert_net_json)r   r   r   r   network_config}   s     
 z"DataSourceOpenStack.network_configc              
   C   s  | j rpz(t| j| jj |  }W 5 Q R X W q ttjfk
rl } zt	t
t| W Y dS d}~X Y qX nHz|  }W n: tjk
r } zt	t
t| W Y dS d}~X Y nX | |dg| _| jtjkrdS |di }t|tg}|| _|d| _|d| _|d| _|d | _| j|d	i  |d
}zt|| _W n6 tk
r } zt
d| d| _W 5 d}~X Y nX |d}zt|| _W n6 tk
r } zt
d| d| _W 5 d}~X Y nX dS )a  Crawl metadata, parse and persist that data for this instance.

        @return: True when metadata discovered indicates OpenStack datasource.
            False when unable to contact metadata service or when metadata
            format is invalid or disabled.
        FNr!   metadatazec2-metadataZnetworkdataZuserdatar   r   Z
vendordataz"Invalid content in vendor-data: %sZvendordata2z#Invalid content in vendor-data2: %sT)perform_dhcp_setupr	   r   r)   _crawl_metadatar   r   InvalidMetaDataExceptionr   Zlogexcr-   strZ_determine_dsmoder+   r!   ZDSMODE_DISABLEDZmergemanydictDEFAULT_METADATAr>   r   r   Zuserdata_rawr   r   updateZconvert_vendordataZvendordata_raw
ValueErrorr1   Zvendordata2_raw)r   ZresultseZmdZvdZvd2r   r   r   	_get_data   sN     


zDataSourceOpenStack._get_datac              
   C   s   z|   stdW n8 tk
rN } ztdjt|dW 5 d}~X Y nX |  }zt| j| j	|j
|jd}W nr tjk
r } ztt|W 5 d}~X Y nB tjtfk
r } zdj| jd}t||W 5 d}~X Y nX |S )zCrawl metadata service when available.

        @returns: Dictionary with all metadata discovered for this datasource.
        @raise: InvalidMetaDataException on unreadable or broken
            metadata.
        z No active metadata service foundz,IOError contacting metadata service: {error})errorN)r   retriesr'   zBroken metadata address {addr})Zaddr)r:   r   rA   IOErrorr(   rB   r3   read_metadata_servicer   r   Znum_retriesr6   r   ZNonReadableZBrokenMetadata)r   rF   r9   resultmsgr   r   r   r@      s6    
z#DataSourceOpenStack._crawl_metadatac                 C   sp   d| j dk}t sdS td}|tkr2dS tdtkrDdS |rTt	 rTdS t
ddtkrldS dS )	z<Return True when a potential OpenStack platform is detected.ZOracleZdatasource_listTzsystem-product-namezchassis-asset-tag   product_nameF)r   r+   r   Zis_x86r   Zread_dmi_dataVALID_DMI_PRODUCT_NAMESVALID_DMI_ASSET_TAGSoracleZ_is_platform_viableZget_proc_envDMI_PRODUCT_NOVA)r   Zaccept_oraclerO   r   r   r   	ds_detect   s    
zDataSourceOpenStack.ds_detect)__name__
__module____qualname__Zdsnamer   r   r<   r?   r   ZNETWORKr   ZBOOT_NEW_INSTANCEZBOOTZBOOT_LEGACYZHOTPLUGZsupported_update_eventsr   r    r:   r;   propertyr=   rG   r@   rT   __classcell__r   r   r   r   r   *   s&   		/
5%r   c                   @   s   e Zd ZdZdZdS )DataSourceOpenStackLocalau  Run in init-local using a dhcp discovery prior to metadata crawl.

    In init-local, no network is available. This subclass sets up minimal
    networking with dhclient on a viable nic so that it can talk to the
    metadata service. If the metadata service provides network configuration
    then render the network configuration for that instance based on metadata.
    TN)rU   rV   rW   __doc__r?   r   r   r   r   rZ     s   rZ      c                 C   s   t j| |||d}| S )N)r   r'   rI   )r   ZMetadataReaderZread_v2)Zbase_urlr   r'   rI   readerr   r   r   rK     s       rK   c                 C   s   t | tS r   )r   Zlist_from_dependsdatasources)Zdependsr   r   r   get_datasource_list  s    r_   )Nr\   r\   )(Zloggingr4   Z	cloudinitr   r   r   r   Zcloudinit.eventr   r   Zcloudinit.net.dhcpr   Zcloudinit.net.ephemeralr	   Zcloudinit.sourcesr
   rR   Zcloudinit.sources.helpersr   Z	getLoggerrU   r-   ZDEFAULT_IIDrC   rS   ZDMI_PRODUCT_COMPUTErP   ZDMI_ASSET_TAG_OPENTELEKOMZDMI_ASSET_TAG_SAPCCLOUDZDMI_ASSET_TAG_HUAWEICLOUDrQ   ZSourceMixinr   r   rZ   rK   ZDEP_FILESYSTEMZDEP_NETWORKr^   r_   r   r   r   r   <module>   s@   
  Z
	
