
    x[hF`                     P   d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZmZmZ d dlmZ d dlmZ  ej&                  e      Zg g dd	d
Z G d de
      Zd Z ej2                  dd      d        Zd Zd Z	 ddeeeeef   f   fdZd Zd Z d Z!d Z"d Z#ddZ$y)    N)copydeepcopy)IPv4Network)DictList	TypedDict)	lifecyclesubputil)net_prefix_to_ipv4_mask)SimpleTable Fipv4ipv6hwaddrupc                   B    e Zd ZU eed<   eed<   ee   ed<   ee   ed<   y)	Interfacer   r   r   r   N)__name__
__module____qualname__bool__annotations__strr   dict     3/usr/lib/python3/dist-packages/cloudinit/netinfo.pyr   r   ,   s     HK
t*
t*r   r   c           	         t        j                  |       }i }|D ]X  }d|v r|d   ng }|j                  d      dk(  r|d   nd}|t        d|v xr d|v       g g d}|j                  d	g       D ]  }|j                  d
      dk(  rvd|v r$t	        t        d|d          j                        nd}|j                  dd      ||j                  dd      |j                  dd      d}	|d   j                  |	       |d
   dk(  s|j                  dd      }
|
r(|j                  d      s|
 d|j                  dd       }
|
|j                  dd      d}	|d   j                  |	        |||d   <   [ |S )a&  Get network device dicts from ip route and ip link info.

    ipaddr_json: Output string from 'ip --json addr' command.

    Returns a dict of device info keyed by network device name containing
    device configuration values.

    Raises json.JSONDecodeError if json could not be decoded
    flags	link_typeetheraddressr   UPLOWER_UP)r   r   r   r   	addr_infofamilyinet	prefixlenz0.0.0.0/local	broadcastscope)ipmaskbcastr-   r   inet6/@   )r.   scope6r   ifname)jsonloadsgetr   r   r   netmaskappend)ipaddr_jsonipaddr_datadevsdevr!   r$   dev_infoaddrr/   parsed_addrr.   s              r   _netdev_info_iproute_jsonrB   3   s    **[)KD %' '3GB$'GGK$8G$C#i.tu}<u)<=	
 GGK, 	5Dxx!V+ #d* htK/@.A$BCKKL  ((7B/ !XXk26!XXgr2	  ''4h7*XXgr* dhhy14q+r!: ;<B"hhw3  ''47	58 'S]K%'L Kr   z22.1zqRequired by old iproute2 versions that don't support ip json output. Consider upgrading to a more recent version.)deprecated_versionextra_messagec                 0   i }d}t        | j                               D ]  \  }}t        j                  d|      }|rm|j	                  d      j                         j                  d      d   }|j	                  d      j                  d      }g g dt        d	|v xr d
|v       d||<   d|v rVt        j                  d|      }|st        j                  d||       ||   d   j                  |j                                d|v rt        j                  d|      }|st        j                  d||       |j                         }|j                  d      }|j                  d      \  }	}
}|sd}||   d   j                  |	|d   r|d   ndt        |      |d   d       d|v rht        j                  d|      }|st        j                  d||       |j	                  d      dk(  r|j	                  d      ||   d<   d||   d<    |S )z
    @param ipaddr_out: Output string from 'ip addr show' command.

    @returns: A dict of device info keyed by network device name containing
              device configuration values.
    @raise: TypeError if ipaddr_out isn't a string.
    Nz.^\d+:\s(?P<dev>[^:]+):\s+<(?P<flags>\S+)>\s+.*r>   @r   r!   ,r   r%   r&   r   r1   z?\s+inet6\s(?P<ip>\S+)(\s(peer\s\S+))?\sscope\s(?P<scope6>\S+).*z*Could not parse ip addr show: (line:%d) %sr   r)   zd\s+inet\s(?P<cidr4>\S+)(\smetric\s(?P<metric>\d+))?(\sbrd\s(?P<bcast>\S+))?\sscope\s(?P<scope>\S+).*cidr4r2   32r   r0   r-   )r.   r0   r/   r-   linkz-\s+link/(?P<link_type>\S+)\s(?P<hwaddr>\S+).*r"   r#   r   )	enumerate
splitlinesrematchgrouplowersplitr   LOGwarningr:   	groupdictpop	partitionr   )
ipaddr_outr=   dev_namenumlinemr!   rN   rH   r@   _prefixs               r   _netdev_info_iprouter^   i   s2    DHz4467 @	THHFMwwu~++-33C8;HGGG$**3/E45=@Z5-@A	DN _. 	A @#t N6"))!++-8t^- A @#t KKMEIIg&E#ooc2OD!VN6"))/4W~U7^23F;"7^	 t^@$A @#t ww{#w.+,778+<Xx(+-Xx(A@B Kr   c                    i }| j                         D ]R  }|s|d   dvr?|j                         d   }|j                  d      r|d d }||vrt        t              ||<   |j                         j                         j                         }t        |      dkD  r!t        j                  d|d         rd|   d<   t        t        |            D ]  }||   d	k(  r>||dz      j                  d
      \  }}|   d   j                  |t        |      d       J||   dk(  r||dz      |   d   d   d<   g||   dk(  r||dz      |   d<   ~||   dk(  rK||dz      dk(  r |   d   j                  d||dz      i       |   d   j                  d||dz      i       ||   dk(  r*|   d   d   d   d
z   ||dz      z   }|||   d   d   d<   ||   j                  d      r"||   j                  d      |   d   d   d<   9||   dk(  sCt        j                  d||dz            }	|	r|	j!                  d      |   d   d   d<   ||dz      |   d   d   d<    U |S )Nr   	 :   zflags=[x\d]+<up.*>Tr   r)   r2   r   )r.   r/   r,   r0   zaddress:r   r1   addr:r   r.      r*   scope:r4   scopeid	.*<(\S+)>)rL   rQ   endswithr   DEFAULT_NETDEV_INFOrP   striplenrM   searchranger:   r   
startswithlstriprN   rO   )
ifconfig_datar=   rZ   curdevtoksinetworknet_bitsaddr6ress
             r   _netdev_info_ifconfig_netbsdr{      s   D((* (E7+%ZZ\!_Fs#T!'(;<Vzz|!!#))+t9q=yy.Q8%)VT"s4y! 	EAAw& $(QK$5$5c$:!VV$++",CH,MN aK'48QKVV$R(1aJ&)-a!eVX&aG#A;')L(//tAE{0CDL(//tAE{0CDaK'VV,R06<tAE{J16VV$R(.a##H-59!W^^H5MVV$R(2aI%hh|T!a%[99<1DL(,X69=a!eDL(,X63	E(ET Kr   c                    i }| j                         D ]  }|s|d   dvr?|j                         d   }|j                  d      r|d d }||vrt        t              ||<   |j                         j                         j                         }|d   dk(  r	d|   d<   n/t        |      dkD  r!t        j                  d|d         rd|   d<   t        t        |            D ]  }||   d	k(  r/|   d
   j                  d||dz      j                  d      i       ;||   j                  d      r!||   j                  d      |   d
   d   d<   p||   dk(  r||dz      |   d
   d   d<   ||   j                  d      r!||   j                  d      |   d
   d   d<   ||   dk(  r||dz      |   d
   d   d<   ||   dk(  s||   dk(  r||dz      |   d<   ||   dk(  rM||dz      dk(  r!|   d   j                  d||dz      i       2|   d   j                  d||dz      i       S||   dk(  r*|   d   d   d   dz   ||dz      z   }|||   d   d   d<   ||   j                  d      r"||   j                  d      |   d   d   d<   ||   dk(  st        j                  d||dz            }|r|j                  d      |   d   d   d<   ||dz      |   d   d   d<     |S )Nr   r`   rc   rd   r   Tre   zflags=\d+<up,r)   r   r.   rf   zbcast:r0   r,   zmask:r/   r9   r   r#   r1   r   rg   r*   r2   rh   r4   ri   rj   )rL   rQ   rk   r   rl   rP   rm   rn   rM   ro   rp   r:   rr   rq   rN   rO   )rs   r=   rZ   rt   ru   rv   ry   rz   s           r   _netdev_info_ifconfigr}      sy   D((* 1E7+%ZZ\!_Fs#T!'(;<Vzz|!!#))+7d?!%DL Y]yy)473%)VT"s4y! 	EAAw& VV$++4A;--g67 a##H-48GNN84LVV$R(1aK'48QKVV$R(1a##G,377>>'3JVV$R(0aI%37A;VV$R(0aH$Q7(:)-a!eVX&aG#A;')L(//tAE{0CDL(//tAE{0CDaK'VV,R06<tAE{J16VV$R(.a##H-59!W^^H5MVV$R(2aI%hh|T!a%[99<1DL(,X69=a!eDL(,X6=	E'1Ef Kr   returnc                 x   i }t        j                         r*t        j                  ddgddg      \  }}t        |      }nt        j                  d      r'	 t        j                  g d      \  }}t        |      }nTt        j                  d      r*t        j                  ddgddg      \  }}t        |      }nt        j                  d	       | d
k(  r|S t        t        t        fdfd	 ||        |S # t        j                  $ r( t        j                  g d      \  }}t        |      }Y ew xY w)af  return the instance's interfaces and interface data

    includes, interface name, link state, hardware address, and lists of ipv4
    and ipv6 addresses

    example output:
    {
    'lo': {
        'up': True,
        'hwaddr': '',
        'ipv4': [
        {
            'bcast': '',
            'ip': '127.0.0.1',
            'mask': '255.0.0.0',
            'scope': 'host',
        }],
        'ipv6': [{'ip': '::1/128', 'scope6': 'host'}],
    },
    'lxdbr0': {
        'up': True
        'hwaddr': '00:16:3e:fa:84:30',
        'ipv4': [{
            'bcast': '',
            'ip': '10.161.80.1',
            'mask': '255.255.255.0',
            'scope': 'global',
        }],
        'ipv6': [
            {'ip': 'fd42:80e2:4695:1e96::1/64', 'scope6': 'global'},
            {'ip': 'fe80::216:3eff:fefa:8430/64', 'scope6': 'link'},
        ]
    },
    }

    ifconfigz-ar   re   rcsr.   )r.   z--jsonr@   )r.   r@   showz>Could not print networks: missing 'ip' and 'ifconfig' commandsr   c                     t        | t              r| j                         }n-t        | t        t        f      rt        |       }nt        d      |D ]%  \  }}||v r|| |<   t        |      s ||       ' y)zQRecursively replace 'empty_vals' in data (dict, tuple, list)
        with new_valzUnexpected input to fillN)
isinstancer   itemstuplelistrK   	TypeError)datanew_val
empty_valsmyiterkeyvalfillrecurse_typess         r   r   znetdev_info.<locals>.fillg  su     dD!ZZ\Fudm,t_F677 	#HCj #S	C/S'"		#r   )r   )r   )r   r   )r   	is_NetBSDr
   r{   whichrB   ProcessExecutionErrorr^   r}   rR   rS   r   r   r   )emptyr=   	ifcfg_out_errrW   r   r   s        @@r   netdev_infor   %  s   N D~~ IIz4&8q!fED+I6	D		4!%+C!DZ,Z8D
 
J	 IIz4&8q!fED$Y/L	
 {5$'M#  	uKG )) 	4!%+A!BZ'
3D	4s   %C> >8D98D9c                    i }g |d<   g |d<   | j                         }ddddddd}|D ]!  }t        |      }|s|j                         }dg}|d   dk(  rd|d	<   d|d
<   n]d|d   v r|d   j                  d      \  }}	n&|d   }d}	|j                  d       t	        |	      |d
<   ||d	<   t	        |	      |d
<   d|d<   t        t        |            D ]N  }
||
   dk(  r||
dz      |d<   |j                  dd       ||
   dk(  r||
dz      |d<   ||
   dk(  sD||
dz      |d<   P dj                  |      |d<   |d   j                  |       $ 	 t        j                  g dddg      \  }}|j                         }|D ]  }i }|s|j                         }|d   dk(  rd|d	<   d|d<   n|d   |d	<   d|d<   d|d<   t        t        |            D ]T  }
||
   dk(  r||
dz      |d<   d|d<   ||
   dk(  r||
dz      |d<   ||
   dk(  r||
dz      |d<   ||
   dk(  sJ|d   dz   |d<   V |d   j                  |        |S # t        j                  $ r Y |S w xY w)aP  
    Get network route dicts from ip route info.

    @param iproute_data: Output string from ip route command.

    @returns: A dict containing ipv4 and ipv6 route entries as lists. Each
              item in the list is a route dictionary representing destination,
              gateway, flags, genmask and interface information.
    r   r   r   )destinationr!   gatewaygenmaskifacemetricUr   default0.0.0.0r   r   r2   rI   Hr   viare   Gr>   r   r   r!   )r.   z	--onelinez-6router   tableallr   z::/0UG::expirese)rL   r   rQ   r:   r   rp   rn   insertjoinr
   r   )iproute_dataroutesentriesdefault_route_entryrZ   entryru   r!   r@   cidrrv   iproute_data6_err6entries6s                 r   _netdev_route_info_iprouter   {  s    FF6NF6N%%'G  %()zz|7i#,E- (E)d1g~#Aw}}S1tAwS!#:4#@i #'E- 6t<E)(E)s4y! 	.AAw%#'A;i Q$Aw%!%a!egAw(""&q1u+h	. gve$;%<)!%FA"
 !++- 	)DE::<DAw)#'-m$!%g'+Awm$#'i !$g3t9% 	:7e#'+AE{E)$%)E'N7e#%)!a%[E'N7h&&*1q5kE(O7i'%*7^c%9E'N	: 6N!!%(-	). M7 %% 4 M7s   H> >IIc           
         i }g |d<   g |d<   | j                         }|D ]  }|s|j                         }t        |      dk  s(|d   dk(  s |d   dk(  s|d   dk(  s|d   dk(  s|d   d	k(  rMt        |      d
k  r/|j                  d       |j                  d       |d   |d<   d|d<   |d   |d   |d   |d   |d   |d   |d   |d   d}|d   j                  |        	 t	        j                  g dddg      \  }}|j                         }|D ]  }|s|j                         }t        |      dk  s(|d   dk(  s |d   dk(  s|d   dk(  s|d   dk(  s|d   dk(  rM|d   |d   |d   |d   |d   |d   |d   d}|d   dk(  ru|d   j                  d      rt        j                  dd|d         |d<   |d   j                  |        |S # t        j                  $ r Y |S w xY w)Nr   r      r   KernelDestinationInternet	Internet6Routing   -      re   rg         )r   r   r   r!   r   refuser   )netstatz-Ar1   --route	--numericr   ProtoActive)r   r   r!   r   r   r   r   r   lor   z/128z\/128$r   )	rL   rQ   rn   r:   r
   rk   rM   subr   )	
route_datar   r   rZ   ru   r   route_data6r   r   s	            r   _netdev_route_info_netstatr     sv   FF6NF6N##%G #%zz| IMAw("Aw-'Aw*$Aw+%Aw)#t9q=KKKK1gDGDG7AwAw!W1g77!W	
 	ve$G#%J&)#yy>QF 
e ))+ 	)D::<DD	A7h&7m+7j(7g%7h&#Aw7aq'AwAwaE W~%]#,,V4')vvr5#7(m$ 6N!!%(=	)> MG %% D MGs   #G G('G(c                  ,   i } t        j                  d      r't        j                   g d      \  }}t        |      } | S t        j                  d      r+t        j                   g dddg      \  }}t        |      } | S t        j                  d       | S )	Nr.   )r.   z-or   r   r   )r   r   r   z--extendr   re   r   z;Could not print routes: missing 'ip' and 'netstat' commands)r
   r   r   r   rR   rS   )r   iproute_outr   	route_outs       r   
route_infor   (  s    Fzz$"ii(EFd+K8 M 
I	 II;!Q
D ,I6
 M 	I	
 Mr   c                     g } d}	 t        |      }|syg d}t        |      }t        |j                               D ]  \  }}|j	                  d      }|D ]5  }|j                  ||d   |d   |d   |j	                  d	|      |d
   f       7 |j	                  d      }	|	D ]2  }|j                  ||d   |d   ||j	                  d|      |d
   f       4 |r|	r|j                  ||d   ||||d
   f        |j                         }
t        t        |
j                         t                    }t        j                  dd|      }| j                  ||
g       dj#                  |       dz   S # t        $ rI}| j                  t        j                  dj                  t!        |            dd             Y d }~ad }~ww xY w)N.)r   
)DeviceUpAddressMaskScopez
Hw-Addressr   r   r.   r/   r-   r   r   r4   r   zNet device info+z Net device info failed ({error})error!P   )r   r   sortedr   r8   add_row
get_stringrn   maxrL   r   centerextend	Exceptionr:   formatr   r   )linesr   netdevfieldstblr>   r   
ipv4_addrsr@   
ipv6_addrsnetdev_smax_lenheaderr   s                 r   netdev_pformatr   ;  s   EE0)5) K&!/ 	IC&)J" 
T
T
V%0X	
 &)J" 
T
T
51X	
 $t*eUE4>J7	< >>#c(--/S9:.W=fh'(99Ud""_  
KK299A9G	
 	

s   E1 1	G:?F>>Gc            
         g } 	 t               }|j                  d      rg d}t        |      }t        |j                  d            D ]D  \  }}t	        |      }	 |j                  ||d   |j                  dd      |d   |d   |d   g       F |j                         }t        t        |j                         t        
            }	t        j                  dd|	      }
| j                  |
|g       |j                  d      rg d}t        |      }t        |j                  d            D ]I  \  }}t	        |      }|d   dk(  r	 |j                  ||d   |j                  dd      |d   |d   g       K |j                         }t        t        |j                         t        
            }	t        j                  dd|	      }
| j                  |
|g       	 dj'                  |       dz   S # t        $ r(}t        j                  t        d	|z         Y d }~d }~ww xY w# t        $ r(}t        j                  t        d	|z         Y d }~#d }~ww xY w# t         $ rf}| j#                  t        j                  dj%                  t	        |            dd             t        j                  t        d|z         Y d }~d }~ww xY w)Nr   )Router   GatewayGenmaskr   Flagsr   r   r   r   r   r!   zRoute info formatting error: %sr   zRoute IPv4 infor   r   )r   r   r   r   r   r   r   zRoute IPv6 infozRoute info failed ({error})r   r   r   zRoute info failed: %sr   )r   r8   r   rK   r   r   KeyErrorr   logexcrR   r   rn   r   rL   r   r   r   r:   r   r   )r   r   	fields_v4tbl_v4nrroute_idr   route_sr   r   	fields_v6tbl_v6s                r   route_pformatr  r  s   EC, ::fI !+F!&**V"45 L1q6LNN$m,EE)Y7iLgJgJ	L '')G#g002<=G[[!2CAFLL&'*+::fI !+F!&**V"45 L1q6W:%LNN$m,EE)T2gJgJL  '')G#g002<=G[[!2CAFLL&'*+99Ud""G   LKK%F%JKKL:   LKK%F%JKKLy  6KK-443q64BC	

 	C014556sH   
I 3G./H".	H7HH"	I+II	KAK  Kc                 H   g }t               j                         }| r|D ]  }|j                  | |        n|j                  |       t	               j                         }| r|D ]  }|j                  | |        n|j                  |       dj                  |      S )Nr   )r   rL   r:   r   r  r   )r]   r   netdev_linesrZ   route_liness        r   
debug_infor    s    E!#..0L  	2DLL6401	2 	\"/,,.K 	2DLL6401	2 	[!99Ur   )r   )z	ci-info: )%r6   loggingrM   r   r   	ipaddressr   typingr   r   r   	cloudinitr	   r
   r   cloudinit.net.network_stater   cloudinit.simpletabler   	getLoggerr   rR   rl   r   rB   deprecate_callr^   r{   r}   r   r   r   r   r   r   r  r  r   r   r   <module>r     s      	  ! ( ( + + ? -g!&  "25I 	 3l K
K
K\-`6t S	#tCN#
#$SlUpRj&4#nF#Rr   