
    ؆ff                        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fdej&                  i fd	d
 dfd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  G d de!      Z" G d d      Z# G d de jH                        Z% G d de%      Z& G d  d!e%      Z'd#d"Z(y)$    N)netsourcessubp
url_helperutil)BrokenMetadata)ec2network_configc                     | S N xs    E/usr/lib/python3/dist-packages/cloudinit/sources/helpers/openstack.py<lambda>r      s    1      meta_jsauthorized_keysc                     | S r   r   r   s    r   r   r      s    q r   )zetc/network/interfaceszmeta.jszroot/.ssh/authorized_keys))z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)Nbgpovsbridge	cascadingdvsethernethw_vebhypervovsphytap	vhostuservifc                       e Zd Zy)NonReadableN)__name__
__module____qualname__r   r   r   r(   r(   Q   s    r   r(   c                   *    e Zd Zd Zd Zd Zd Zd Zy)SourceMixinc                     | j                   sy | j                   j                  di       }|j                         D ]  \  }}||k(  s|c S  y )Nzblock-device-mapping)ec2_metadatagetitems)selfnamebdment_namedevices        r   _ec2_name_to_devicezSourceMixin._ec2_name_to_deviceV   sS      ##$:B?"%))+ 	Xvx	 r   c                     d}| j                   dk(  rd}t        j                  | j                  j	                  |            S )Npublic_keys   public-keys)versionr   normalize_pubkey_datametadatar0   )r2   r3   s     r   get_public_ssh_keyszSourceMixin.get_public_ssh_keys_   s8    <<1 D,,T]]->->t-DEEr   c                     d }	 d|z  }|dk(  rd|z  }t        j                  |      }|r|d   }|S # t        j                  $ r Y |S w xY w)NzLABEL=%sswapzTYPE=%sr   )r   find_devs_withr   ProcessExecutionError)r2   r3   r6   criteriadev_entriess        r   _os_name_to_devicezSourceMixin._os_name_to_devicee   si    	!T*Hv~$---h7K$Q  )) 		s   +1 AAc                 
   |sy |j                  d      sd|z  }t        j                  j                  |      r|S | j	                  t        j                  j                  |            }|rt        j                  d||       |S y )N/z/dev/%szRemapped device name %s => %s)
startswithospathexists_remap_devicebasenameLOGdebug)r2   r6   remappeds      r   _validate_device_namez!SourceMixin._validate_device_namer   sp      %'F77>>&!M%%bgg&6&6v&>?II5vxHOr   c                    |sy |g}|dk(  r|j                  dd       |dk(  r|j                  d       d }t        j                  d|       |D ](  }| j	                  |      }| j                  |      }|s( n |sCt        j                  d|       |D ](  }| j                  |      }| j                  |      }|s( n |sy t        j                  d||       |S )Nrootr   amiz(Using ec2 style lookup to find device %sz.Using openstack style lookup to find device %szMapped %s to device %s)insertappendrO   rP   r7   rR   rF   )r2   r3   namesr6   ns        r   device_name_to_devicez!SourceMixin.device_name_to_device   s    6>LLE"5=LL 		<eD 	A--a0F//7F		 IIFN 00333F;	 II.f=Mr   N)r)   r*   r+   r7   r?   rF   rR   rZ   r   r   r   r-   r-   U   s    Fr   r-   c                       e Zd Zd Zej
                  d        Zej
                  d
d       Zej
                  d        Zej
                  d        Z	d Z
d
dZd Zy	)
BaseReaderc                     || _         y r   )	base_path)r2   r^   s     r   __init__zBaseReader.__init__   s	    "r   c                      y r   r   r2   baseadd_onss      r   
_path_joinzBaseReader._path_join       r   c                      y r   r   r2   rK   decodes      r   
_path_readzBaseReader._path_read   re   r   c                      y r   r   r2   s    r   _fetch_available_versionsz$BaseReader._fetch_available_versions   re   r   c                      y r   r   rk   s    r   _read_ec2_metadatazBaseReader._read_ec2_metadata   re   r   c                 F   	 | j                         }t        t        t                    D cg c]  }| }}t        }|D ]
  }||vr|} n t        j                  d||       |S # t        $ r-}t        j                  d| j                  |       g }Y d }~d }~ww xY wc c}w )Nz4Unable to read openstack versions from %s due to: %szSelected version '%s' from %s)	rl   	ExceptionrO   rP   r^   reversedlistOS_VERSIONS	OS_LATEST)r2   versions_availableev	supportedselected_versionpotential_versions          r   _find_working_versionz BaseReader._find_working_version   s    	$!%!?!?!A !)k): ;<1Q<	<$!* 	 (::0		 			+	

  1  	$IIF
 "$	$ =s   A% 	B%	B.#BBc                 (   |j                  dd      j                  d      }|j                  d      }|D cg c]  }t        |      s| }}|st	        d|z         | j
                  | j                  dg| }| j                  ||      S c c}w )Ncontent_pathr   rH   z!Item %s has no valid content path	openstackrh   )r0   lstripsplitlenr   rd   r^   ri   )r2   itemrh   rK   path_piecespvalid_piecess          r   _read_content_pathzBaseReader._read_content_path   s    xx+2237jjo#.9a#a&99 !D!MNNtt~~{I[ItF33	 :s   BBc                 F    t        j                  t        j                  t        t
        t        f       fd}ddd} | j                               }|j                         D ]d  \  }\  }}} j                   j                  |      }d}d}	  j                  |      }d}|r|st        d|z        |r|r		  ||      }|s`|||<   f |d   }
d|
v r|
d   }	 t%        j&                  |      |
d<   i }|
j-                  dg       }|D ]!  }d|vr|d   }	  j/                  |      ||<   # ||d<   |
j-                  dd      }|r	  j/                  |d      }||d<   	 |
d   d   |d<    j3                         |d<   t4        D ]3  \  }}}|r||
vrt#        d|z        ||
v s |
j-                  |      |
|<   5 |S # t        $ r<}	|st        j                  d	||	       nt        j                  d
||	       Y d}	~	Yd}	~	ww xY w# t         $ r}	t#        d|d|	      |	d}	~	ww xY w# t(        t*        f$ r}	t#        d|	z        |	d}	~	ww xY w# t         $ r}	t#        d|d|	      |	d}	~	ww xY w# t        $ r}	t#        d|	z        |	d}	~	ww xY w# t0        $ r Y 1w xY w)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.
        )
root_typesc                 $   i }j                  d| d      dt        j                  f|d<   j                  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 )Nr~   zmeta_data.jsonTr>   	user_dataFc                     | S r   r   r   s    r   r   z7BaseReader.read_v2.<locals>.datafiles.<locals>.<lambda>   s    ! r   userdatazvendor_data.json
vendordatazvendor_data2.jsonvendordata2znetwork_data.jsonnetworkdata)rd   r   	load_json)r<   filesload_json_anytyper2   s     r   	datafilesz%BaseReader.read_v2.<locals>.datafiles   s    E W6FG!E* WkB!E* W6HI!#E, W6IJ!$E-  W6IJ!$E- 
 Lr   r      )r   r<   NFTz*Failed reading optional path %s due to: %sz+Failed reading mandatory path %s due to: %szMissing mandatory path: %sFailed to process path : r>   random_seedz.Badly formatted metadata random_seed entry: %sr   rK   zFailed to read provided file r
   r   z(Failed to read network configuration: %smetadsmodezec2-metadatazNo '%s' entry in metadata)	functoolspartialr   r   dictrr   strr{   r1   rd   r^   ri   IOErrorrO   rP   r(   rp   r   base64	b64decode
ValueError	TypeErrorr0   r   KeyErrorrn   
KEY_COPIES)r2   r   resultsdatar3   rK   required
translatorfoundrv   r>   r   r   metadata_filesr   net_itemcontent
target_key
source_keyis_requiredr   s   `                   @r   read_v2zBaseReader.read_v2   s4    &--NNdC'8
	B 
 335648JJL 	%0T/D(J??4>>48DDEt, !">"EFF%d+D
  $7	%: :&H$"=1K*0*:*:;*G' !gr2" 		DT!<D"55d;d		 !
 << 0$711(41H,3()	 ( 0 :GH
 #'"9"9"; 6@ 	@1Z[z9$%@:%MNNX%'/||J'?$		@
 _  IIDdA IIEtQ  ! (;?C 	* $DqH  $=A1E  $>!D  		s   F?=HH* I
I3 #J ?	H1G??H	H'H""H'*I9II	I0I++I03	J<JJ	J J NF)r)   r*   r+   r_   abcabstractmethodrd   ri   rl   rn   r{   r   r   r   r   r   r\   r\      s    # 	  	  	  	  :4Gr   r\   )	metaclassc                   >     e Zd Z fdZd ZddZd Zd Zd Z xZ	S )ConfigDriveReaderc                 :    t         t        |   |       d | _        y r   )superr   r_   	_versions)r2   r^   	__class__s     r   r_   zConfigDriveReader.__init__f  s    /	:r   c                 X    |gt        |      z   }t        j                  j                  | S r   )rr   rJ   rK   join)r2   rb   rc   
componentss       r   rd   zConfigDriveReader._path_joinj  s%    Vd7m+
ww||Z((r   c                 Z    |rt        j                  |      S t        j                  |      S r   )r   load_text_fileload_binary_filerg   s      r   ri   zConfigDriveReader._path_readn  s1      %	
 &&t,	
r   c                 P   | j                   | j                  | j                  d      }t        j                  |      D cg c]@  }t        j
                  j                  t        j
                  j                  |            r|B }}t        |      | _         | j                   S c c}w )Nr~   )	r   rd   r^   rJ   listdirrK   isdirr   sorted)r2   rK   dr   s       r   rl   z+ConfigDriveReader._fetch_available_versionsu  s    >>!??4>>;?D D)77==d!34 E 
 $E]DN~~s    AB#c                    | j                  | j                  ddd      }t        j                  j	                  |      si S 	 t        j                  | j                  |            S # t        $ r}t        d|d|      |d }~ww xY w)Nr	   r   zmeta-data.jsonr   r   )
rd   r^   rJ   rK   rL   r   r   ri   rp   r   )r2   rK   rv   s      r   rn   z$ConfigDriveReader._read_ec2_metadata  sz    NNE8-=
 ww~~d#I~~dood&;<< $7;Q?s   #A% %	B.B  Bc                    i }t         j                         D ]C  }| j                  | j                  |      }t        j
                  j                  |      s?|||<   E t        |      dk(  rt        d| j                  z        i }t         j                         D ]I  \  }\  }}}||v r$||   }	 | j                  |      }	  ||      ||<   2t        j                  |      ||<   K |d   }
|d   }|j!                  d	|
      }
|
r?|
j#                         }|D cg c]   }t        |      r|j%                  d
      s|" c}|d	<   d|v r|d   |d<   d|d}d|v r|d   |d<   |j!                  dd      |d<   i |d<   |S # t        $ r}	t        d|z        |	d}	~	ww xY w# t        $ r}	t        d|d|	      |	d}	~	ww xY wc c}w )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: %sNr   r   r   r   r;   #r   r:   )r<   r>   r   z	user-datar   r   r   )FILES_V1keysrd   r^   rJ   rK   rL   r   r(   r1   ri   r   r   rp   copydeepcopyr0   
splitlinesrI   )r2   r   r3   rK   mdkeyr   defaultcontentsrv   keydatar   linesliner   s                  r   read_v1zConfigDriveReader.read_v1  s	    MMO 	#D??4>>48Dww~~d#"d	# u:?2dnnEFF2:..2B 	1.T-CWu}T{M#t4H )2BsG --03#	1& &'Y- ++mW5&&(E "!t9T__S%9 !B} G# ' 6B} 
 w ' 1GH &kk+r:
 c  M()=)DE1LM ! (;?C!s6   -E;?F%F>;	FFF	F;$F66F;r   )
r)   r*   r+   r_   rd   ri   rl   rn   r   __classcell__r   s   @r   r   r   e  s"    )
	Gr   r   c                   :     e Zd Zd fd	Zd ZddZd Zd Z xZS )MetadataReaderc                     t         t        |   |       || _        t	        |      | _        t        |      | _        d | _        y r   )	r   r   r_   ssl_detailsfloattimeoutintretriesr   )r2   base_urlr   r   r   r   s        r   r_   zMetadataReader.__init__  s7    nd,X6&W~7|r   c                 ,   | j                   | j                   S g }| j                  | j                  d      }| j                  |d      }|j	                         D ]&  }|j                         }|s|j                  |       ( || _         | j                   S )Nr~   Tr   )r   rd   r^   ri   r   striprW   )r2   r   version_pathr   r   s        r   rl   z(MetadataReader._fetch_available_versions  s    >>%>>!t~~{C//,t/<&&( 	D::<DLL		
 ~~r   c                     d }t        j                  || j                  | j                  | j                  |      }|r|j
                  j                         S |j
                  S )Nc                 h    	 t        |j                        }|dk\  ry	 y# t        t        f$ r Y yw xY w)Ni  FT)r   coder   r   )_request_argscauser   s      r   should_retry_cbz2MetadataReader._path_read.<locals>.should_retry_cb  sD    5::3;  
  z* s    11)r   r   r   exception_cb)r   readurlr   r   r   r   rh   )r2   rK   rh   r   responses        r   ri   zMetadataReader._path_read  s\    	 %%LL((LL(
 $$++--$$$r   c                 .    t        j                  |g| S r   )r   combine_urlra   s      r   rd   zMetadataReader._path_join  s    %%d5W55r   c                 n    t        j                  | j                  | j                  | j                        S )N)r   r   r   )r	   get_instance_metadatar   r   r   rk   s    r   rn   z!MetadataReader._read_ec2_metadata	  s,    ((((LLLL
 	
r   )N   r   r   )	r)   r*   r+   r_   rl   ri   rd   rn   r   r   s   @r   r   r     s    %.6
r   r   c           
        # | yg dg dd#| j                  dg       }| j                  dg       }| j                  dg       }g }i }d}d	}g }	|D ]  }
g }t        #fd
|
j                         D              }d|
v r|
d   |d<   d}|
j                  d      r'|
j                  d      j                         }|||
d   <   |j                  d      ||
d   |
d   d}|D cg c]  }|d   |
d   k(  s| c}D ]e  }t        #fd|j                         D              }|d   dk(  r|j	                  ddi       n|d   dk(  r|j	                  ddi       n|d   dv r|j	                  d|d   i       nh|d   dv r$|j	                  d|j                  d      d       n=|d   dv r6|j	                  ddi       |j	                  d|j                  d      d       |j                  dg       D cg c]  }|j                  d      dk(  r|d     }}|r||d!<   |d   d"v r|j	                  dd#i       |d   d$k(  rd#|d$<   |d   d%k(  rd#|d%<   |j                  |       h |j	                  d&|i       |
d   d'v ri }|r||d(<   |
j                         D ]0  \  }}|d)k(  r|j                  d*      s|j	                  ||i       2 ||z  }|d+z  }|j                  |d,d-t        j                  |
d)         f       |j	                  ||d.       ||d<   n|
d   d/v rv|
d0   d1|
d2   }|j	                  ||
d2   |
d3   d4       |j                  |d0d-|
d0   f       |j                  |dd5|
d2   z  |
d0   f       |j	                  |
d3   |d6       n8|
d   t        vrt        j                  d7|
d          |j	                  d8|d9       |	j                  |       |||d   <    |	D cg c]  }|j                  d      d8k(  sd|vs|  }}|s|r|t        j                         }|j                         D ]6  \  }}|j                  d      r|j                  d:      |v s,||d:      |d<   8 |D ]=  }|j                  d(      }|st        d;|z        ||vrt        d<|z        ||   |d<   ? |D ]H  \  }}}} t        | t         t"        f      r| D !cg c]  }!|||!   d   z   c}!||<   ;|||    d   z  ||<   J t        j$                         }"|"r|	D ]  }|d   |"v s|"|d      |d(<   d=|d<    |D ];  }t        j                  |      }|j	                  dd>i       |	j                  |       = d+|	d?S c c}w c c}w c c}w c c}!w )@a*  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 superfluous keys from the network_config yaml.
    N)r3   typemac_addresssubnetsparamsmtu)r   addressnetmask	broadcastmetricgatewaypointopointscopedns_nameservers
dns_searchroutes)physicalsubnetlinksnetworksserviceszbond%dr   c              3   <   K   | ]  \  }}|d    v s||f  yw)r  Nr   .0krw   
valid_keyss      r   	<genexpr>z#convert_net_json.<locals>.<genexpr>T  s*      
q!qJz4J/JQF
   	r3   ethernet_mac_addressidr   )r3   macr  r   linkc              3   <   K   | ]  \  }}|d    v s||f  yw)r  Nr   r	  s      r   r  z#convert_net_json.<locals>.<genexpr>k  s*      1aa:h;O6OAr  	ipv4_dhcpdhcp4	ipv6_dhcpdhcp6)
ipv6_slaaczipv6_dhcpv6-statelessipv6_dhcpv6-stateful)ipv4staticr  
ip_address)r   r   )ipv6static6z	accept-raFr  dnsr   r   )r  r  Tr  r  r   )bondr   
bond_linksr   r:   bond_interfacesz%s)r   r3   )vlan	vlan_link.vlan_idvlan_mac_address)r3   r&  r   z%%s.%s)r  r3   z9Unknown network_data link type (%s); treating as physicalr  )r   r   r  z#No mac_address or name entry for %sz"Unable to find a system nic for %s
infiniband
nameserver)r<   config)r0   r   r1   lowerupdaterW   rI   r   r   KNOWN_PHYSICAL_TYPESrO   warningr   get_interfaces_by_macr   
isinstancerr   tupleget_ib_hwaddrs_by_interface)$network_json
known_macsr  r  r  link_updateslink_id_infobond_name_fmtbond_numberr*  r  r   cfglink_mac_addrcurinforY   networkr  servicer   r   r  rw   	link_namer3   r   
need_names_link_idinfor  r   fmttargetstargetib_known_hwaddrsr  s$                                      @r   convert_net_jsonrF    s   6 

J0 Wb)E
B/H
B/HLLMKF . 
#zz|
 
 T>v,CK88*+ HH%;<BBDM'4Ld$ GGFO t*L	
 $,GaqyDJ/FG /	#G #*==? F v+-vw/0K/vw/0 % 
 vwv78$66 (#*;;|#< $77

K/0 )#*;;|#<  '{{:r:;;v&%/ 	"O 
 ,;() v"GG

K./v&(!%vv&(!%vNN6"_/	#` 	

Iw'(<8#F(5}%

 *1$\\&)MM1a&)	* &3I1K
 %MM$|"45	 JJ&)<='GFO&\X%";/iADJJ #I#'(:#; k4k9J KLfhi8${:KL NN4(:#;TJKF|#77 L
 JJ
=IJc&-WT]#.D QUU6]j8V1_J  \224J +002 	7NHdxxxx*,)$u+6V		7  	(A%%&C !F!JKK*$ !E!IJJ"3AfI	( '3 	?"Cc7'D%=1EL;AC,v.v66C g!6v!>>C	? 668 	+C6{..%5c&k%BM"*F	+
  mmG$

FL)*c
 F++q H>T2s*   U:/U:. U?)VVVV	)NN))r   r   r   r   loggingrJ   	cloudinitr   r   r   r   r   cloudinit.sourcesr   cloudinit.sources.helpersr	   	getLoggerr)   rO   r   r   r   rt   	OS_FOLSOM
OS_GRIZZLY	OS_HAVANA
OS_LIBERTYOS_NEWTON_ONEOS_NEWTON_TWOOS_OCATAOS_ROCKYrs   r-  r   r(   r-   ABCMetar\   r   r   rF  r   r   r   <module>rU     s        	 : : , ) g!  0bA4>>2."3["!E	
 		
	

 	 "	' 	I IXA3;; AHp
 pf6
Z 6
tp,r   