
    x[hm                        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? #		 	Hf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   s3    &--NNdC'8
	B 
 335626**, 	%.D.4:??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"; 4> 	@/J
K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                 n   i }t         j                         D ]C  }| j                  | j                  |      }t        j
                  j                  |      s?|||<   E |s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.
        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(   r1   ri   r   r   rp   copydeepcopyr0   
splitlinesr   rI   )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	# 2dnnEFF080@ 	1,D,3
G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/3F%F2/	F8FF	F/F**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                 n    	 t        | j                        }|dk\  r|dvryy# t        t        f$ r Y yw xY w)Ni  )i  i  i  i  i  i  FT)r   coder   r   )causer   s     r   should_retry_cbz2MetadataReader._path_read.<locals>.should_retry_cb  sG    5::3;4/M#M   z* s   " 44)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           
      V  & | yg dg dg dd&| j                  dg       }| j                  dg       }| j                  dg       }g }i }d	}d
}g }	|D ]x  }
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 ]  }t        &fd|j                         D              }|j                  dg       D cg c]$  }t        &fd|j                         D              & }}|r|j	                  d|i       |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]2  }|j                  dg       D ]  }|j                  d      d"k(  r|d#    4 }}}|j                  dg       D ]3  }|j                  d      d"k7  r|d#   |v r |j                  |d#          5 |r||d$<   |d   d%v r|j	                  dd&i       |d   d'k(  rd&|d'<   |d   d(k(  rd&|d(<   |j                  |        |j	                  d)|i       |
d   d*v ri }|r|j	                  d+|i       |
j                         D ]T  \  }}|d,k(  r|j                  d-      sd.j                  |j                  d/d0      d1         }|j	                  ||i       V ||z  }|d0z  }|j                  |d2d3t        j                  |
d,         f       |j	                  ||d4       ||d<   n|
d   d5v rv|
d6   d7|
d8   }|j	                  ||
d8   |
d9   d:       |j                  |d6d3|
d6   f       |j                  |dd;|
d8   z  |
d6   f       |j	                  |
d9   |d<       n8|
d   t        vrt        j                  d=|
d          |j	                  d>|d?       |	j                  |       |||d   <   { |	D cg c]  }|j                  d      d>k(  sd|vs|  }}|s|r|t        j                         }|j                         D ]6  \  }}|j                  d      r|j                  d@      |v s,||d@      |d<   8 |D ]i  }|j                  d+      } | st!        dA|z        | |vr:t#        j$                          t        j                         }| |vrt!        dB|z        ||    |d<   k |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+<   dC|d<    |D ];  }t        j                  |      }|j	                  ddDi       |	j                  |       = d0|	dES c c}w c c}w c c}}w c c}w c c}$w )Fa*  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)networkdestinationr   r   r   )physicalsubnetroutes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  r  c              3   :   K   | ]  \  }}|d    v r||f  yw)r  Nr   r
  s      r   r  z#convert_net_json.<locals>.<genexpr>r  s.      1Jx00 Fs   	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"  zbond-{}bond_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   formatr   r   r   KNOWN_PHYSICAL_TYPESrO   warningr   get_interfaces_by_macr   r   udevadm_settle
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   r  r  router  servicer   r   r  rw   translated_key	link_namer3   r   
need_names_link_idinfor  r   fmttargetstargetib_known_hwaddrsr  s'                                         @r   convert_net_jsonrM    s   6 

 M+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 H	#G #*==? F %[[26    % F  x01v+-vw/0K/vw/0 % 
 vwv78$66 (#*;;|#< $77

K/0 )#*;;|#< %[[26$yyR8 ;;v&%/ 	""O  #;;z26 ;;;v&%/9%8&&wy'9:; ,;() v"GG

K./v&(!%vv&(!%vNN6"QH	#R 	

Iw'(<8#F

M=9:

 71$\\&) &/%5%5agggq6I"6M%NNMM>1"567  &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*$##% 668
j($%IA%MNN"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++y HRr:s0   !Z2Z3)Z7Z
Z!-Z!2Z!.Z&)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   r2  r   r(   r-   ABCMetar\   r   r   rM  r   r   r   <module>r\     s        	 : : , ) g!  0bA4>>2."3["!E	
 		
	

 	 "	' 	I IXA3;; AHp
 pf6
Z 6
tT,r   