o
    x[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 r t d|¡}|spt 	d||¡ q
| ¡ }| d¡}| d¡\}	}
}|s…d}|| d  
|	|d r”|d ndt|ƒ|d dœ¡ q
d|v rÌt d|¡}|s´t 	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�rƒt 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 }|s×qÐ| ¡ }|d dkrêd|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}|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œ|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   Ú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 }~n‹d }~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 }~nâd }~ww | 	d¡ržg 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rÂq³z| ||d | 	d	d¡|d |d g¡ W q³ tyò } zt td| ¡ W Y d }~q³d }~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