o
    w7e)                     @   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 ComputeOpenTelekomCloudzSAP CCloud VM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 )DataSourceOpenStack	OpenStackFc                    sH   t t| ||| d | _t| j| _d | _i | _	t
j| _t
j| _d S N)superr   __init__metadata_addressr   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   rootmstrr"   r"   r#   r%   G   s   zDataSourceOpenStack.__str__c                 C   s  | j dt}dd |D }t|t|kr$tdtt|t|  t|r+|}ntd t}g }i }|D ]}t	
|d}|| |||< q8|  }t }t	j||j|jdd\}	}
|	rjtd	||	  ntd
|tt |  ||	| _t|	S )Nmetadata_urlsc                 S   s   g | ]	}t |r|qS r"   )r   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)urlsmax_waittimeout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   combine_urlappendget_url_paramstimewait_for_urlmax_wait_secondstimeout_secondsintr   bool)r   r.   filteredmd_urlsurl2baseurlmd_url
url_params
start_time	avail_url	_responser"   r"   r#   wait_for_metadata_serviceL   sD   



z-DataSourceOpenStack.wait_for_metadata_servicec                 C   s   t |  S r   )r   instance_id_matches_system_uuid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rd| _ | j S | jtjkr&t	d dS t
d tj| jdd| _ | j S )z@Return a network config dict for rendering ENI or netplan files.apply_network_configTNz<Unexpected call to network_config when network_json is None.z(network config provided via network_json)
known_macs)_network_configr   r   r   is_falser2   r3   r   r6   r:   r7   r   convert_net_json)r   r"   r"   r#   network_configy   s   
z"DataSourceOpenStack.network_configc              
   C   s  | j rEz#t| j| j tjtjd| jd}W d   n1 s w   Y  W nA t	t
jfyD } zttt| W Y d}~dS d}~ww z|  }W n t
jyg } zttt| W Y d}~dS d}~ww | |dg| _| jt
jkrzdS |di }t|tg}|| _|d| _|d| _|d	| _|d
 | _| j|di  |d}|| _zt
|| _W n ty } ztd| d| _W Y d}~nd}~ww |d}|| _ z	t
|| _!W dS  ty } ztd| d| _!W Y d}~dS d}~ww )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)logfuncmsgfuncNFr&   metadatazec2-metadatanetworkdatauserdatar   r   
vendordataz"Invalid content in vendor-data: %svendordata2z#Invalid content in vendor-data2: %sT)"perform_dhcp_setupr
   r   fallback_interfacer   log_timer6   r7   _crawl_metadatar	   r   InvalidMetaDataExceptionlogexcstr_determine_dsmoder3   r&   DSMODE_DISABLEDmergemanydictDEFAULT_METADATArZ   r   r   userdata_rawr   r   updatevendordata_pureconvert_vendordatavendordata_raw
ValueErrorr:   vendordata2_purevendordata2_raw)r   resultsemdvdvd2r"   r"   r#   	_get_data   sj   


zDataSourceOpenStack._get_datac              
   C   s   z|   s
tdW n ty" } ztdjt|dd}~ww |  }ztjt	j
dt| jg| j|j|jdd}W |S  tjyR } ztt|d}~w tjtfym } zdj| jd	}t||d}~ww )
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})errorNz#Crawl of openstack metadata service)r   retriesr0   )argskwargszBroken metadata address {addr})addr)rM   r   rc   IOErrorformatre   r=   r   ra   r6   r7   read_metadata_servicer   r   num_retriesrA   r   NonReadableBrokenMetadata)r   rs   rI   resultrX   r"   r"   r#   rb      sJ   z#DataSourceOpenStack._crawl_metadatac                 C   sp   d| j dv }t sdS td}|tv rdS tdtv r"dS |r*t	 r*dS t
ddtkr6dS dS )	z<Return True when a potential OpenStack platform is detected.Oracledatasource_listTzsystem-product-namezchassis-asset-tag   product_nameF)r   r3   r   is_x86r   read_dmi_dataVALID_DMI_PRODUCT_NAMESVALID_DMI_ASSET_TAGSoracle_is_platform_viableget_proc_envDMI_PRODUCT_NOVA)r   accept_oracler   r"   r"   r#   	ds_detect   s   
zDataSourceOpenStack.ds_detect)__name__
__module____qualname__dsnamer   r   rS   r_   r   NETWORKr   BOOT_NEW_INSTANCEBOOTBOOT_LEGACYHOTPLUGsupported_update_eventsr   r%   rM   rP   propertyrV   rw   rb   r   __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)r   r   r   __doc__r_   r"   r"   r"   r#   r     s    r      c                 C   s   t j| |||d}| S )N)r   r0   ry   )r   MetadataReaderread_v2)base_urlr   r0   ry   readerr"   r"   r#   r     s   r   c                 C   s   t | tS r   )r   list_from_dependsdatasources)dependsr"   r"   r#   get_datasource_list#  s   r   )Nr   r   )*r>   	cloudinitr   r   loggingr   r   r   cloudinit.eventr   r   cloudinit.net.dhcpr	   cloudinit.net.ephemeralr
   cloudinit.sourcesr   r   cloudinit.sources.helpersr   	getLoggerr   r6   r4   DEFAULT_IIDri   r   DMI_PRODUCT_COMPUTEr   DMI_ASSET_TAG_OPENTELEKOMDMI_ASSET_TAG_SAPCCLOUDDMI_ASSET_TAG_HUAWEICLOUDr   SourceMixinr$   r   r   r   DEP_FILESYSTEMDEP_NETWORKr   r   r"   r"   r"   r#   <module>   sD   
 ]

	