
"T`d                 @   s  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 d  d l m Z d  d l m	 Z	 d  d l m
 Z
 d  d l m Z d  d l m Z d  d l m Z d  d	 l m Z e j e  Z d
 d d d   d f d d e j i  f d d d d   d f i Z d> Z 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 d? Z  Gd/ d0   d0 e!  Z" Gd1 d2   d2 e#  Z$ Gd3 d4   d4 d5 e  j% Z& Gd6 d7   d7 e&  Z' Gd8 d9   d9 e&  Z( d d d: d;  Z) d S)@    N)	ec2_utils)log)net)sources)subp)
url_helper)util)BrokenMetadatazetc/network/interfacesnetwork_configc             C   s   |  S)N )xr   r   E/usr/lib/python3/dist-packages/cloudinit/sources/helpers/openstack.py<lambda>   s    r    zmeta.jsmeta_jszroot/.ssh/authorized_keysauthorized_keysc             C   s   |  S)Nr   )r   r   r   r   r       s    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#   U   s   r#   c               @   sL   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
   Z d S)SourceMixinc             C   sS   |  j  s d  S|  j  j d i   } x* | j   D] \ } } | | k r/ | Sq/ Wd  S)Nzblock-device-mapping)Zec2_metadatagetitems)selfnameZbdmZent_namedevicer   r   r   _ec2_name_to_deviceZ   s    	zSourceMixin._ec2_name_to_devicec             C   s4   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_keysc   s    zSourceMixin.get_public_ssh_keysc             C   se   d  } yC d | } | d k r) d | } t  j |  } | rH | d } Wn t j k
 r` Yn 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_devicei   s    

zSourceMixin._os_name_to_devicec             C   su   | s
 d  S| j  d  s# d | } t j j |  r9 | S|  j t j j |   } | rq t j d | |  | Sd  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_namev   s    
z!SourceMixin._validate_device_namec             C   s  | s
 d  S| g } | d k r/ | j  d d  | d k rH | j d  d  } t j d |  x3 | D]+ } |  j |  } |  j |  } | re Pqe W| s t j d |  x3 | D]+ } |  j |  } |  j |  } | r Pq W| s d  St j d | |  | Sd  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appendr9   r:   r-   r;   r2   )r*   r+   namesr,   nr   r   r   device_name_to_device   s2    	z!SourceMixin.device_name_to_deviceN)r$   r%   r&   r-   r1   r2   r;   rA   r   r   r   r   r'   Y   s
   	r'   c               @   s   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*   rC   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*   r6   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    } WnA t k
 rS } z! t j d |  j |  g  } WYd  d  } ~ Xn Xd d   t t t   D } t } x$ | D] } | | k r q | } Pq Wt j d | |  | S)Nz4Unable to read openstack versions from %s due to: %sc             S   s   g  |  ] } |  q Sr   r   ).0vr   r   r   
<listcomp>   s   	 z4BaseReader._find_working_version.<locals>.<listcomp>zSelected version '%s' from %s)	rJ   	Exceptionr9   r:   rC   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 } | sS t d |   |  j |  j d |  } |  j | d | S)	NZcontent_pathr   r3   c             S   s"   g  |  ] } t  |  r |  q Sr   )len)rL   pr   r   r   rN      s   	 z1BaseReader._read_content_path.<locals>.<listcomp>z!Item %s has no valid content path	openstackrH   )r(   lstripsplitr	   rG   rC   rI   )r*   itemrH   r6   Zpath_piecesZvalid_piecesr   r   r   _read_content_path   s    zBaseReader._read_content_pathc          (      s  t  j t j d t t t f      f d d   } d d d d i } |  j    } x>| j   D]0\ } \ } } }  j	  j
 |  } d } d	 } y  j |  } WnT t k
 r}	 z4 | s t j d
 | |	  n t j d | |	  WYd d }	 ~	 Xn Xd } | r*| r*t d |   | r| ry | |  } Wn> t k
 r}	 z t d | |	 f  |	  WYd d }	 ~	 Xn X| rg | | | <qg W| d }
 d |
 k r|
 d } y t j |  |
 d <Wn> t t f k
 r}	 z t d |	  |	  WYd d }	 ~	 Xn Xi  } |
 j d g   } x | D]w } d | k rGq2| d } y  j |  | | <Wq2t k
 r}	 z t d | |	 f  |	  WYd d }	 ~	 Xq2Xq2W| | d <|
 j d d  } | r-y#  j | d d } | | d <Wn8 t k
 r,}	 z t d |	  |	  WYd d }	 ~	 Xn Xy |
 d d | d <Wn t k
 rWYn X j   | d <xX t D]P \ } } } | r| |
 k rt d |   | |
 k ro|
 j |  |
 | <qoW| 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)NrX   zmeta_data.jsonTr0   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)rG   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: %sr0   random_seedz.Badly formatted metadata random_seed entry: %sr_   r6   z#Failed to read provided file %s: %sr
   rH   z(Failed to read network configuration: %smetadsmodezec2-metadatazNo '%s' entry in metadata)	functoolspartialr   r^   dictrQ   strrU   r)   rG   rC   rI   IOErrorr9   r:   r#   rO   r	   base64Z	b64decode
ValueError	TypeErrorr(   r\   KeyErrorrK   
KEY_COPIES)r*   ra   resultsdatar+   r6   Zrequired
translatorfoundrT   r0   rc   r_   Zmetadata_filesr[   Znet_itemcontentZ
target_keyZ
source_keyZis_requiredr   )r`   r*   r   read_v2   s    	!"		





zBaseReader.read_v2N)r$   r%   r&   rD   abcabstractmethodrG   rI   rJ   rK   rU   r\   ru   r   r   r   r   rB      s   	rB   	metaclassc                   sa   e  Z d  Z   f d d   Z d d   Z d d d  Z d d	   Z d
 d   Z d d   Z   S)ConfigDriveReaderc                s#   t  t |   j |  d  |  _ d  S)N)superry   rD   	_versions)r*   rC   )	__class__r   r   rD   b  s    zConfigDriveReader.__init__c             G   s#   | g t  |  } t j j |   S)N)rQ   r5   r6   join)r*   rE   rF   Z
componentsr   r   r   rG   f  s    zConfigDriveReader._path_joinFc             C   s   t  j | d | S)NrH   )r   Z	load_file)r*   r6   rH   r   r   r   rI   j  s    zConfigDriveReader._path_readc                s\   |  j  d  k rU |  j |  j d      f d d   t j    D } t |  |  _  |  j  S)NrX   c                s4   g  |  ]* } t  j j t  j j     r |  q Sr   )r5   r6   isdirr}   )rL   d)r6   r   r   rN   p  s   	 z?ConfigDriveReader._fetch_available_versions.<locals>.<listcomp>)r{   rG   rC   r5   listdirsorted)r*   rs   r   )r6   r   rJ   m  s
    "z+ConfigDriveReader._fetch_available_versionsc             C   s   |  j  |  j d d d  } t j j |  s1 i  Sy t j |  j |   SWn> t k
 r } z t	 d | | f  |  WYd  d  } ~ Xn Xd  S)NZec2r   zmeta-data.jsonzFailed to process path %s: %s)
rG   rC   r5   r6   r7   r   r^   rI   rO   r	   )r*   r6   rT   r   r   r   rK   u  s    z$ConfigDriveReader._read_ec2_metadatac             C   s'  i  } xE t  j   D]7 } |  j |  j |  } t j j |  r | | | <q Wt |  d k rs t d |  j   i  } x t  j	   D] \ } \ } } } | | k rW| | } y |  j
 |  } Wn8 t k
 r }	 z t d |  |	  WYd d }	 ~	 Xn Xy | |  | | <Wqjt k
 rS}	 z t d | |	 f  |	  WYd d }	 ~	 XqjXq t j |  | | <q W| d }
 | d } | j d |
  }
 |
 r|
 j   } d	 d
   | D | d <d | k r| d | d <d d d | i } 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   s2   g  |  ]( } t  |  r | j d   r |  q S)#)rV   r4   )rL   liner   r   r   rN     s   	z-ConfigDriveReader.read_v1.<locals>.<listcomp>zinstance-idr/   r.   r0   re   z	user-datar   r]   r_   )FILES_V1keysrG   rC   r5   r6   r7   rV   r#   r)   rI   rj   r	   rO   copydeepcopyr(   
splitlines)r*   rs   r+   r6   Zmdkeyrr   defaultcontentsrT   Zkeydatar   linesrp   r   r   r   read_v1  sL    "
&

	
zConfigDriveReader.read_v1)	r$   r%   r&   rD   rG   rI   rJ   rK   r   r   r   )r|   r   ry   a  s   ry   c                   s^   e  Z d  Z d d d   f d d  Z d d   Z d d d	  Z d
 d   Z d d   Z   S)MetadataReaderN   c                sJ   t  t |   j |  | |  _ t |  |  _ t |  |  _ d  |  _ d  S)N)	rz   r   rD   ssl_detailsfloattimeoutintretriesr{   )r*   Zbase_urlr   r   r   )r|   r   r   rD     s
    	zMetadataReader.__init__c             C   s   |  j  d  k	 r |  j  Sg  } |  j |  j d  } |  j | d d } x6 | j   D]( } | j   } | sn qS | j |  qS W| |  _  |  j  S)NrX   rH   T)r{   rG   rC   rI   r   stripr>   )r*   rs   Zversion_pathrt   r   r   r   r   rJ     s    	z(MetadataReader._fetch_available_versionsFc          
   C   sZ   d d   } t  j | d |  j d |  j d |  j d | } | rO | j j   S| j Sd  S)Nc             S   sB   y# t  | j  } | d k r" d SWn t t f k
 r= Yn Xd S)Ni  FT)r   coderm   rl   )Z_request_argscauser   r   r   r   should_retry_cb  s    z2MetadataReader._path_read.<locals>.should_retry_cbr   r   r   Zexception_cb)r   Zreadurlr   r   r   r   rH   )r*   r6   rH   r   Zresponser   r   r   rI     s    
				zMetadataReader._path_readc             G   s   t  j | |  S)N)r   Zcombine_url)r*   rE   rF   r   r   r   rG     s    zMetadataReader._path_joinc             C   s%   t  j d |  j d |  j d |  j  S)Nr   r   r   )r   Zget_instance_metadatar   r   r   )r*   r   r   r   rK     s    	z!MetadataReader._read_ec2_metadata)r$   r%   r&   rD   rJ   rI   rG   rK   r   r   )r|   r   r     s
   r   c                s  |  d k r d Sd d d d d d d g d	 d d
 d d d d d d d d d g i  |  j  d g   } |  j  d g   } |  j  d g   } g  } i   d } d } g  } xJ| D]B g  }	 t  f d d    j   D  }
 d  k r  d |
 d <d }  j  d  r3 j  d  j   } |   d <d |
 j  d  d | d  d d  d i } x f d d   | D D]} t  f d  d   | j   D  } | d d! k r| j d d" i  n | d d# k r| j d d$ i  n | d dD k r| j d | d i  nz | d dE k rR| j d d) d
 | j  d*  i  nE | d dF k r|
 j d- d. i  | j d d, d
 | j  d*  i  | d dG k r|
 j d- d/ i  | d d( k rd/ | d( <| d d+ k rd/ | d+ <|	 j |  q|W|
 j d |	 i   d dH k ri  } | r8| | d <xN  j   D]@ \ } } | d1 k rcqEqE| j d0  rE| j | | i  qEW| | } | d2 7} | j |
 d3 d4 t j  d1  f  |
 j d | d | i  | | d <n  d dI k rd6  d7  d8 f } |
 j d | d8  d8 d  d9 i  | j |
 d7 d4  d7 f  | j |
 d d:  d8  d7 f  | j d  d9 d | i  n=  d t	 k rt
 j d;  d  |
 j d d d | i  | j |
  |  | d <q Wd< d   | D } | s| rN| d k r-t j   } xS  j   D]E \ } } | j  d  rXq:| j  d  | k r:| | d | d <q:Wx] | D]U } | j  d  } | st d= |   | | k rt d> |   | | | d <qWxh | D]` \ }
 }   } t | t t f  r4   f d? d   | D |
 | <q   | d |
 | <qWt j   } | rx: | D]2 }
 |
 d | k rg| |
 d |
 d <d@ |
 d <qgWx4 | D], } | }
 |
 j d dA i  | j |
  qWdB d2 dC | i S)Ja)  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.
    Nphysicalr+   typeZmac_addresssubnetsparamsZmtusubnetZaddressZnetmaskZ	broadcastZmetricZgatewayZpointopointZscopeZdns_nameserversZ
dns_searchZrouteslinksnetworksserviceszbond%dr   c             3   s1   |  ]' \ } } |   d  k r | | f Vq d S)r   Nr   )rL   krM   )
valid_keysr   r   	<genexpr>E  s    	z#convert_net_json.<locals>.<genexpr>Zethernet_mac_addressidmacc                s*   g  |  ]  } | d    d k r |  q S)linkr   r   )rL   r@   )r   r   r   rN   V  s   	 z$convert_net_json.<locals>.<listcomp>c             3   s1   |  ]' \ } } |   d  k r | | f Vq d S)r   Nr   )rL   r   rM   )r   r   r   r   X  s    	Z	ipv4_dhcpZdhcp4	ipv6_dhcpZdhcp6
ipv6_slaacipv6_dhcpv6-statelessipv6_dhcpv6-statefulipv4staticZ
ip_addressipv6static6z	accept-raFTbondZ
bond_linksr.   Zbond_interfacesz%svlanz%s.%sZ	vlan_linkZvlan_idZvlan_mac_addressz%%s.%sz9Unknown network_data link type (%s); treating as physicalc             S   s7   g  |  ]- } | j  d   d k r d | k r |  q S)r   r   r+   )r(   )rL   r   r   r   r   rN     s   	 z#No mac_address or name entry for %sz"Unable to find a system nic for %sc                s"   g  |  ] }    | d   q S)r+   r   )rL   target)fmtlink_id_infor   r   rN     s   	 Z
infinibandZ
nameserverr/   config)r   r   r   )r   r   )r   r   )r   r   )r   )r   )r(   rh   r)   lowerupdater>   r4   r   r   KNOWN_PHYSICAL_TYPESr9   Zwarningr   Zget_interfaces_by_macrl   
isinstancerQ   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   rM   Z	link_namer+   Z
need_namesZ_link_idinfor   r   r   ZtargetsZib_known_hwaddrsservicer   )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"   )*rv   rk   r   rf   r5   Z	cloudinitr   r   Zloggingr   r   r   r   r   Zcloudinit.sourcesr	   Z	getLoggerr$   r9   r^   r   ro   rS   Z	OS_FOLSOMZ
OS_GRIZZLYZ	OS_HAVANAZ
OS_LIBERTYZOS_NEWTON_ONEZOS_NEWTON_TWOZOS_OCATAZOS_ROCKYrR   r   rj   r#   objectr'   ABCMetarB   ry   r   r   r   r   r   r   <module>	   sl    	            Lk7