
    }fB                        d 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 ddlm	Z	m
Z
mZ ddlmZmZmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZ  ej6                  e      Zd	d
iZdZdZ e dz   Z!dZ"ddiZ# edd      Z$ G d dejJ                        Z&deddfdZ' G d dejP                        Z) G d de)      Z*de
e+   fdZ,de-fdZ.de+de/fdZ0de+de
e	e+e+f      fd Z1d
e)jd                  e)jf                  d!d"e-de
e$   fd#Z4e)ejj                  ffe*ejj                  ejl                  ffgZ7d$ Z8ed%k(  rOddl9Z9d&Z: e9jv                  e:'      Z<e<j{                           e> ej~                   e4        e.       d(             yy))a3  Datasource for Oracle (OCI/Oracle Cloud Infrastructure)

Notes:
 * This datasource does not support OCI Classic. OCI Classic provides an EC2
   lookalike metadata service.
 * The UUID provided in DMI data is not the same as the meta-data provided
   instance-id, but has an equivalent lifespan.
 * We do need to support upgrade from an instance that cloud-init
   identified as OpenStack.
 * Bare metal instances use iSCSI root, virtual machine instances do not.
 * Both bare metal and virtual machine instances provide a chassis-asset-tag of
   OracleCloud.com.
    N)
namedtuple)DictOptionalTuple)atomic_helperdminetsourcesutil)NetworkConfig)cmdline	ephemeralget_interfaces_by_macis_netfail_master)wait_for_urlconfigure_secondary_nicsFzOracleCloud.comz&http://169.254.169.254/opc/v{version}/z{path}/i(#  AuthorizationzBearer OracleOpcMetadataz version instance_data vnics_datac                       e Zd ZdZdefdZy)KlibcOracleNetworkConfigSourcezOverride super class to lower the applicability conditions.

    If any `/run/net-*.cfg` files exist, then it is applicable. Even if
    `/run/initramfs/open-iscsi.interface` does not exist.
    returnc                 ,    t        | j                        S )zOverride is_applicable)bool_filesselfs    D/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceOracle.pyis_applicablez,KlibcOracleNetworkConfigSource.is_applicable:   s    DKK      N)__name__
__module____qualname____doc__r   r    r   r   r   r   3   s    !t !r   r   network_configr   c                 <   d| vry| d   dvrt         j                  d| d          yt               }| d   dk(  rT| d   D cg c]	  }d|v s| c}D ]8  }|d   dk(  sd	|v s|d	   }|j                  |      }|s*t	        |      s6|d	= : y| d   d
k(  r| j                  di       j                         D ]_  \  }}d|v s|j                  di       j                  d      }|s/|j                  |      }|sCt	        |      sO|d   d= |d= ||d   d<   a yyc c}w )aP  
    Search network config physical interfaces to see if any of them are
    a netfailover master.  If found, we prevent matching by MAC as the other
    failover devices have the same MAC but need to be ignored.

    Note: we rely on cloudinit.net changes which prevent netfailover devices
    from being present in the provided network config.  For more details about
    netfailover devices, refer to cloudinit.net module.

    :param network_config
       A v1 or v2 network config dict with the primary NIC, and possibly
       secondary nic configured.  This dict will be mutated.

    versionN)      z+Ignoring unknown network config version: %sr(   configtypephysicalmac_addressr)   	ethernetsmatch
macaddresszset-namename)LOGdebugr   getr   items)r%   mac_to_nameccfgmaccur_name_macaddrs           r   _ensure_netfailover_safer=   ?   sY     &i .		99%	
 	')Ki A%-h7G!6Q;AG 	/C6{j( C'm,C*s3H# *84.	/ 
		"a	'$((b9??A 
	8FAs#~'''2.22<@*w7H# *84L6
O/7GV,
	8 
( Hs    	D
Dc                       e Zd ZU dZdZej                  j                  ej                  j                  ej                  j                  ej                  j                  fZeej                  df   ed<   dZdZdZ fdZd	ed
df fdZd
efdZed
efd       Zd Zd
efdZd Zd
efdZd
efdZed        ZddefdZ  xZ!S )DataSourceOracleOracleN.network_config_sourcesT      c                 Z   t        t        | 
  |g|i | d | _        t	        j
                  t	        j                  |d| j                  gi       t        g      | _	        t               | _        g dd| _        | j                         }|j                  | _        |j                   | _        y )N
datasourcer(   r*   r'   )superr?   __init___vnics_datar   mergemanydictget_cfg_by_pathdsnameBUILTIN_DS_CONFIGds_cfgr   _network_config_source_network_configget_url_paramsmax_wait_secondsurl_max_waittimeout_secondsurl_timeout)r   sys_cfgargskwargs
url_params	__class__s        r   rH   zDataSourceOracle.__init__   s    .wHHH(($$W|T[[.I2N!
 'E&F#02q%A((*
&77%55r   ci_pkl_versionr   c                     t         |   |       t        | d      st        | dd        t        | d      st        | dt	                      t        | d      sg dd| _        y y )NrI   rO   rP   r(   rF   )rG   	_unpicklehasattrsetattrr   rP   )r   r[   rZ   s     r   r]   zDataSourceOracle._unpickle   sd    .)t]+D-.t56(.0
 t./.0Q#?D  0r   c                 L    t        | j                  j                  dg             S )Nr*   )r   rP   r4   r   s    r   _has_network_configz$DataSourceOracle._has_network_config   s     D((,,Xr:;;r   c                      t               S )z@Check platform environment to report if this datasource may run.)_is_platform_viabler$   r   r   	ds_detectzDataSourceOracle.ds_detect   s     #$$r   c                 Z   t               | _        | j                  rQt        j                  | j
                  t        j                         t        j                  dd      t        d      }nt        j                         }| j                          }| j                  j                  dt         d         }|5  t#        |xs || j$                  | j&                        }d d d        sy|j(                  x}| _        t,        j                  |j.                  	      | _        |j2                  | _        |d
   |d   d|d   |d   d| _        d|v rQ|d   j                  d      }|rt9        j:                  |      | _        |d   j                  d      | j6                  d<   y# 1 sw Y   xY w)Nr)   instancer'   path)urlheaders)ifaceconnectivity_url_datar   fetch_vnics_datamax_waittimeoutF)r'   	ociAdNameidr   hostnamedisplayName)zavailability-zonezinstance-idzlaunch-indexzlocal-hostnamer1   metadata	user_datassh_authorized_keyspublic_keysT)_read_system_uuidsystem_uuidperform_dhcp_setupr   EphemeralDHCPv4distror	   find_fallback_nicMETADATA_PATTERNformat
V2_HEADERSr   nullcontext_is_iscsi_rootrN   r4   rM   read_opc_metadatarS   rU   instance_data_crawled_metadataMETADATA_ROOTr'   metadata_address
vnics_datarI   ru   base64	b64decodeuserdata_raw)r   network_contextfetch_primary_nicfetch_secondary_nicsfetched_metadatadatarv   s          r   	_get_datazDataSourceOracle._get_data   s   ,.""'77++-+221:2N)'O #..0O $ 3 3 55#{{&89 

  	0!2!J6J**(( 	  (8(F(FFt% - 4 4$,, !5 !
 ,66 "&k!2:":.'
 Z(,,[9I$*$4$4Y$?!+/
+;+?+?%,DMM-( ?	 	s   7'F!!F*c                 @    t        j                  | j                        S )zquickly check (local only) if self.instance_id is still valid

        On Oracle, the dmi-provided system uuid differs from the instance-id
        but has the same life-span.)r
   instance_id_matches_system_uuidrz   )r   rV   s     r   check_instance_idz"DataSourceOracle.check_instance_id   s    
 66t7G7GHHr   c                 ^    t        j                  | j                  j                  d            S )Nrx   )r
   normalize_pubkey_dataru   r4   r   s    r   get_public_ssh_keysz$DataSourceOracle.get_public_ssh_keys   s"    ,,T]]->->}-MNNr   c                 6    | j                   j                         S )z)Return whether we are on a iscsi machine.)rO   r   r   s    r   r   zDataSourceOracle._is_iscsi_root   s    **88::r   c                 6    | j                   j                         S N)rO   render_configr   s    r   _get_iscsi_configz"DataSourceOracle._get_iscsi_config   s    **88::r   c                    | j                         r| j                  S d}| j                         r| j                         | _        | j                         st        j                  d       d}| j                  j                  dt        d         }|s|r	 | j                  |       t        | j                         | j                  S # t        $ r t        j                  t        d       Y Fw xY w)zNetwork config is read from initramfs provided files

        Priority for primary network_config selection:
        - iscsi
        - imds

        If none is present, then we fall back to fallback configuration.
        FzLCould not obtain network configuration from initramfs. Falling back to IMDS.Tr   z+Failed to parse IMDS network configuration!)ra   rP   r   r   r2   warningrN   r4   rM   !_add_network_config_from_opc_imds	Exceptionr   logexcr=   )r   set_primaryset_secondarys      r   r%   zDataSourceOracle.network_config   s     ##%''' #'#9#9#;D '')KK( K&89
 - 66{C 	!!5!56###  As   C #C+*C+r   c                 
   | j                   t        j                  d       y|s'd| j                   d   v rt        j                  d       yt               }|r| j                   n| j                   dd }t	        |      D ]  \  }}|xr |dk(  }|d   j                         }||vrt        j                  d|       >||   }t        j                  |d	         }	| j                  d
   dk(  rJ|rddi}
nd|d    d|	j                   d}
|d|t        |
gd}| j                  d   j                  |       | j                  d
   dk(  st        d|id|d}|s|d    d|	j                   g|d<   || j                  d   |<    y)a  Generate primary and/or secondary NIC config from IMDS and merge it.

        It will mutate the network config to include the secondary VNICs.

        :param set_primary: If True set primary interface.
        :raises:
            Exceptions are not handled within this function.  Likely
            exceptions are KeyError/IndexError
            (if the IMDS returns valid JSON with unexpected contents).
        Nz#NIC data is UNSET but should not benicIndexr   z\VNIC metadata indicates this is a bare metal machine; skipping secondary VNIC configuration.r(   macAddrz)Interface with MAC %s not found; skippingsubnetCidrBlockr'   r+   dhcpstatic	privateIp/)r+   addressr,   )r1   r+   r-   mtusubnetsr*   r)   r0   F)r   r/   dhcp6dhcp4	addressesr.   )rI   r2   r   r   	enumeratelower	ipaddress
ip_networkrP   	prefixlenMTUappend)r   r   interfaces_by_macr   index	vnic_dict
is_primaryr-   r1   networksubnetinterface_configs               r   r   z2DataSourceOracle._add_network_config_from_opc_imds  s    #KK=>
d.>.>q.A A KK9 13)4T%%$:J:J12:N
 )* 5 +	KE9$3!J#I.446K"33? $[1D**95F+GHG##I.!3$f-F !)(56a8I8I7JKF !&#. &x$  $$X.556FG%%i0A5 *K8"'	$  "$[12!G4E4E3FG5$[1 ;K$$[1$7W+	Kr   )F)"r    r!   r"   rL   rz   r
   NetworkConfigSourceCMD_LINE
SYSTEM_CFGDS	INITRAMFSrA   r   __annotations__r{   rS   rU   rH   intr]   r   ra   staticmethodrd   r   r   r   r   dictr   propertyr%   r   __classcell__)rZ   s   @r   r?   r?   s   s   FK##,,##..##&&##--	GE'"="=s"BC   LK6"@ @ @<T < %t % %4lID IO; ;;4 ; +$ +$ZLKT LKr   r?   c                       e Zd ZdZy)DataSourceOracleNetFN)r    r!   r"   r{   r$   r   r   r   r   n  s    r   r   c                  T    t        j                  d      } | d S | j                         S )Nzsystem-uuid)r   read_dmi_datar   )sys_uuids    r   ry   ry   r  s)      /H#49)99r   c                  >    t        j                  d      } | t        k(  S )Nzchassis-asset-tag)r   r   CHASSIS_ASSET_TAG)	asset_tags    r   rc   rc   w  s    !!"56I)))r   ri   c                 ,    | j                  d      rdS dS )Nzhttp://169.254.169.254/opc/v2r)   r(   )
startswithri   s    r   _url_versionr   |  s    >?1FQFr   c                 .    t        |       dk(  rt        S d S )Nr)   )r   r   r   s    r   _headers_cbr     s    %c*a/:9T9r   rm   rn   c                 f   t         j                  dd      t         j                  dd      g}t        j                         }t	        |||t
        d      \  }}|st        j                  d       yt        j                  |j                  d	            }t        |      }d}	| rt	        t         j                  |d
      g|t        j                         |z
  z
  |t
        d      \  }
}|
r%t        j                  |j                  d	            }	nt        j                  d       t        |||	      S )ao  Fetch metadata from the /opc/ routes.

    :return:
        A namedtuple containing:
          The metadata version as an integer
          The JSON-decoded value of the instance data endpoint on the IMDS
          The JSON-decoded value of the vnics data endpoint if
            `fetch_vnics_data` is True, else None
        or None if fetching metadata failed

    r)   rf   rg   r(   r   )ro   rp   
headers_cb
sleep_timezFailed to fetch IMDS metadata!Nzutf-8vnicsz+Failed to fetch IMDS network configuration!)r   r   time	monotonicr   r   r2   r   jsonloadsdecoder   r   )rn   ro   rp   urls
start_timeinstance_urlinstance_responser   metadata_versionr   	vnics_urlvnics_responses               r   r   r     s    * 	
;
;D !J&2'#L# 45JJ077@AM#L1J %1$$-=G$LM!1J!>?"%
!	> N$9$9'$BCJKKEF'
CCr   c                 6    t        j                  | t              S r   )r
   list_from_dependsdatasources)dependss    r   get_datasource_listr     s    $$Wk::r   __main__z
        Query Oracle Cloud metadata and emit a JSON object with two keys:
        `read_opc_metadata` and `_is_platform_viable`.  The values of each are
        the return values of the corresponding functions defined in
        DataSourceOracle.py.)description)r   rc   )@r#   r   r   r   loggingr   collectionsr   typingr   r   r   	cloudinitr   r   r	   r
   r   cloudinit.distros.networkingr   cloudinit.netr   r   r   r   cloudinit.url_helperr   	getLoggerr    r2   rM   r   r   r   r   r   r   KlibcNetworkConfigSourcer   r=   
DataSourcer?   r   strry   r   rc   r   r   r   rS   rU   r   DEP_FILESYSTEMDEP_NETWORKr   r   argparser   ArgumentParserparser
parse_argsprint
json_dumpsr$   r   r   <module>r     s        " ( ( < < 6  .g!   & 8 9,  /
(JK	!W%E%E 	!18] 18t 18hxKw)) xKv* :8C= :
*T *
Gc Gc G:S :Xd38n5 : #**((	7D7D
 k7Dx ..01""	
	; z K
 %X$$=F
	   %6%8':'<	
 r   