
    ؆f<                        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mZ d dlmZ d dlmZmZ d dlmZmZ  ej*                  e      ZdZdZg dZg d	Z ej8                  d
      fdZd ZdcdZ	 	 	 	 dddZ dedZ!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z) ejT                  d      de+fd       Z, ejT                  d      de-fd       Z.de/de+fdZ0dedZ1d Z2d  Z3dede+fd!Z4ded"Z5ded#Z6d$ Z7d% Z8d& Z9d' Z:d( Z; G d) d*e<      Z=d+ Z>de
e/   fd,Z?dee/   fd-Z@de
e/   fd.ZAdee/   fd/ZBde
e/   fd0ZCdee/   fd1ZDde
e/   fd2ZEdee/   fd3ZFded4ZGd5 ZHdfd6ZIdgd7ZJ	 dhd8ZKd9 ZLd: ZMdeNfd;ZOd<e/dee/   fd=ZPdeNfd>ZQdeNfd?ZRdeNfd@ZSdeNfdAZT	 	 	 	 	 	 	 didBe+dCe+dDe+dEe+dFe+dGe+dHe+de-fdIZUdJedK   dLe
ee/e/e/e/f      ddfdMZVdN ZWdOe	e/ef   de+fdPZXdQedRe/fdSZYdRe/de+fdTZZdRe/de+fdUZ[dRe/de+fdVZ\dRe/de+fdWZ]dRe/de+fdXZ^dRe/de+fdYZ_de+fdZZ`de/fd[Zadebfd\Zcdebfd]Zdd^e/d_e/de/fd`Ze G da dbef      Zgy)j    N)AnyCallableDictListOptionalTuple)urlparse)subputil)UrlErrorreadurlz/sys/class/net/eth0)dhcp6
ipv6_slaaczipv6_dhcpv6-statelesszipv6_dhcpv6-stateful)	ovs-vsctlz--formatcsvz--no-headingsz	--timeout10z	--columnsnamefind	interfaceztype=internalz([0-9]+)c                     t        j                  ||       D cg c]-  }|j                         rt        |      n|j	                         / c}S c c}w )aD  Sorting for Humans: natural sort order. Can be use as the key to sort
    functions.
    This will sort ['eth0', 'ens3', 'ens10', 'ens12', 'ens8', 'ens0'] as
    ['ens0', 'ens3', 'ens8', 'ens10', 'ens12', 'eth0'] instead of the simple
    python way which will produce ['ens0', 'ens10', 'ens12', 'ens3', 'ens8',
    'eth0'].)resplitisdigitintlower)s_nsretexts      8/usr/lib/python3/dist-packages/cloudinit/net/__init__.pynatural_sort_keyr!   ,   sF     HHUA& \\^D	5  s   2Ac                      t         S )z3Simple function to return the global SYS_CLASS_NET.)SYS_CLASS_NET     r    get_sys_class_pathr&   9   s    r%   c                 (    t               | z   dz   |z   S )N/)r&   devnamepaths     r    sys_dev_pathr,   >   s    ')C/$66r%   c                    t        | |      }	 t        j                  |      }|j                         }||S 	 ||   S # t        t        f$ rf}t        |dd       }	|	t        j                  t        j                  fv r| ||      cY d }~S |	t        j                  fv r| ||      cY d }~S  d }~ww xY w# t        $ r,}| ||      cY d }~S t        j                  d||        d }~ww xY w)Nerrnoz5Found unexpected (not translatable) value '%s' in '%s)r,   r   load_text_fileOSErrorIOErrorgetattrr.   ENOENTENOTDIREINVALstripKeyErrorLOGdebug)
r*   r+   	translate	on_enoenton_keyerror	on_einvaldev_pathcontentsee_errnos
             r    read_sys_netrB   B   s     GT*H
&&x0 ~~H"" W !Wd+u||U]]33$ |#u||o%$ |#  	"q>!IIG
 	sP   = B5 B28B-B2
B-&B2,B--B25	C*>	C%C*C%%C*c                 *    d }t        | |||||      S )Nc                      yNFr$   )r@   s    r    on_excp_falsez(read_sys_net_safe.<locals>.on_excp_falseh   s    r%   )r<   r;   r=   r:   )rB   )ifacefieldr:   rF   s       r    read_sys_net_saferI   g   s(     ! r%   c                 Z    t        | |      }|du ry 	 t        |      S # t        $ r Y y w xY wrE   )rI   r   
ValueError)rG   rH   vals      r    read_sys_net_intrM   u   s8    
E5
)C
e|3x s   
 	**c                 *    dddd}t        | d|      S )NTF)upunknowndown	operstate)r:   rI   )r*   r:   s     r    is_uprT      s     e<IWkYGGr%   c                 T    t         j                  j                  t        | d            S )Nbridgeosr+   existsr,   r*   s    r    	is_bridger[      s    77>>,w9::r%   c                 T    t         j                  j                  t        | d            S )NbondingrW   rZ   s    r    is_bondr^      s    77>>,w	:;;r%   c                 `    t        | d      }t        j                  j                  |      r|S y)z8Return the master path for devname, or None if no mastermasterr+   N)r,   rX   r+   rY   r)   s     r    
get_masterrb      s&    h/D	ww~~dr%   c                    t        |       }|yt        j                  j                  |d      }t        j                  j                  |d      }t        j                  j	                  |      xs t        j                  j	                  |      S )z@Return a bool indicating if devname's master is a bridge or bondFr]   rV   )rb   rX   r+   joinrY   )r*   master_pathbonding_pathbridge_paths       r    master_is_bridge_or_bondrh      sb    W%K77<<Y7L'',,{H5K77>>,'F277>>++FFr%   c                 v    t        |       }|yt        | d      }t        j                  j	                  |      S )z;Return a bool indicating if devname's master is openvswitchFzupper_ovs-systemra   )rb   r,   rX   r+   rY   )r*   re   ovs_paths      r    master_is_openvswitchrk      s5    W%KG*<=H77>>(##r%   c                      t        | d      dk(  S )Ntype32rS   rZ   s    r    is_ib_interfacero      s    Wf-55r%   )maxsizereturnc                  p    t        t        j                  d            } | st        j	                  d       | S )zDReturn a bool indicating if Open vSwitch is installed in the system.r   z<ovs-vsctl not in PATH; not detecting Open vSwitch interfaces)boolr
   whichr8   r9   )rets    r    openvswitch_is_installedrv      s0     tzz+&
'C		J	
 Jr%   c                      	 t        j                   t              \  } }| j                         S # t         j                  $ r0}d|j                  v rt
        j                  d       g cY d}~S  d}~ww xY w)zReturn a list of the names of OVS internal interfaces on the system.

    These will all be strings, and are used to exclude OVS-specific interface
    from cloud-init's network configuration handling.
    zdatabase connection failedzJOpen vSwitch is not yet up; no interfaces will be detected as OVS-internalN)r
   !OVS_INTERNAL_INTERFACE_LOOKUP_CMD
splitlinesProcessExecutionErrorstderrr8   info)out_errexcs      r    get_ovs_internal_interfacesr      sh     II?@	T ~~ %% '3::5HH  Is!   . A1$A,%A1+A,,A1r*   c                 d    t               syt               }| |v rt        j                  d|        yy)zReturns True if this is an OVS internal interface.

    If OVS is not installed or not yet running, this will return False.
    FzDetected %s as an OVS interfaceT)rv   r   r8   r9   )r*   ovs_bridgess     r    !is_openvswitch_internal_interfacer      s2    
 $%-/K+		3W=r%   c                 P    |t        |       }t        | |      st        | |      ryy)znetfailover driver uses 3 nics, master, primary and standby.
    this returns True if the device is either the primary or standby
    as these devices are to be ignored.
    TF)device_driveris_netfail_primaryis_netfail_standbyr*   drivers     r    is_netfailoverr      s2    
 ~w''6*.@/ r%   c                 D    d}	 t        | d      }|S # t        $ r Y |S w xY w)zDReturns a str from reading /sys/class/net/<devname>/device/features. zdevice/features)rB   	Exceptionr*   featuress     r    get_dev_featuresr      s9    H):; O  Os    	c                 J    t        |       }|rt        |      dk  ry|d   dk(  S )z Return True if VIRTIO_NET_F_STANDBY bit (62) is set.

    https://github.com/torvalds/linux/blob/         089cf7f6ecb266b6a4164919a2e69bd2f938374a/         include/uapi/linux/virtio_net.h#L60
    @   F>   1)r   lenr   s     r    has_netfail_standby_featurer      s.      (Hs8}r)B<3r%   c                 Z    t        |       y|t        |       }|dk7  ryt        |       syy)zA device is a "netfail master" device if:

    - The device does NOT have the 'master' sysfs attribute
    - The device driver is 'virtio_net'
    - The device has the standby feature bit set

    Return True if all of the above is True.
    F
virtio_netTrb   r   r   r   s     r    is_netfail_masterr     s:     '&~w'&w/r%   c                 :   t        | d      }t        j                  j                  |      sy|t	        |       }|dk(  ryt        j                  j                  t        j                  j                  |            }t	        |      }|dk7  ryt        |      }|syy)a7  A device is a "netfail primary" device if:

    - the device has a 'master' sysfs file
    - the device driver is not 'virtio_net'
    - the 'master' sysfs file points to device with virtio_net driver
    - the 'master' device has the 'standby' feature bit set

    Return True if all of the above is True.
    r`   ra   Fr   T)r,   rX   r+   rY   r   basenamerealpathr   )r*   r   master_sysfs_pathmaster_devnamemaster_drivermaster_has_standbys         r    r   r     s     %W8<77>>+,~w'WW%%bgg&6&67H&IJN!.1M$4^Dr%   c                 Z    t        |       y|t        |       }|dk7  ryt        |       syy)zA device is a "netfail standby" device if:

    - The device has a 'master' sysfs attribute
    - The device driver is 'virtio_net'
    - The device has the standby feature bit set

    Return True if all of the above is True.
    Fr   Tr   r   s     r    r   r   :  s:     '"~w'&w/r%   c                 *    t        | d      }|r|dv ryy)a  
    /* interface name assignment types (sysfs name_assign_type attribute) */
    #define NET_NAME_UNKNOWN      0  /* unknown origin (not exposed to user) */
    #define NET_NAME_ENUM         1  /* enumerated by kernel */
    #define NET_NAME_PREDICTABLE  2  /* predictably named by the kernel */
    #define NET_NAME_USER         3  /* provided by user-space */
    #define NET_NAME_RENAMED      4  /* renamed by user-space */
    name_assign_type)34TFrS   )r*   r   s     r    
is_renamedr   R  s#     )2DE,
:r%   c                 P    t        t        | d            }d|j                         v S )NueventzDEVTYPE=vlan)strrI   ry   )r*   r   s     r    is_vlanr   a  s(    "7H56FV..000r%   c                     d}t        | d      }t        j                  j                  |      r2t        j                  j	                  t        j
                  |            }|S )z8Return the device driver for net device named 'devname'.Nzdevice/driver)r,   rX   r+   islinkr   readlink)r*   r   driver_paths      r    r   r   f  sE    Fw8K	ww~~k"!!"++k":;Mr%   c                 (    t        | d      }|du ry|S )z;Return the device id string for net device named 'devname'.zdevice/deviceFNrS   )r*   dev_ids     r    device_devidr   q  s    w8FMr%   c                  D   t        j                         st        j                         r!t        t	               j                               S 	 t        j                  t                     } | S # t        $ r,}|j                  t        j                  k(  rg } n Y d }~| S d }~ww xY wN)r   
is_FreeBSDis_DragonFlyBSDlistget_interfaces_by_macvaluesrX   listdirr&   r0   r.   r3   )devsr@   s     r    get_devicelistr   z  s    D002)+22455zz,./ K  77ell"D  Ks   A* *	B3!BBc                       e Zd ZdZy)ParserErrorz6Raised when a parser has issue parsing a file/content.N)__name__
__module____qualname____doc__r$   r%   r    r   r     s    @r%   r   c                 P    | rt        | t              sy| j                  d      dk(  S )NFconfigdisabled)
isinstancedictget)cfgs    r    is_disabled_cfgr     s%    jd+778
**r%   c                      t        j                         st        j                         r
t               S t        j                         st        j
                         r
t               S t               S )zqGet the list of network interfaces viable for networking.

    @return List of interfaces, sorted naturally.
    )r   r   r   find_candidate_nics_on_freebsd	is_NetBSD
is_OpenBSD(find_candidate_nics_on_netbsd_or_openbsdfind_candidate_nics_on_linuxr$   r%   r    find_candidate_nicsr     sG    
 D002-//		T__.799+--r%   c                      t        j                         st        j                         r
t               S t        j                         st        j
                         r
t               S t               S )z.Get the name of the 'fallback' network device.)r   r   r   find_fallback_nic_on_freebsdr   r   &find_fallback_nic_on_netbsd_or_openbsdfind_fallback_nic_on_linuxr$   r%   r    find_fallback_nicr     sE    D002+--		T__.577)++r%   c                  P    t        t               j                         t              S )zmGet the names of the candidate network devices on NetBSD/OpenBSD.

    @return list of sorted interfaces
    key)sortedr   r   r!   r$   r%   r    r   r     s    
 ')0028HIIr%   c                  &    t               } | r| d   S y)zfGet the 'fallback' network device name on NetBSD/OpenBSD.

    @return default interface, or None
    r   N)r   namess    r    r   r     s    
 56EQxr%   c                      t        j                   g d      \  } }| j                         }|r|S t        t               j	                         t
              S )zgGet the names of the candidate network devices on FreeBSD.

    @return List of sorted interfaces.
    )ifconfigz-lz-uetherr   )r
   r   r   r   r   r!   )stdout_stderrr   s      r    r   r     sG    
 ii ABOFG\\^F ')0028HIIr%   c                  &    t               } | r| d   S y)z_Get the 'fallback' network device name on FreeBSD.

    @return List of sorted interfaces.
    r   N)r   r   s    r    r   r     s    
 +,EQxr%   c                     dt        j                         v rt        j                  d       n~t	               D  cg c]  } | dk7  rt        |       s|  }} t        |      rLt        j                  d|       d}t        j                  t        j                  |t         j                         g }g }t        dddddd	      D ]  \  }}}}|dk(  r|j                  d
      rt        j                  d|       6t        |d      }|r|j                  |       Vt        j                  d|       t        |d      }|r|j                  |       t        |d      }	|	dv r|j                  |       t        j                  d|        g }
||fD ]K  }t        |t              }t         |v r+|j#                  t                |j%                  dt                |
|z  }
M |
S c c} w )zeGet the names of the candidate network devices on Linux.

    @return List of sorted interfaces.
    znet.ifnames=0z9Stable ifnames disabled by net.ifnames=0 in /proc/cmdlineloz4Found unstable nic names: %s; calling udevadm settlez!Waiting for udev events to settle)funcFT)filter_openvswitch_internal2filter_slave_if_master_not_bridge_bond_openvswitchfilter_vlanfilter_without_own_macfilter_zero_maclog_filtered_reasonsvethzIgnoring veth interface: %scarrierzInterface has no carrier: %sdormantrR   )r   rQ   lowerlayerdownrP   zInterface ignored: %sr   r   )r   get_cmdliner8   r9   r   r   r   log_timeudevadm_settleget_interfaces
startswithrM   appendrI   r   r!   DEFAULT_PRIMARY_INTERFACEremoveinsert)deviceunstablemsg	connectedpossibly_connectedr   _r   r   rR   sorted_interfaces
interfacess               r    r   r     s   
 $**,,		MN )*
~j&8 
 

 x=IIF 6CMM#))St/B/BC I,$);@$! 6	1a 'II3Y?"9i8Y'		0)< #9i8%%i0%i=	HH%%i0		)95=6J  "45 (
J,<=
$
278a!:;Z'( }
s   Gc                  &    t               } | r| d   S y)z]Get the 'fallback' network device name on Linux.

    @return List of sorted interfaces.
    r   N)r   r   s    r    r   r   !  s    
 )*EQxr%   c                     | sd} t               }|syt        |      rd|i}ndt        |d      j                         i}dd||d}| rt	        |      }|r||d   d	<   ||id
d}|S )zBGenerate network cfg v2 for dhcp on the NIC most likely connected.FNr   
macaddressaddressT)dhcp4r   set-namematchr  r      )	ethernetsversion)r   r   rI   r   r   )config_drivertarget_namer  r   r   nconfs         r    generate_fallback_configr  -  s    #%K %% +KCIIK
 	C {+%+CL"&,;ELr%   c                     d }d }| j                  d      }|dk(  r ||       S |dk(  r ||       S t        d|z        )Nc                    g }| j                  di       D ]  }|j                  d      dk7  r|j                  d      }|s,|j                  d      }|j                  di       j                  d      }|j                  di       j                  d      }|st        |      }|st        |      }|j                  ||||g        |S )	Nr   rm   physicalmac_addressr   paramsr   	device_id)r   r   r   r   )netcfgphysdevsentmacr   r   r  s          r    
_version_1z$extract_physdevs.<locals>._version_1M  s    ::h+ 	<Cwwv*,''-(C776?DWWXr*..x8F"-11+>I&t,(.	OOS$	:;	< r%   c                    g }| j                  di       j                         D ]  }|j                  d      }|s|j                  di       j                  d      }|s;|j                  di       j                  d      }|j                  di       j                  d      }|st        |      }|st        |      }|j	                  ||||g        |S )Nr
  r  r  r  r   r  )r   r   r   r   r   )r  r  r  r   r  r   r  s          r    
_version_2z$extract_physdevs.<locals>._version_2_  s    ::k2.557 	<C77:&D'''2&**<8CWWWb)--h7F,00=I&t,(.	OOS$	:;	<  r%   r     r	  z"Unknown network config version: %s)r   RuntimeError)r  r  r  r  s       r    extract_physdevsr  L  sQ    $( jj#G!|&!!	A&!!
;gE
FFr%   c                 B    t        | d      }||rt        d      y|dv S )a  return True if the provided interface has its own address.

    Based on addr_assign_type in /sys.  Return true for any interface
    that does not have a 'stolen' address. Examples of such devices
    are bonds or vlans that inherit their mac from another device.
    Possible values are:
      0: permanent address    2: stolen from another device
      1: randomly generated   3: set using dev_set_mac_addressaddr_assign_typez%s had no addr_assign_type.T)r   r     )rM   rK   )ifnamestrictassign_types      r    interface_has_own_macr&  |  s6     #6+=>K :;;)##r%   c           	         i }t               D ]*  \  }}}}d|||j                         |t        |      d||<   , | rt        j                  d      }t        j
                  g dd      \  }}t        j
                  g dd      \  }	}t               }
||	fD ]"  }|
j                  |j                  |             $ |j                         D ]  }|d   d	u xs |d
   |
v|d<    |S )a  Collect information necessary for rename_interfaces.

    returns a dictionary by mac address like:
       {name:
         {
          'downable': None or boolean indicating that the
                      device has only automatically assigned ip addrs.
          'device_id': Device id value (if it has one)
          'driver': Device driver (if it has one)
          'mac': mac address (in lower case)
          'name': name
          'up': boolean: is_up(name)
         }}
    N)downabler  r   r  r   rO   z[0-9]+:\s+(\w+)[@:])ipz-6addrshow	permanentscopeglobalTcapture)r)  z-4r*  r+  rO   Fr   r(  )
r   r   rT   r   compiler
   setupdatefindallr   )check_downablecur_infor   r  r   r  nmatchipv6r~   ipv4nics_with_addresses	bytes_outds                r    _get_current_rename_infor=    s    H*8*: 
&sFI"99;+

 23YYH

d YY;TJ
d!e 	BI&&v~~i'@A	B " 	A$5 HAfI5H$H jM	
 Or%   c                     t        |       st        j                  d       y |
t               }i |j	                         D ]F  \  }}|j                         }|j                  d      r|d   j                         |d<   ||d<   ||<   H t        j                  d       fd}d }d }	d }
g }g }g } |      }d	}d
}d   fd}| D ]  \  }}}}|r|j                         }g } ||||      }|s|r|j                  d|d|d       D|j                  d      }||k(  r[|s|r|j                  d|d|d       x|d   rRd}|d   s|r|j                  ||||fz         d|d<   |j                  d|||ff       |j                  d|||ff       ||v r||   }|d   r7d}|d   s|r|j                  ||||fz         |j                  d|||ff       d }|||v r|dz  }||z  }|||v r|j                  d||||ff       ||d<    |      }|d   r|j                  d|||ff       |j                  d|||d   |ff       ||d<    |      }||z  } ||	|
d}t        |      t        |      z   dk(  r:t        |      rt        j                  d| |       nUt        j                  d|        n>t        j                  d| ||z          ||z   D ]  \  }}}}	  |j                  |      |   t        |      rt        d!j                  |            y # t        $ r)}|j                  d||d|d|d |	       Y d }~rd }~ww xY w)"Nzno interfaces to renamer  r   zDetected interfaces %sc                 D    t        d j                         D              S )Nc              3   *   K   | ]  }|d    |f  yw)r   Nr$   ).0datas     r    	<genexpr>z<_rename_interfaces.<locals>.update_byname.<locals>.<genexpr>  s     GTT&\4(Gs   )r   r   )bymacr6  s    r    update_bynamez)_rename_interfaces.<locals>.update_byname  s    GX__5FGGGr%   c                 >    t        j                   ddd| d|gd       y )Nr)  linkr2  r   Tr/  r
   )curnews     r    renamez"_rename_interfaces.<locals>.rename  s    		4VS94Hr%   c                 <    t        j                   ddd| dgd       y )Nr)  rG  r2  rQ   Tr/  rH  r   s    r    rQ   z _rename_interfaces.<locals>.down  s    		4f5tDr%   c                 <    t        j                   ddd| dgd       y )Nr)  rG  r2  rO   Tr/  rH  rM  s    r    rO   z_rename_interfaces.<locals>.up  s    		4d3TBr%   z
cirename%dc                     |r |r|r| d   |k(  xr | d   |k(  xr | d   |k(  S |r|r| d   |k(  xr | d   |k(  S |r| d   |k(  S y)zmatch if set and in datar  r   r  Fr$   )rB  r  r   r  s       r    entry_matchz'_rename_interfaces.<locals>.entry_match  sv    6iUs" 3Nf,3%2
 V;#%B$x.F*BB;#%%r%   c           	          j                         D cg c]  } || ||      r| }}t        |      r-t        |      dkD  rd|d| d|d|d	}t        |      |d   S y c c}w )Nr  z2Failed to match a single device. Matched devices "z" with search values "(mac:z driver:z device_id:z)"r   )r   r   rK   )r  r   r  rB  r  r   r6  rQ  s         r    
find_entryz&_rename_interfaces.<locals>.find_entry  s}     !)
4fi8 
 

 u:5zA~ c696 
 !o%8O
s   A#z$[nic not present] Cannot rename mac=z to z, not available.rO   z*[busy] Error renaming mac=%s from %s to %sr(  FrQ   z2[busy-target] Error renaming mac=%s from %s to %s.r  rK  )rK  rQ   rO   r   z1Unable to rename interfaces: %s due to errors: %sz$no work necessary for renaming of %szRenamed %s with ops %sz[unknown] Error performing z for z, z: 
)r   r8   r9   r=  itemscopyr   r   r   warningr   r  rd   )!renamesstrict_presentstrict_busycurrent_infor   rB  rI  rE  rK  rQ   rO   opserrorsups
cur_bynametmpname_fmttmpirS  r  new_namer   r  cur_opscur_namer   targettmp_nameopmapopr  r@   r6  rQ  s!                                  @@r    _rename_interfacesri    s    w<		+,/1H"((* 
diik775>U))+CJF II&1HIEC CF
Cx(JKD$ -4 =(Xvy))+Cfi0*-x9 776?x*-x9 t9>Cz?MM#h(A"ABCINNFCH;?@JJc8h[9:z!)Fd|Jj)"cS(H,E&EFNNFCH;#GHH"h*&<	&- "h*&< NNHc8h5IJK%F6N&x0Jd|

D#x(=>#x#f+x1HIJF"8,
w{=~ t26E
3x#c(av;KKC II<gF		*GS3Y?),s 	%BXv		"v&	 6{499V,--   63!5 s   *L&&	M/MMc                 t    d}t         j                  j                  t        | d            rd}t	        | |      S )z6Returns the string value of an interface's MAC Addressr  bonding_slavezbonding_slave/perm_hwaddr)rX   r+   isdirr,   rI   )r#  r+   s     r    get_interface_macrm  a  s2    D	ww}}\&/:; +VT**r%   c                 Z    t        | d      dk(  rt        |       }|r|r|dd |dd z   }|S y)zReturns the string value of an Infiniband interface's hardware
    address. If ethernet_format is True, an Ethernet MAC-style 6 byte
    representation of the address will be returned.
    rm   rn   $   i3   N)rI   rm  )r#  ethernet_formatr  s      r    get_ib_interface_hwaddrrr  k  sB     (D0'?b+BC(C
 1r%   c                      t        j                         st        j                         r
t               S t        j                         r
t               S t        j                         r
t               S t               S r   )	r   r   r    get_interfaces_by_mac_on_freebsdr   get_interfaces_by_mac_on_netbsdr    get_interfaces_by_mac_on_openbsdget_interfaces_by_mac_on_linuxr$   r%   r    r   r   y  sO    D002/11		.00		/11-//r%   r  c                     t               j                         D ]*  \  }}| j                         |j                         k(  s(|c S  y r   )r   rU  r   )r  interface_macinterface_names      r    find_interface_name_from_macr{    sD    )>)@)F)F)H "%~99;---//!!" r%   c                      t        j                   g d      \  } }d }d } | ||             D ci c]  \  }}||
 }}}|S c c}}w )N)r   -ar   c              3      K   d}| j                  d      D ]!  }|j                  d      r||z  }|r| |}# | y w)Nr   rT  	)r   r   )r}   
curr_blocklines      r    flattenz1get_interfaces_by_mac_on_freebsd.<locals>.flatten  sN     
IIdO 	"Dt$d"
$$!
	" s   =?c              3      K   | D ]?  }t        j                  d|      }|s|j                  d      |j                  d      f A y w)Nz2^(?P<ifname>\S*): .*ether\s(?P<mac>[\da-f:]{17}).*r  r#  )r   searchgroup)	flat_listblockms      r    find_macz2get_interfaces_by_mac_on_freebsd.<locals>.find_mac  sI      	:E		EuA wwu~qwwx'899	:s
   A'ArH  )r}   r   r  r  r  r#  resultss          r    rt  rt    sP    yy45HS!	: /7ws|.DE{sFsF{EGEN Fs   Ac                     i } d}t        j                   ddg      \  }}t        j                  dd|      j                         }|D ]6  }t        j                  ||      }|s|j                         }|d   | |d   <   8 | S )NzE(?P<ifname>\w+).*address:\s(?P<mac>([\da-f]{2}[:-]){5}([\da-f]{2})).*r   r}  \n\s+ r#  r  r
   r   subry   r  	groupdictru   re_field_matchr}   r   if_linesr  r  fieldss           r    ru  ru        
C	6  yy*d+,HS!vvhS)446H 2HH^T*[[]F!'!1Cu	2
 Jr%   c                     i } d}t        j                   ddg      \  }}t        j                  dd|      j                         }|D ]6  }t        j                  ||      }|s|j                         }|d   | |d   <   8 | S )NzC(?P<ifname>\w+).*lladdr\s(?P<mac>([\da-f]{2}[:-]){5}([\da-f]{2})).*r   r}  r  r  r#  r  r  r  s           r    rv  rv    r  r%   c                      i } t               D ]~  \  }}}}|| v r:|dv rt        j                  d|| |   |       ,d|d| |   d|d}t        |      || |<   t	        |d      }|sZ|| vr|| |<   dt        j                  d|| |   |        | S )	zmBuild a dictionary of tuples {mac: name}.

    Bridges and any devices that have a 'stolen' mac are excluded.)	fsl_enetc
mscc_felixqmi_wwanz>Ignoring duplicate macs from '%s' and '%s' due to driver '%s'.duplicate mac found! both '' and '' have mac 'z'.Tz^Ethernet and InfiniBand interfaces have the same address both '%s' and '%s' have address '%s'.)r   r8   r9   r  rr  rW  )ru   r   r  r   _devidr   ib_macs          r    rw  rw    s     C%3%5 =!c66#: @@		#H  A CC
 s##C
 )t4* S "F=Ko=| Jr%   filter_hyperv_vf_with_syntheticr   r   r   r   r   r   c           	      `   |rt         j                  nd }g }t               }	dj                  d      }
|	D ]  }|rt	        |      st        |      r
 |d|       &|rt        |      r4t        |      r
 |d|       I|r"t        |      t        |      st        |      smt        |      r
 |d|       t        |      }|s
 |d|       |r|d	k7  r||
dt        |       k(  r|rt        |      rt        |      }|j!                  |||t#        |      f        | rt%        ||       |S )
zReturn list of interface tuples (name, mac, driver, device_id)

    Bridges and any devices that have a 'stolen' mac are excluded.c                       y r   r$   )argss    r    <lambda>z get_interfaces.<locals>.<lambda>  s    r%   :)00r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  zIgnoring bridge interface: %szIgnoring bond interface: %sNzIgnoring failover interface: %sz"Ignoring interface without mac: %sr   )r8   r9   r   rd   r&  r[   r   r^   rb   rh   rk   r   rm  r   r   r   r   r   )filter_hyperv_vf_with_synthetic_interface)r  r   r   r   r   r   r   filtered_loggerru   r   zero_macr   r  r   s                 r    r   r     s=    $8cii=OO
CDxx%H "<!*?*ET?;TB74=4=94@>4 ,,T2)$/$=tD%@$Gtt|x
#c(7K0K&+L,
 t$

D#v|D'9:;E"<J '1/3GJr%   r  ).Nr  c                     |D ci c]  }|d   dk(  s|d   |d    }}|D cg c]  }|d   |v r
|d   dk7  r| }}|D ])  }|\  }}}}	 | d||||   |       |j                  |       + yc c}w c c}w )a  Filter Hyper-V SR-IOV/VFs when used with synthetic hv_netvsc.

    Hyper-V's netvsc driver may register an SR-IOV/VF interface with a mac
    that matches the synthetic (hv_netvsc) interface.  This VF will be
    enslaved to the synthetic interface, but cloud-init may be racing this
    process.  The [perhaps-yet-to-be-enslaved] VF should never be directly
    configured, so we filter interfaces that duplicate any hv_netvsc mac
    address, as this the most reliable indicator that it is meant to be
    subordinate to the synthetic interface.

    VF drivers will be mlx4_core, mlx5_core, or mana.  However, given that
    this list of drivers has changed over time and mana's dependency on
    hv_netvsc is expected to be removed in the future, we no longer rely
    on these names. Note that this will not affect mlx4/5 instances outside
    of Hyper-V, as it only affects environments where hv_netvsc is present.
    r	  	hv_netvscr  r   zdIgnoring %r VF interface with driver %r due to synthetic hv_netvsc interface %r with mac address %r.N)r   )
r  r  ihv_netvsc_mac_to_nameinterfaces_to_remover   r   r  r   r   s
             r    r  r  J  s    * '!A$+*=!ad
 
 Q4((QqT[-@ 	
  * 
%	(c61D!#&	
 	)$
%s   A-A-A2c            
          i } t               D ]7  \  }}}}t        |d      }|s|| v rt        d|d| |   d|d      || |<   9 | S )zTBuild a dictionary mapping Infiniband interface names to their hardware
    address.Fr  r  r  ')r   rr  r  )ru   r   r   r  s       r    get_ib_hwaddrs_by_interfacer  t  sh     C') aA(u5}"S[&2  CI Jr%   url_datac                    d| vrt         j                  d|        y| d   }	 t        |      }t        |j                  dk(  |j                  dk(  g      s!t         j                  d|j                         y	 d	| vrd
| d	<   	 t        di |  y# t
        $ r }t         j                  d|       Y d}~yd}~ww xY w# t        $ r Y yw xY w)aD  Return true when the instance has access to the provided URL.

    Logs a warning if url is not the expected format.

    url_data is a dictionary of kwargs to send to readurl. E.g.:

    has_url_connectivity({
        "url": "http://example.invalid",
        "headers": {"some": "header"},
        "timeout": 10
    })
    urlz4Ignoring connectivity check. No 'url' to check in %sFhttphttpsz2Ignoring connectivity check. Invalid URL scheme %sz+Ignoring connectivity check. Invalid URL %sNtimeout   Tr$   )r8   rW  r	   anyschemerK   r   r   )r  r  resulterrs       r    has_url_connectivityr    s     HBH	
 
5/C
#FMMV+V]]g-EFGKKD

  H  (   A3G  s*   AB  B8 	B5B00B58	CCconvert_to_addressr  c                 4    	  | |fi |S # t         $ r Y yw xY w)a  Use a function to return an address. If conversion throws a ValueError
    exception return False.

    :param check_cb:
        Test function, must return a truthy value
    :param address:
        The string to test.

    :return:
        Address or False

    F)rK   )r  r  kwargss      r    maybe_get_addressr    s)    !'4V44 s    	c                 H    t        t        t        j                  |             S )zReturns a bool indicating if ``s`` is an IP address.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IP address or not.
    )rs   r  	ipaddress
ip_addressr  s    r    is_ip_addressr    s     !)"6"6@AAr%   c                 H    t        t        t        j                  |             S )zReturns a bool indicating if ``s`` is an IPv4 address.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    )rs   r  r  IPv4Addressr  s    r    is_ipv4_addressr         !)"7"7ABBr%   c                 H    t        t        t        j                  |             S )zReturns a bool indicating if ``s`` is an IPv6 address.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    )rs   r  r  IPv6Addressr  s    r    is_ipv6_addressr    r  r%   c                 L    t        t        t        j                  | d            S )zReturns a bool indicating if ``s`` is an IPv4 or IPv6 network.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    Fr$  )rs   r  r  
ip_networkr  s    r    is_ip_networkr    s     !)"6"6NOOr%   c                 L    t        t        t        j                  | d            S )zReturns a bool indicating if ``s`` is an IPv4 network.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    Fr  )rs   r  r  IPv4Networkr  s    r    is_ipv4_networkr    #     )//G r%   c                 L    t        t        t        j                  | d            S )zReturns a bool indicating if ``s`` is an IPv6 network.

    :param address:
        The string to test.

    :return:
        A bool indicating if the string is an IPv4 address or not.
    Fr  )rs   r  r  IPv6Networkr  s    r    is_ipv6_networkr    r  r%   c                     | d   j                  d      s| d   t        v ry| d   dk(  rt        | j                  d            ryy)z:Common helper for checking network_state subnets for ipv6.rm   6Tstaticr  F)endswithIPV6_DYNAMIC_TYPESr  r   )subnets    r    subnet_is_ipv6r  
  sG     f~s#vf~9K'K	8	#

98M(Nr%   c                 X    t        t        j                  d|        j                        S )zConvert a network prefix to an ipv4 netmask.

    This is the inverse of ipv4_mask_to_net_prefix.
        24 -> "255.255.255.0"
    Also supports input as a string.0.0.0.0/)r   r  r  netmask)prefixs    r    net_prefix_to_ipv4_maskr    s'     y$$xx%89AABBr%   c                 F    t        j                  d|        j                  S )a  Convert an ipv4 netmask into a network prefix length.

    If the input is already an integer or a string representation of
    an integer, then int(mask) will be returned.
       "255.255.255.0" => 24
       str(24)         => 24
       "24"            => 24
    r  )r  r  	prefixlen)masks    r    ipv4_mask_to_net_prefixr  !  s"     (4& 12<<<r%   c                    	 t        j                  d|        j                  }|S # t        $ r Y nw xY wt        j                  |       }t        |      }|dk(  r|S t        t         j                  | |dz
  z  j                               }||z	  }t         j                  |z
  }d|z  dz
  }||k7  rt        d| z        |S )zConvert an ipv6 netmask (very uncommon) or prefix (64) to prefix.

    If the input is already an integer or a string representation of
    an integer, then int(mask) will be returned.
       "ffff:ffff:ffff::"  => 48
       "48"                => 48
    z::/r   r  zInvalid network mask '%s')	r  r  r  rK   r  r   min
IPV6LENGTH
bit_length)r  r  r  mask_inttrailing_zeroesleading_onesall_oness          r    ipv6_mask_to_net_prefixr  -  s    ((3tf6@@	  	
 ""4(G7|H1}yHqL9EEGO .L$$6IY!#Hx4t;<<s   #& 	22r  r)  c                 `    t        t        j                  | d|  d      j                        S )zCGet string representation of broadcast address from an ip/mask pairr(   Fr  )r   r  r  broadcast_address)r  r)  s     r    mask_and_ipv4_to_bcast_addrr  P  s/    AdVnU;MM r%   c                       e Zd Zy)RendererNotFoundErrorN)r   r   r   r$   r%   r    r  r  W  s    r%   r  )r   )NNNNr   )F)T)TTN)TTTTTTF)hr.   	functoolsr  loggingrX   r   typingr   r   r   r   r   r   urllib.parser	   	cloudinitr
   r   cloudinit.url_helperr   r   	getLoggerr   r8   r#   r   r  rx   r1  r!   r&   r,   rB   rI   rM   rT   r[   r^   rb   rh   rk   ro   	lru_cachers   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r&  r=  ri  rm  rr  r   r   r{  rt  ru  rv  rw  r   r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r$   r%   r    <module>r     s$       	 	 = = !   2g!!"  % ! )bjj4 

7 "JH;<G$6 T"$  # T" T   # (s t 
t 0B01
A) A+
.T#Y 
.,8C= ,J$s) J	 	JS	 J	hsm 	Fd3i FR	HSM 	>-G`$(+^ BF`.F+0t 0c hsm $ 8  $  D DP -1(,?C#' !&9%)9!%9 9=9 	9
 !9 9 9 
9x'%i('%U3S#-./'% 
'%T $4S> $d $N( S &	B3 	B4 	B	CS 	CT 	C	CS 	CT 	C	P3 	P4 	PS T S T d Cs C	=S 	= S  Fc s s 	L 	r%   