U
    AdKZ                     @   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 Zg g dd	d
Zdd Z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   sP  t | }i }|D ]6}d|kr(|d ng }|ddkrB|d nd}|td|koXd|kg g d}|d	g D ]}|d
dkrd|krttd|d  jnd}|dd||dd|ddd}	|d |	 qp|d
 dkrp|dd}
|
r|ds|
 d|dd }
|
|ddd}	|d |	 qp|||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   Z	addr_infoZfamilyinet	prefixlenz0.0.0.0/Zlocal	broadcastscope)ipmaskbcastr   r   inet6/@   )r   scope6r   Zifname)jsonloadsgetboolstrr   netmaskappend)Zipaddr_jsonZipaddr_datadevsdevr   r   Zdev_infoaddrr   Zparsed_addrr    r+   3/usr/lib/python3/dist-packages/cloudinit/netinfo.py_netdev_info_iproute_json+   s@    






r-   c                 C   s  i }d}t |  D ]\}}td|}|rz|d dd }|dd}g g dtd	|kold
|kd||< qd|krtd|}|st	d|| q|| d 
|  qd|krHtd|}|st	d|| q| }|d}|d\}	}
}|sd}|| d 
|	|d r0|d ndt||d d qd|krtd|}|srt	d|| q|ddkr|d|| d< nd|| d< qqq|S )an  
    DEPRECATED: Only used on distros that don't support ip json output
    Use _netdev_info_iproute_json() when possible.

    @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(   Zdev_nameZnumlinemr   r6   r0   r*   _prefixr+   r+   r,   _netdev_info_iproutea   s      
  
   rD   c           
      C   sz  i }|   D ]f}t|dkr q|d dkrb| d }|drN|d d }||krbtt||< |   }t|dkrt	d|d rd|| d< t
t|D ]}|| d	kr||d  d
\}}|| d |t|d q|| dkr||d  || d d d< q|| dkr<||d  || d< q|| dkr||d  dkr||| d d||d  i n|| d d||d  i q|| dkr|| d d d d
 ||d   }||| d d d< q|| dr|| d|| d d d< q|| dkrtd||d  }	|	rV|	d|| d d d< q||d  || d d d< qq|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+)>)r4   lenr9   endswithr   DEFAULT_NETDEV_INFOr8   stripr5   searchranger'   r   
startswithlstripr6   r7   )
ifconfig_datar(   r@   curdevtoksiZnetworkZnet_bitsaddr6resr+   r+   r,   _netdev_info_ifconfig_netbsd   sN    
  $  r^   c                 C   s   i }|   D ]}t|dkr q|d dkrb| d }|drN|d d }||krbtt||< |   }|d dkrd|| d< n(t|dkrt	d|d rd|| d< t
t|D ]V}|| d	kr|| d
 d||d  di q|| dr(|| d|| d
 d d< q|| dkrT||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rB||d  dkr"|| d d||d  i n|| d d||d  i q|| dkr|| d d d d ||d   }||| d d d< q|| dr|| d|| d d d< q|| dkrtd||d  }|r|d|| d d d< q||d  || d d d< qq|S )Nr   rE   rH   rI   r   TrJ   zflags=\d+<up,r   r   r   rK   zbcast:r   r   zmask:r   r&   r   r   r   r   rL   r   r   rM   r    rN   rO   )r4   rP   r9   rQ   r   rR   r8   rS   r5   rT   rU   r'   rW   rV   r6   r7   )rX   r(   r@   rY   rZ   r[   r\   r]   r+   r+   r,   _netdev_info_ifconfig   s\    
    $  r_   c                    s   i }t  r0tjddgddgd\}}t|}ntdrz tdddg\}}t|}W q tjk
r   tddd	g\}}t|}Y qX n8tdrtjddgddgd\}}t|}n
t	
d
 | dkr|S tttfd fdd	  || d |S )NZifconfigz-ar   rJ   Zrcsr   z--jsonr*   Z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 ].\}}||krR|| |< q8t |r8 || q8dS )zQRecursively replace 'empty_vals' in data (dict, tuple, list)
        with new_valzUnexpected input to fillN)
isinstancedictitemstuplelistr3   	TypeError)datanew_valZ
empty_valsZmyiterkeyvalfillZrecurse_typesr+   r,   rn   7  s    




znetdev_info.<locals>.fill)rj   )r
   ra   )r   Z	is_NetBSDr   r^   whichr-   ProcessExecutionErrorrD   r_   r:   r;   rd   rf   rg   )emptyr(   Z	ifcfg_out_errr?   r+   rm   r,   netdev_info  s.    




rs   c                 C   s  i }g |d< g |d< |   }ddddddd}|D ].}t|}|sFq2| }dg}|d dkrrd|d	< d|d
< n^d|d kr|d d\}}	n"|d }d}	|d t|	|d
< ||d	< t|	|d
< d|d< tt|D ]h}
||
 dkr
||
d  |d< |dd ||
 dkr(||
d  |d< ||
 dkr||
d  |d< qd||d< |d | q2z(t	j	dddddddgddgd\}}W n t	j
k
r   Y n
X |  }|D ]}i }|sƐq| }|d dkrd|d	< d|d< n|d |d	< d |d< d|d< tt|D ]}
||
 dkr@||
d  |d< d|d< ||
 dkr^||
d  |d< ||
 dkr|||
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   defaultz0.0.0.0rt   rv   r   r1   Hru   ZviarJ   Gr)   rw   rx   r   r   z	--onelinez-6routerg   tableallr`   z::/0ZUGz::Zexpirese)r4   r   r9   r'   r   rU   rP   insertjoinr   rp   )Ziproute_dataroutesentriesZdefault_route_entryr@   entryrZ   r   r*   Zcidrr[   Ziproute_data6_err6entries6r+   r+   r,   _netdev_route_info_iprouteK  s    



r   c           	   
   C   s,  i }g |d< g |d< |   }|D ]}|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 r|d |d |d |d< d|d< |d |d |d |d |d |d |d |d d}|d | q z$tjdddddgddgd\}}W n tjk
r2   Y nX |  }|D ]}|sN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@|d |d |d |d |d |d |d d}|d dkrq@|d drtd d!|d |d< |d | q@|S )"Nr   r      r   ZKernelDestinationZInternetZ	Internet6ZRouting   -      rJ   rL         )rt   ru   rv   r   rx   refuserw   netstatz-Ar   --route	--numericr`   ZProtoZActive)rt   ru   r   rx   r   r   rw   rw   lort   z/128z\/128$r
   )	r4   r9   rP   r'   r   rp   rQ   r5   sub)	Z
route_datar   r   r@   rZ   r   Zroute_data6r   r   r+   r+   r,   _netdev_route_info_netstat  s    	








 






  r   c                  C   sn   i } t dr.t  ddddg\}}t|} n<t dr`t j ddddgd	d
gd\}}t|} n
td | S )Nr   z-or}   rg   r   r   r   z--extendr   rJ   r`   z;Could not print routes: missing 'ip' and 'netstat' commands)r   ro   r   r   r:   r;   )r   Ziproute_outrr   Z	route_outr+   r+   r,   
route_info  s    



 

r   c                  C   s  g } d}zt |d}W nD tk
rZ } z$| tdjt|ddd W 5 d }~X Y n&X |sddS dd	d
dddg}t|}t|	 D ]\}}|
dD ]2}|||d |d |d |
d||d f q|
dD ].}|||d |d ||
d||d f qt|
dt|
d dkr|||d ||||d f q| }	tt|	 td}
tdd|
}| ||	g d| d S )N.)rq   z Net device info failed ({error})error!P   
ZDeviceZUpZAddressZMaskZScopez
Hw-Addressr   r   r   r   r   r   r   r    r   rk   zNet device info+)rs   	Exceptionr'   r   centerformatr%   r	   sortedre   r#   add_rowrP   
get_stringmaxr4   extendr   )linesrq   Znetdevr   ZfieldsZtblr)   ri   r*   Znetdev_smax_lenheaderr+   r+   r,   netdev_pformat  s\    



 r   c               
   C   s  g } z
t  }W nT tk
rb } z4| tdjt|ddd ttd|  W 5 d }~X Y nZX |	dr
ddd	d
ddg}t
|}t|	dD ]:\}}t|}|||d |d |d |d |d g q| }tt| td}	tdd|	}
| |
|g |	drddd	ddg}t
|}t|	dD ]H\}}t|}|d dkr\q:|||d |d |d |d g q:| }tt| td}	tdd|	}
| |
|g d| d S )NzRoute info failed ({error})r   r   r   zRoute info failed: %sr   ZRouter   ZGatewayZGenmaskZ	InterfaceZFlagsrt   ru   rv   rw   r   r   zRoute IPv4 infor   r   r   zRoute IPv6 infor   )r   r   r'   r   r   r   r%   Zlogexcr:   r#   r	   r3   r   r   rP   r   r4   r   r   )r   r   r   Z	fields_v4Ztbl_v4nrZroute_idZroute_sr   r   Z	fields_v6Ztbl_v6r+   r+   r,   route_pformat?  sz    
  $
	r   	ci-info: c                 C   sz   g }t   }| r0|D ]}|d| |f  qn
|| t  }| rf|D ]}|d| |f  qLn
|| d|S )Nz%s%sr   )r   r4   r'   r   r   r   )rC   r   Znetdev_linesr@   Zroute_linesr+   r+   r,   
debug_info  s    



r   )r
   )r   )r!   r5   r   r   Z	ipaddressr   Z	cloudinitr   Zloggingr   r   Zcloudinit.net.network_stater   Zcloudinit.simpletabler	   Z	getLoggerr:   rR   r-   rD   r^   r_   rs   r   r   r   r   r   r   r+   r+   r+   r,   <module>   s(   6Q09
0XU4C