o
    w7e\                     @   s   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 d dlm	Z	m
Z
 d dlmZ d dlmZ eeZg g dd	d
Zdd Ze
jddddd Zdd Zdd Zd%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)log)subputil)net_prefix_to_ipv4_mask)SimpleTable Fipv4ipv6hwaddrupc              	   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getboolstrr   netmaskappend)ipaddr_jsonipaddr_datadevsdevr   r   dev_infoaddrr   parsed_addrr    r3   3/usr/lib/python3/dist-packages/cloudinit/netinfo.py_netdev_info_iproute_json+   sB   





r5   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warningr+   	groupdictpop	partitionr   )
ipaddr_outr.   dev_namenumlinemr   r@   r:   r1   _prefixr3   r3   r4   _netdev_info_iproutea   sv   
rP   c           
      C   sp  i }|   D ].}t|dkrq|d dvr1| d }|dr'|d d }||vr1tt||< |   }t|dkrMt	d|d rMd|| d< t
t|D ]}|| d	kru||d  d
\}}|| d |t|d qS|| dkr||d  || d d d< qS|| dkr||d  || d< qS|| dkr||d  dkr|| d d||d  i qS|| d d||d  i qS|| dkr|| d d d d
 ||d   }||| d d d< qS|| dr|| d|| d d d< qS|| dkr4td||d  }	|	r&|	d|| d d d< qS||d  || d d d< qSq|S )Nr   	 :   zflags=[x\d]+<up.*>Tr   r   r!   r   )r   r   r   r   zaddress:r   r    addr:r   r      r   scope:r#   scopeid	.*<(\S+)>)r>   lenrC   endswithr   DEFAULT_NETDEV_INFOrB   stripr?   searchranger+   r   
startswithlstripr@   rA   )
ifconfig_datar.   rL   curdevtoksinetworknet_bitsaddr6resr3   r3   r4   _netdev_info_ifconfig_netbsd   sR   
  $ rl   c                 C   s  i }|   D ]}t|dkrq|d dvr1| d }|dr'|d d }||vr1tt||< |   }|d dkrFd|| d< nt|dkrZt	d|d rZd|| d< t
t|D ]&}|| d	kr||| 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rW|| d|| d d d< q`|| dkrtd||d  }|ry|d|| d d d< q`||d  || d d d< q`q|S )Nr   rQ   rT   rU   r   TrV   zflags=\d+<up,r   r   r   rW   zbcast:r   r   zmask:r   r*   r   r   r    r   rX   r   r!   rY   r#   rZ   r[   )r>   r\   rC   r]   r   r^   rB   r_   r?   r`   ra   r+   rc   rb   r@   rA   )rd   r.   rL   re   rf   rg   rj   rk   r3   r3   r4   _netdev_info_ifconfig   s`   
    $  rm   c                    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 )Nifconfigz-ar   rV   rcsr   )r   z--jsonr1   )r   r1   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)
isinstancedictitemstuplelistr=   	TypeError)datanew_val
empty_valsmyiterkeyvalfillrecurse_typesr3   r4   r   9  s   





znetdev_info.<locals>.fill)r{   )r
   rr   )r   	is_NetBSDr   rl   whichr5   ProcessExecutionErrorrP   rm   rD   rE   ru   rw   rx   )emptyr.   	ifcfg_out_errrI   r3   r   r4   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!   r;   Hr   viarV   Gr/   r   r   r   )r   z	--onelinez-6routerx   tableallro   z::/0UG::expirese)r>   r   rC   r+   r   ra   r\   insertjoinr   r   )iproute_dataroutesentriesdefault_route_entryrL   entryrf   r   r1   cidrrg   iproute_data6_err6entries6r3   r3   r4   _netdev_route_info_iprouteM  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   -      rV   rX         )r   r   r   r   r   refuser   )netstatz-Ar    --route	--numericro   ProtoActive)r   r   r   r   r   r   r   r   lor   z/128z\/128$r
   )	r>   rC   r\   r+   r   r   r]   r?   sub)	
route_datar   r   rL   rf   r   route_data6r   r   r3   r3   r4   _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   rx   r   )r   r   r   z--extendr   rV   ro   z;Could not print routes: missing 'ip' and 'netstat' commands)r   r   r   r   rD   rE   )r   iproute_outr   	route_outr3   r3   r4   
route_info  s   


r   c                  C   s  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 ]_\}}|
d	D ]}|||d
 |d |d |
d||d f qI|
dD ]}|||d
 |d ||
d||d f qht|
dt|
d	 dkr|||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   r#   r   r~   zNet device info+)r   	Exceptionr+   r   centerformatr)   r	   sortedrv   r'   add_rowr\   
get_stringmaxr>   extendr   )linesr   netdevr   fieldstblr/   rz   r1   netdev_smax_lenheaderr3   r3   r4   netdev_pformat  sb   	


 
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Genmask	Interface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   r+   r   r   r   r)   logexcrD   r'   r	   r=   r   KeyErrorr   r\   r   r>   r   r   )r   r   r   	fields_v4tbl_v4nrroute_idroute_sr   r   	fields_v6tbl_v6r3   r3   r4   route_pformatA  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   r>   r+   r   r   r   )rO   r   netdev_linesrL   route_linesr3   r3   r4   
debug_info  s   




r   )r
   )r   )r%   r?   r   r   	ipaddressr   	cloudinitr   loggingr   r   cloudinit.net.network_stater   cloudinit.simpletabler	   	getLogger__name__rD   r^   r5   deprecate_callrP   rl   rm   r   r   r   r   r   r   r   r3   r3   r3   r4   <module>   s2   

6
N0
90XU4I