U
    L¬÷d)  ã                   @   s  d dl Z d dl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 d dlmZ d d	lmZ e e¡Zd
dg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)Úlog)ÚsourcesÚ
url_helperÚutil)Ú
EventScopeÚ	EventType)ÚNoDHCPLeaseError)ÚEphemeralDHCPv4)ÚDataSourceOracle)Ú	openstackzhttp://[fe80::a9fe:a9fe]zhttp://169.254.169.254z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!   G   s    zDataSourceOpenStack.__str__c                 C   s  | j  dt¡}dd„ |D ƒ}t|ƒt|ƒkrHt dtt|ƒt|ƒ ƒ¡ t|ƒrV|}nt d¡ t}g }i }|D ]"}t	 
|d¡}| |¡ |||< qp|  ¡ }t ¡ }t	j||j|jdd\}	}
|	rÔt d	||	 ¡ nt d
|tt ¡ | ƒ¡ | |	¡| _t|	ƒS )NZmetadata_urlsc                 S   s   g | ]}t  |¡r|‘qS r   )r   Zis_resolvable_url)Ú.0Úxr   r   r   Ú
<listcomp>N   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)Úds_cfgÚgetÚDEF_MD_URLSÚsetÚLOGÚdebugÚlistÚlenÚwarningr   Zcombine_urlÚappendÚget_url_paramsÚtimeZwait_for_urlZmax_wait_secondsÚtimeout_secondsÚintr   Úbool)r   r'   ZfilteredZmd_urlsZurl2baseZurlZmd_urlÚ
url_paramsZ
start_timeZ	avail_urlZ	_responser   r   r   Úwait_for_metadata_serviceL   sD    þ


ü
ý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_idu   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_configy   s     ÿ
 ÿz"DataSourceOpenStack.network_configc              
   C   sü  | j rzz2t| j| jƒ tjtjd| jd}W 5 Q R X W qÂ t	t
jfk
rv } zt tt|ƒ¡ W Y ¢dS d}~X Y qÂX 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ræd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.
        zCrawl of metadata service)ZlogfuncÚmsgÚfuncFNr"   Ú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   Zfallback_interfacer   Úlog_timer-   r.   Ú_crawl_metadatar	   r   ÚInvalidMetaDataExceptionZlogexcÚstrZ_determine_dsmoder*   r"   ZDSMODE_DISABLEDZmergemanydictÚDEFAULT_METADATAr?   r   r   Zuserdata_rawr   r   ÚupdateZvendordata_pureZconvert_vendordataZvendordata_rawÚ
ValueErrorr1   Zvendordata2_pureZvendordata2_raw)r   ZresultsÚeZmdZvdZvd2r   r   r   Ú	_get_data’   sT    ý


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t	j
dt| jg| j|j|jdœ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 )
zÖCrawl 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})ÚerrorNz#Crawl of openstack metadata service)r   Úretriesr(   )ÚargsÚkwargszBroken metadata address {addr})Zaddr)r9   r   rC   ÚIOErrorÚformatrD   r3   r   rA   r-   r.   Úread_metadata_servicer   r   Znum_retriesr5   r   ZNonReadableZBrokenMetadata)r   rH   r8   Úresultr=   r   r   r   rB   Ë   s>    ÿÿÿýû
ÿ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_oraclerS   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!   r9   r:   Úpropertyr<   rI   rB   rX   Ú__classcell__r   r   r   r   r   ,   s&   üÿ		)
9*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)rY   rZ   r[   Ú__doc__r@   r   r   r   r   r^     s   r^   é   c                 C   s   t j| |||d}| ¡ S )N)r   r(   rK   )r   ZMetadataReaderZread_v2)Zbase_urlr   r(   rK   Úreaderr   r   r   rP     s       ÿrP   c                 C   s   t  | t¡S r   )r   Zlist_from_dependsÚdatasources)Zdependsr   r   r   Úget_datasource_list#  s    rc   )Nr`   r`   )*r4   Z	cloudinitr   r   Zloggingr   r   r   Zcloudinit.eventr   r   Zcloudinit.net.dhcpr	   Zcloudinit.net.ephemeralr
   Zcloudinit.sourcesr   rV   Zcloudinit.sources.helpersr   Z	getLoggerrY   r-   r+   ZDEFAULT_IIDrE   rW   ZDMI_PRODUCT_COMPUTErT   ZDMI_ASSET_TAG_OPENTELEKOMZDMI_ASSET_TAG_SAPCCLOUDZDMI_ASSET_TAG_HUAWEICLOUDrU   ZSourceMixinr    r   r^   rP   ZDEP_FILESYSTEMZDEP_NETWORKrb   rc   r   r   r   r   Ú<module>   sD   
 ÿý ]
	
þ