o
    쑛hF`                     @   s"  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eZg g dd	d
ZG dd de
Zdd Zejddddd Zdd Zdd Z	d(deeeeef f fddZdd Zdd Z dd  Z!d!d" Z"d#d$ Z#d)d&d'Z$dS )*    N)copydeepcopy)IPv4Network)DictList	TypedDict)	lifecyclesubputil)net_prefix_to_ipv4_mask)SimpleTable Fipv4ipv6hwaddrupc                   @   s6   e Zd ZU eed< eed< ee ed< ee ed< dS )	Interfacer   r   r   r   N)__name__
__module____qualname__bool__annotations__strr   dict r   r   3/usr/lib/python3/dist-packages/cloudinit/netinfo.pyr   ,   s
   
 r   c              	   C   sJ  t | }i }|D ]}d|v r|d ng }|ddkr |d nd}|td|v o+d|v g g d}|d	g D ]d}|d
dkrmd|v rPttd|d  jnd}|dd||dd|ddd}	|d |	 q7|d
 dkr|dd}
|
r|ds|
 d|dd }
|
|ddd}	|d |	 q7|||d < q	|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*   r   r   r   _netdev_info_iproute_json3   sB   





r>   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                 C   s  i }d}t |  D ]\}}td|}|r<|d dd }|dd}g g dtd	|v o5d
|v d||< q
d|v r\td|}|sPt	d|| q
|| d 
|  q
d|v rtd|}|spt	d|| q
| }|d}|d\}	}
}|sd}|| d 
|	|d r|d ndt||d d q
d|v rtd|}|st	d|| q
|ddkr|d|| d< q
d|| d< q
q
|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   r-   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+).*cidr4r.   32r   r,   r)   )r*   r,   r+   r)   linkz-\s+link/(?P<link_type>\S+)\s(?P<hwaddr>\S+).*r   r   r   )	enumerate
splitlinesrematchgrouplowersplitr   LOGwarningr6   	groupdictpop	partitionr   )
ipaddr_outr9   dev_namenumlinemr   rI   rC   r<   _prefixr   r   r   _netdev_info_iproutei   sv   
rY   c           
      C   sf  i }|   D ])}|sq|d dvr-| d }|dr#|d d }||vr-tt||< |   }t|dkrIt	d|d rId|| d< t
t|D ]}|| d	krq||d  d
\}}|| d |t|d qO|| dkr||d  || d d d< qO|| dkr||d  || d< qO|| dkr||d  dkr|| d d||d  i qO|| d d||d  i qO|| dkr|| d d d d
 ||d   }||| d d d< qO|| dr|| d|| d d d< qO|| dkr/td||d  }	|	r!|	d|| d d d< qO||d  || d d d< qOq|S )Nr   	 :   zflags=[x\d]+<up.*>Tr   r%   r.   r   )r*   r+   r(   r,   zaddress:r   r-   addr:r   r*      r&   scope:r0   scopeid	.*<(\S+)>)rG   rL   endswithr   DEFAULT_NETDEV_INFOrK   striplenrH   searchranger6   r   
startswithlstriprI   rJ   )
ifconfig_datar9   rU   curdevtoksinetworknet_bitsaddr6resr   r   r   _netdev_info_ifconfig_netbsd   sR   
  $ ru   c                 C   s  i }|   D ]}}|sq|d dvr-| d }|dr#|d d }||vr-tt||< |   }|d dkrBd|| d< nt|dkrVt	d|d rVd|| d< t
t|D ]&}|| d	krx|| d
 d||d  di q\|| dr|| d|| d
 d d< q\|| dkr||d  || d
 d d< q\|| dr|| d|| d
 d d< q\|| dkr||d  || d
 d d< q\|| dks|| dkr||d  || d< q\|| dkr||d  dkr|| d d||d  i q\|| d d||d  i q\|| dkr;|| d d d d ||d   }||| d d d< q\|| drS|| d|| d d d< q\|| dkrtd||d  }|ru|d|| d d d< q\||d  || d d d< q\q|S )Nr   rZ   r]   r^   r   Tr_   zflags=\d+<up,r%   r   r*   r`   zbcast:r,   r(   zmask:r+   r5   r   r   r-   r   ra   r&   r.   rb   r0   rc   rd   )rG   rL   re   r   rf   rK   rg   rh   rH   ri   rj   r6   rl   rk   rI   rJ   )rm   r9   rU   rn   ro   rp   rs   rt   r   r   r   _netdev_info_ifconfig   s`   
    $  rv   returnc                    s   i }t  rtjddgddgd\}}t|}nHtdrDztg d\}}t|}W n3 tjyC   tg d\}}t|}Y nw tdr[tjddgddgd\}}t|}nt	
d	 | d
krf|S tttfd fdd	  || d |S )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   r_   rcsr*   )r*   z--jsonr<   )r*   r<   showz>Could not print networks: missing 'ip' and 'ifconfig' commandsr   r       c                    sl   t | tr
|  }nt | ttfrt| }ntd|D ]\}}||v r)|| |< qt |r3 || qdS )zQRecursively replace 'empty_vals' in data (dict, tuple, list)
        with new_valzUnexpected input to fillN)
isinstancer   itemstuplelistrF   	TypeError)datanew_val
empty_valsmyiterkeyvalfillrecurse_typesr   r   r   g  s   





znetdev_info.<locals>.fill)r   N)r   r|   )r
   	is_NetBSDr	   ru   whichr>   ProcessExecutionErrorrY   rv   rM   rN   r   r   r   )emptyr9   	ifcfg_out_errrR   r   r   r   netdev_info%  s0   '




r   c                 C   s  i }g |d< g |d< |   }ddddddd}|D ]}t|}|s"q| }dg}|d dkr8d|d	< d|d
< n/d|d v rH|d d\}}	n|d }d}	|d t|	|d
< ||d	< t|	|d
< d|d< tt|D ]2}
||
 dkr||
d  |d< |dd ||
 dkr||
d  |d< ||
 dkr||
d  |d< qmd||d< |d | qzt	j	g dddgd\}}W n t	j
y   Y |S w |  }|D ]x}i }|sq| }|d dkrd|d	< d|d< n|d |d	< d|d< d|d< tt|D ]B}
||
 dkr||
d  |d< d|d< ||
 dkr"||
d  |d< ||
 dkr1||
d  |d< ||
 dkr@|d d |d< q|d | q|S )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   r.   rD   Hr   viar_   Gr:   r   r   r   )r*   z	--onelinez-6router   tableallry   z::/0UG::expirese)rG   r   rL   r6   r   rj   rh   insertjoinr	   r   )iproute_dataroutesentriesdefault_route_entryrU   entryro   r   r<   cidrrp   iproute_data6_err6entries6r   r   r   _netdev_route_info_iproute{  s   


r   c           	   
   C   s
  i }g |d< g |d< |   }|D ]j}|sq| }t|dk s=|d dks=|d dks=|d dks=|d dks=|d d	kr>qt|d
k rX|d |d |d |d< d|d< |d |d |d |d |d |d |d |d d}|d | qztjg dddgd\}}W n tjy   Y |S w |  }|D ]f}|sq| }t|dk s|d dks|d dks|d dks|d dks|d dkrq|d |d |d |d |d |d |d d}|d dkrq|d drtdd|d |d< |d | q|S )Nr   r      r   KernelDestinationInternet	Internet6Routing   -      r_   ra         )r   r   r   r   r   refuser   )netstatz-Ar-   --route	--numericry   ProtoActive)r   r   r   r   r   r   r   r   lor   z/128z\/128$r   )	rG   rL   rh   r6   r	   r   re   rH   sub)	
route_datar   r   rU   ro   r   route_data6r   r   r   r   r   _netdev_route_info_netstat  s   	


"

r   c                  C   sj   i } t drt  g d\}}t|} | S t dr.t j g dddgd\}}t|} | S td | S )	Nr*   )r*   z-or   r   r   )r   r   r   z--extendr   r_   ry   z;Could not print routes: missing 'ip' and 'netstat' commands)r	   r   r   r   rM   rN   )r   iproute_outr   	route_outr   r   r   
route_info(  s   


r   c                  C   sv  g } d}zt |d}W n" ty- } z| tdjt|ddd W Y d }~nd }~ww |s2dS g d}t|}t|	 D ]W\}}|
d	}|D ]}	|||d
 |	d |	d |	
d||d f qK|
d}
|
D ]}	|||d
 |	d ||	
d||d f ql|s|
s|||d
 ||||d f q@| }tt| td}tdd|}| ||g d| d S )N.)r   z Net device info failed ({error})error!P   
)DeviceUpAddressMaskScopez
Hw-Addressr   r   r*   r+   r)   r   r   r0   r   zNet device info+)r   	Exceptionr6   r
   centerformatr   r   sortedr   r4   add_row
get_stringrh   maxrG   extendr   )linesr   netdevr   fieldstblr:   r   
ipv4_addrsr<   
ipv6_addrsnetdev_smax_lenheaderr   r   r   netdev_pformat;  sf   	




r   c                  C   s,  g } zt  }W n* ty1 } z| tdjt|ddd ttd|  W Y d }~nd }~ww |	drg d}t
|}t|	dD ];\}}t|}z|||d |	d	d
|d |d |d g W qF ty } zttd|  W Y d }~qFd }~ww | }tt| td}	tdd|	}
| |
|g |	drg d}t
|}t|	dD ]?\}}t|}|d dkrqz|||d |	d	d|d |d g W q ty } zttd|  W Y d }~qd }~ww | }tt| td}	tdd|	}
| |
|g d| d S )NzRoute info failed ({error})r   r   r   zRoute info failed: %sr   )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 infor   )r   r   r6   r
   r   r   r   logexcrM   r4   r   rF   r   KeyErrorr   rh   r   rG   r   r   )r   r   r   	fields_v4tbl_v4nrroute_idroute_sr   r   	fields_v6tbl_v6r   r   r   route_pformatr  sx   




	r   	ci-info: c                 C   sz   g }t   }| r|D ]}|d| |f  qn|| t  }| r3|D ]}|d| |f  q&n|| d|S )Nz%s%sr   )r   rG   r6   r   r   r   )rX   r   netdev_linesrU   route_linesr   r   r   
debug_info  s   




r   )r   )r   )%r2   loggingrH   r   r   	ipaddressr   typingr   r   r   	cloudinitr   r	   r
   cloudinit.net.network_stater   cloudinit.simpletabler   	getLoggerr   rM   rf   r   r>   deprecate_callrY   ru   rv   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s<   

6
N0:
VXU7I