
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
cjzf                 @   s6  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZ d dlmZ d dlmZ ejeZddd dfd	eji fd
dd dfdZd7ZdZdZdZdZdZdZdZdZdZeeeeeeeefZd8Z G d(d) d)e!Z"G d*d+ d+Z#G d,d- d-e j$d.Z%G d/d0 d0e%Z&G d1d2 d2e%Z'd9d3d4Z(dS ):    N)netsourcessubp
url_helperutil)BrokenMetadata)ec2network_configc             C   s   | S )N )xr
   r
   /usr/lib/python3.6/openstack.py<lambda>   s    r    meta_jsauthorized_keysc             C   s   | S )Nr
   )r   r
   r
   r   r      s    )zetc/network/interfaceszmeta.jszroot/.ssh/authorized_keyslocal-hostnamehostnameFinstance-iduuidTlatestz
2012-08-10z
2013-04-04z
2013-10-17z
2015-10-15z
2016-06-30z
2016-10-06z
2017-02-22z
2018-08-27bgpovsbridge	cascadingdvsethernethw_vebhypervovsphytap	vhostuservifc               @   s   e Zd ZdS )NonReadableN)__name__
__module____qualname__r
   r
   r
   r   r"   Q   s   r"   c               @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )SourceMixinc             C   s>   | j s
d S | j jdi }x |j D ]\}}||kr"|S q"W d S )Nzblock-device-mapping)Zec2_metadatagetitems)selfnameZbdmZent_namedevicer
   r
   r   _ec2_name_to_deviceV   s    zSourceMixin._ec2_name_to_devicec             C   s$   d}| j dkrd}tj| jj|S )NZpublic_keys   zpublic-keys)versionr   Znormalize_pubkey_datametadatar'   )r)   r*   r
   r
   r   get_public_ssh_keys_   s    
zSourceMixin.get_public_ssh_keysc             C   sR   d }y2d| }|dkrd| }t j|}|r4|d }W n tjk
rL   Y nX |S )NzLABEL=%sZswapzTYPE=%sr   )r   Zfind_devs_withr   ZProcessExecutionError)r)   r*   r+   ZcriteriaZdev_entriesr
   r
   r   _os_name_to_devicee   s    
zSourceMixin._os_name_to_devicec             C   sV   |sd S |j dsd| }tjj|r*|S | jtjj|}|rRtjd|| |S d S )N/z/dev/%szRemapped device name %s => %s)
startswithospathexistsZ_remap_devicebasenameLOGdebug)r)   r+   Zremappedr
   r
   r   _validate_device_namer   s    
z!SourceMixin._validate_device_namec             C   s   |sd S |g}|dkr"|j dd |dkr4|jd d }tjd| x&|D ]}| j|}| j|}|rJP qJW |stjd| x&|D ]}| j|}| j|}|rP qW |sd S tjd|| |S d S )Nrootr   Zamiz(Using ec2 style lookup to find device %sz.Using openstack style lookup to find device %szMapped %s to device %s)insertappendr8   r9   r,   r:   r1   )r)   r*   namesr+   nr
   r
   r   device_name_to_device   s2    






z!SourceMixin.device_name_to_deviceN)r#   r$   r%   r,   r0   r1   r:   r@   r
   r
   r
   r   r&   U   s
   	r&   c               @   sh   e Zd Zdd Zejdd ZejdddZejdd	 Zejd
d Z	dd Z
dddZdd ZdS )
BaseReaderc             C   s
   || _ d S )N)	base_path)r)   rB   r
   r
   r   __init__   s    zBaseReader.__init__c             G   s   d S )Nr
   )r)   baseadd_onsr
   r
   r   
_path_join   s    zBaseReader._path_joinFc             C   s   d S )Nr
   )r)   r5   decoder
   r
   r   
_path_read   s    zBaseReader._path_readc             C   s   d S )Nr
   )r)   r
   r
   r   _fetch_available_versions   s    z$BaseReader._fetch_available_versionsc             C   s   d S )Nr
   )r)   r
   r
   r   _read_ec2_metadata   s    zBaseReader._read_ec2_metadatac             C   s   y| j  }W n6 tk
rB } ztjd| j| g }W Y d d }~X nX dd tttD }t}x|D ]}||krrqd|}P qdW tjd|| |S )Nz4Unable to read openstack versions from %s due to: %sc             S   s   g | ]}|qS r
   r
   ).0vr
   r
   r   
<listcomp>   s    z4BaseReader._find_working_version.<locals>.<listcomp>zSelected version '%s' from %s)	rI   	Exceptionr8   r9   rB   reversedlistOS_VERSIONS	OS_LATEST)r)   Zversions_availableeZ	supportedZselected_versionZpotential_versionr
   r
   r   _find_working_version   s(    
z BaseReader._find_working_versionc             C   s\   |j ddjd}|jd}dd |D }|s:td| | j| jdf| }| j||dS )	NZcontent_pathr   r2   c             S   s   g | ]}t |r|qS r
   )len)rK   pr
   r
   r   rM      s    z1BaseReader._read_content_path.<locals>.<listcomp>z!Item %s has no valid content path	openstack)rG   )r'   lstripsplitr   rF   rB   rH   )r)   itemrG   r5   Zpath_piecesZvalid_piecesr
   r
   r   _read_content_path   s    
zBaseReader._read_content_pathc          (      s  t jtjtttfd  fdd}ddd}|j }x|j D ]\}\}}}j	j
|}d}d}yj|}W nD tk
r }	 z(|stjd	||	 ntjd
||	 W Y dd}	~	X nX d}|r| rtd| |o|r$y||}W n6 tk
r" }	 ztd||	f |	W Y dd}	~	X nX |rD|||< qDW |d }
d|
kr|
d }ytj||
d< W n6 ttfk
r }	 ztd|	 |	W Y dd}	~	X nX i }|
jdg }xn|D ]f}d|krq|d }yj|||< W n6 tk
r }	 ztd||	f |	W Y dd}	~	X nX qW ||d< |
jdd}|ryj|dd}||d< W n2 tk
r~ }	 ztd|	 |	W Y dd}	~	X nX y|
d d |d< W n tk
r   Y nX j |d< xHtD ]@\}}}|r||
krtd| ||
kr|
j||
|< qW |S )zReads a version 2 formatted location.

        Return a dict with metadata, userdata, ec2-metadata, dsmode,
        network_config, files and version (2).

        If not a valid location, raise a NonReadable exception.
        )Z
root_typesc                s   i }j d| ddtjf|d< j d| dddd f|d	< j d| d
d f|d< j d| dd f|d< j d| dd f|d< |S )NrW   zmeta_data.jsonTr/   Z	user_dataFc             S   s   | S )Nr
   )r   r
   r
   r   r      s    z7BaseReader.read_v2.<locals>.datafiles.<locals>.<lambda>userdatazvendor_data.jsonZ
vendordatazvendor_data2.jsonZvendordata2znetwork_data.jsonZnetworkdata)rF   r   	load_json)r.   files)load_json_anytyper)   r
   r   	datafiles   s"    


z%BaseReader.read_v2.<locals>.datafilesr      )r\   r.   NFz*Failed reading optional path %s due to: %sz+Failed reading mandatory path %s due to: %sTzMissing mandatory path: %szFailed to process path %s: %sr/   random_seedz.Badly formatted metadata random_seed entry: %sr^   r5   z#Failed to read provided file %s: %sr	   )rG   z(Failed to read network configuration: %smetadsmodezec2-metadatazNo '%s' entry in metadata)	functoolspartialr   r]   dictrP   strrT   r(   rF   rB   rH   IOErrorr8   r9   r"   rN   r   base64Z	b64decode
ValueError	TypeErrorr'   r[   KeyErrorrJ   
KEY_COPIES)r)   r`   resultsdatar*   r5   Zrequired
translatorfoundrS   r/   rb   r^   Zmetadata_filesrZ   Znet_itemcontentZ
target_keyZ
source_keyZis_requiredr
   )r_   r)   r   read_v2   s    	!





zBaseReader.read_v2N)F)F)r#   r$   r%   rC   abcabstractmethodrF   rH   rI   rJ   rT   r[   rt   r
   r
   r
   r   rA      s   
	rA   )	metaclassc                   sF   e Zd Z fddZdd ZdddZdd	 Zd
d Zdd Z  Z	S )ConfigDriveReaderc                s   t t| j| d | _d S )N)superrx   rC   	_versions)r)   rB   )	__class__r
   r   rC   f  s    zConfigDriveReader.__init__c             G   s   |gt | }tjj| S )N)rP   r4   r5   join)r)   rD   rE   Z
componentsr
   r
   r   rF   j  s    zConfigDriveReader._path_joinFc             C   s   t j||dS )N)rG   )r   Z	load_file)r)   r5   rG   r
   r
   r   rH   n  s    zConfigDriveReader._path_readc                s@   | j d kr:| j| jd  fddtj D }t|| _ | j S )NrW   c                s$   g | ]}t jjt jj r|qS r
   )r4   r5   isdirr|   )rK   d)r5   r
   r   rM   u  s   z?ConfigDriveReader._fetch_available_versions.<locals>.<listcomp>)rz   rF   rB   r4   listdirsorted)r)   rr   r
   )r5   r   rI   q  s    


z+ConfigDriveReader._fetch_available_versionsc             C   sl   | j | jddd}tjj|s"i S ytj| j|S  tk
rf } zt	d||f |W Y d d }~X nX d S )Nr   r   zmeta-data.jsonzFailed to process path %s: %s)
rF   rB   r4   r5   r6   r   r]   rH   rN   r   )r)   r5   rS   r
   r
   r   rJ   |  s    z$ConfigDriveReader._read_ec2_metadatac             C   s  i }x2t j D ]&}| j| j|}tjj|r|||< qW t|dkrRtd| j i }xt j	 D ]\}\}}}||kr
|| }y| j
|}W n0 tk
r }	 ztd| |	W Y dd}	~	X nX y||||< W n6 tk
r }	 ztd||	f |	W Y dd}	~	X nX q`tj|||< q`W |d }
|d }|jd|
}
|
rX|
j }d	d
 |D |d< d|krn|d |d< d|d}d|kr|d |d< |jdd|d< i |d< |S )zReads a version 1 formatted location.

        Return a dict with metadata, userdata, dsmode, files and version (1).

        If not a valid path, raise a NonReadable exception.
        r   z%s: no files foundzFailed to read: %sNzFailed to process path %s: %sr   r   zpublic-keysc             S   s$   g | ]}t |r|jd  r|qS )#)rU   r3   )rK   liner
   r
   r   rM     s   z-ConfigDriveReader.read_v1.<locals>.<listcomp>zinstance-idr-   )r.   r/   rd   z	user-datar   r\   r^   )FILES_V1keysrF   rB   r4   r5   r6   rU   r"   r(   rH   ri   r   rN   copydeepcopyr'   
splitlines)r)   rr   r*   r5   Zmdkeyrq   defaultcontentsrS   Zkeydatar   linesro   r
   r
   r   read_v1  sL    
 

zConfigDriveReader.read_v1)F)
r#   r$   r%   rC   rF   rH   rI   rJ   r   __classcell__r
   r
   )r{   r   rx   e  s   
rx   c                   s@   e Zd Zd fdd	Zdd Zddd	Zd
d Zdd Z  ZS )MetadataReaderN   c                s4   t t| j| || _t|| _t|| _d | _d S )N)	ry   r   rC   ssl_detailsfloattimeoutintretriesrz   )r)   Zbase_urlr   r   r   )r{   r
   r   rC     s
    

zMetadataReader.__init__c             C   sf   | j d k	r| j S g }| j| jd}| j|dd}x(|j D ]}|j }|sLq:|j| q:W || _ | j S )NrW   T)rG   )rz   rF   rB   rH   r   stripr=   )r)   rr   Zversion_pathrs   r   r
   r
   r   rI     s    
z(MetadataReader._fetch_available_versionsFc             C   s:   dd }t j|| j| j| j|d}|r0|jj S |jS d S )Nc             S   s8   yt |j}|dkrdS W n ttfk
r2   Y nX dS )Ni  FT)r   coderl   rk   )Z_request_argscauser   r
   r
   r   should_retry_cb  s    
z2MetadataReader._path_read.<locals>.should_retry_cb)r   r   r   Zexception_cb)r   Zreadurlr   r   r   r   rG   )r)   r5   rG   r   Zresponser
   r
   r   rH     s    

zMetadataReader._path_readc             G   s   t j|f| S )N)r   Zcombine_url)r)   rD   rE   r
   r
   r   rF     s    zMetadataReader._path_joinc             C   s   t j| j| j| jdS )N)r   r   r   )r   Zget_instance_metadatar   r   r   )r)   r
   r
   r   rJ     s    z!MetadataReader._read_ec2_metadata)Nr   r   )F)	r#   r$   r%   rC   rI   rH   rF   rJ   r   r
   r
   )r{   r   r     s
   
r   c                sx  | dkrdS ddddddgddd	d
dddddddgd| j dg }| j dg }| j dg }g }i d}d}g }xr|D ]hg }	tfddj D }
dkrd |
d< d}j dr؈j dj }|d < |
j d|d d d}xdfdd|D D ]L}tfdd|j D }|d d krH|jdd!i n|d d"krf|jdd#i nz|d dJkr|jd|d i nX|d dKkr|jd(|j d)d* n2|d dLkr|
jd-d.i |jd,|j d)d* d/d |j dg D }|r||d< |d dMkr |
jd-d0i |d d'kr6d0|d'< |d d+krLd0|d+< |	j| q
W |
jd|	i d dNkri }|r|
jd|i x@j D ]4\}}|d2krqn|jd1r|j||i qW || }|d37 }|j|
d4d5tjd2 f |
j||d6 ||d< nd dOkrd8d9 d: f }|
j|d: d; d< |j|
d9d5d9 f |j|
dd=d:  d9 f |jd; |d> n.d t	krt
jd?d  |
jd@|dA |j|
 ||d < qxW dBd |D }|s |r|dkrtj }xFj D ]:\}}|j dr4q|j dC|kr||dC  |d< qW xL|D ]D}|j d}|stdD| ||krtdE| || |d< q`W xT|D ]L\}
} }t|ttfr fdFd|D |
|< n | d  |
|< qW tj }|rBx4|D ],}
|
d |kr||
d  |
d< dG|
d< qW x*|D ]"}|}
|
jddHi |j|
 qHW d3|dIS )Pa)  Return a dictionary of network_config by parsing provided
       OpenStack ConfigDrive NetworkData json format

    OpenStack network_data.json provides a 3 element dictionary
      - "links" (links are network devices, physical or virtual)
      - "networks" (networks are ip network configurations for one or more
                    links)
      -  services (non-ip services, like dns)

    networks and links are combined via network items referencing specific
    links via a 'link_id' which maps to a links 'id' field.

    To convert this format to network_config yaml, we first iterate over the
    links and then walk the network list to determine if any of the networks
    utilize the current link; if so we generate a subnet entry for the device

    We also need to map network_data.json fields to network_config fields. For
    example, the network_data links 'id' field is equivalent to network_config
    'name' field for devices.  We apply more of this mapping to the various
    link types that we encounter.

    There are additional fields that are populated in the network_data.json
    from OpenStack that are not relevant to network_config yaml, so we
    enumerate a dictionary of valid keys for network_yaml and apply filtering
    to drop these superflous keys from the network_config yaml.
    Nr*   typemac_addresssubnetsparamsZmtuaddressZnetmaskZ	broadcastZmetricZgatewayZpointopointZscopedns_nameserversZ
dns_searchZroutes)physicalsubnetlinksnetworksserviceszbond%dr   c             3   s&   | ]\}}| d  kr||fV  qdS )r   Nr
   )rK   krL   )
valid_keysr
   r   	<genexpr>Q  s    z#convert_net_json.<locals>.<genexpr>Zethernet_mac_addressid)r*   macr   r   c                s    g | ]}|d   d kr|qS )linkr   r
   )rK   r?   )r   r
   r   rM   f  s    z$convert_net_json.<locals>.<listcomp>c             3   s&   | ]\}}| d  kr||fV  qdS )r   Nr
   )rK   r   rL   )r   r
   r   r   h  s    Z	ipv4_dhcpZdhcp4	ipv6_dhcpZdhcp6
ipv6_slaacipv6_dhcpv6-statelessipv6_dhcpv6-statefulipv4staticZ
ip_address)r   r   ipv6static6z	accept-raFc             S   s"   g | ]}|j d dkr|d qS )r   Zdnsr   )r'   )rK   servicer
   r
   r   rM     s   TbondZ
bond_linksr-   Zbond_interfacesz%s)r   r*   vlanz%s.%sZ	vlan_linkvlan_idZvlan_mac_address)r*   r   r   z%%s.%s)r   r*   z9Unknown network_data link type (%s); treating as physicalr   )r   r   c             S   s&   g | ]}|j d dkrd|kr|qS )r   r   r*   )r'   )rK   r~   r
   r
   r   rM     s    r   z#No mac_address or name entry for %sz"Unable to find a system nic for %sc                s   g | ]} | d   qS )r*   r
   )rK   target)fmtlink_id_infor
   r   rM     s    Z
infinibandZ
nameserver)r.   config)r   r   r   )r   r   )r   r   )r   r   )r   )r   )r'   rg   r(   lowerupdater=   r3   r   r   KNOWN_PHYSICAL_TYPESr8   Zwarningr   Zget_interfaces_by_macrk   
isinstancerP   tupleZget_ib_hwaddrs_by_interface)Znetwork_jsonZ
known_macsr   r   r   Zlink_updatesZbond_name_fmtZbond_numberr   r   ZcfgZlink_mac_addrZcurinfoZnetworkr   r   r   r   rL   Z	link_namer*   Z
need_namesZ_link_idinfor~   r   r   ZtargetsZib_known_hwaddrsr   r
   )r   r   r   r   r   convert_net_json  s   

  









r   r   r   Fr   r   T)r   r   )Nr   r   r   r   r   r   r   r   r   r   r    r!   )NN))ru   rj   r   re   Zloggingr4   Z	cloudinitr   r   r   r   r   Zcloudinit.sourcesr   Zcloudinit.sources.helpersr   Z	getLoggerr#   r8   r]   r   rn   rR   Z	OS_FOLSOMZ
OS_GRIZZLYZ	OS_HAVANAZ
OS_LIBERTYZOS_NEWTON_ONEZOS_NEWTON_TWOZOS_OCATAZOS_ROCKYrQ   r   ri   r"   r&   ABCMetarA   rx   r   r   r
   r
   r
   r   <module>	   sf   

             L Eo: