U
    Ӈg`                     @   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(eeeeef f 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)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   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getr   r   r   netmaskappend)Zipaddr_jsonZipaddr_datadevsdevr   r    Zdev_infoaddrr(   Zparsed_addrr'   r   r   r   _netdev_info_iproute_json3   s@    






r6   z22.1zqRequired by old iproute2 versions that don't support ip json output. Consider upgrading to a more recent version.)Zdeprecated_versionZextra_messagec                 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 )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+.*r4   @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warningr2   	groupdictpop	partitionr   )
ipaddr_outr3   Zdev_nameZnumlinemr   r?   r9   r5   _prefixr   r   r   _netdev_info_iproutei   s      
  
   rM   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+)>)r=   lenrB   endswithr   DEFAULT_NETDEV_INFOrA   stripr>   searchranger2   r   
startswithlstripr?   r@   )
ifconfig_datar3   rI   curdevtoksiZnetworkZnet_bitsaddr6resr   r   r   _netdev_info_ifconfig_netbsd   sN    
  $  rg   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   rN   rQ   rR   r   TrS   zflags=\d+<up,r#   r   r'   rT   zbcast:r)   r%   zmask:r(   r1   r   r   r*   r   rU   r$   r+   rV   r-   rW   rX   )r=   rY   rB   rZ   r   r[   rA   r\   r>   r]   r^   r2   r`   r_   r?   r@   )ra   r3   rI   rb   rc   rd   re   rf   r   r   r   _netdev_info_ifconfig   s\    
    $  rh   )returnc                    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 )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'},
        ]
    },
    }

    Zifconfigz-ar   rS   Zrcsr'   z--jsonr5   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)
isinstancer   itemstuplelistr<   	TypeError)datanew_valZ
empty_valsZmyiterkeyvalfillZrecurse_typesr   r   rw   g  s    




znetdev_info.<locals>.fill)rs   )r   rk   )r
   Z	is_NetBSDr	   rg   whichr6   ProcessExecutionErrorrM   rh   rC   rD   r   ro   rp   )emptyr3   Z	ifcfg_out_errrH   r   rv   r   netdev_info%  s.    '




r|   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   default0.0.0.0r}   r   r+   r:   Hr~   ZviarS   Gr4   r   r   r   r'   z	--onelinez-6routerp   tableallrj   z::/0ZUG::Zexpirese)r=   r   rB   r2   r   r^   rY   insertjoinr	   ry   )Ziproute_dataroutesentriesZdefault_route_entryrI   entryrc   r   r5   Zcidrrd   Ziproute_data6_err6entries6r   r   r   _netdev_route_info_iproute{  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   -      rS   rU         )r}   r~   r   r   r   refuser   netstatz-Ar*   --route	--numericrj   ZProtoZActive)r}   r~   r   r   r   r   r   r   lor}   z/128z\/128$r   )	r=   rB   rY   r2   r	   ry   rZ   r>   sub)	Z
route_datar   r   rI   rc   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   rp   r   r   r   z--extendr   rS   rj   z;Could not print routes: missing 'ip' and 'netstat' commands)r	   rx   r   r   rC   rD   )r   Ziproute_outr{   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.)rz   z Net device info failed ({error})error!P   
ZDeviceZUpZAddressZMaskZScopez
Hw-Addressr   r   r'   r(   r&   r   r   r-   r   rt   zNet device info+)r|   	Exceptionr2   r
   centerformatr   r   sortedrn   r0   add_rowrY   
get_stringmaxr=   extendr   )linesrz   Znetdevr   ZfieldsZtblr4   rr   r5   Znetdev_smax_lenheaderr   r   r   netdev_pformat;  s\    



 r   c                  C   sF  g } z
t  }W nT tk
rb } z4| tdjt|ddd ttd|  W 5 d }~X Y nX |	drHddd	d
ddg}t
|}t|	dD ]x\}}t|}z2|||d |	dd|d |d |d g W q tk
r } zttd|  W 5 d }~X Y qX q| }tt| td}	tdd|	}
| |
|g |	dr8ddd	ddg}t
|}t|	dD ]\}}t|}|d dkrqxz,|||d |	dd|d |d g W n4 tk
r } zttd|  W 5 d }~X Y nX qx| }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Genmaskr   ZFlagsr}   r~   r   r   r   r   zRoute info formatting error: %sr   zRoute IPv4 infor   r   r   r   zRoute IPv6 infor   )r   r   r2   r
   r   r   r   ZlogexcrC   r0   r   r<   r   KeyErrorr   rY   r   r=   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_pformato  s    
  $

$
	&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   r=   r2   r   r   r   )rL   r   Znetdev_linesrI   Zroute_linesr   r   r   
debug_info  s    



r   )r   )r   )%r.   Zloggingr>   r   r   Z	ipaddressr   typingr   r   r   Z	cloudinitr   r	   r
   Zcloudinit.net.network_stater   Zcloudinit.simpletabler   Z	getLoggerr   rC   r[   r   r6   Zdeprecate_callrM   rg   rh   r   r|   r   r   r   r   r   r   r   r   r   r   <module>   s:   
6
N0: VXU4I