
    gˉ                         d dl m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
 d dlmZmZmZ d dlmZmZ  G d d	ej$                        Z G d
 d      Zy)    )defaultdictN)AF_INETAF_INET6)AbstractSet)NetplanRoute)SystemConfigStateNetplanConfigStateDEVICE_TYPES)is_valid_macaddressroute_table_lookupc                       e Zd Zd Zy)DiffJSONEncoderc                     t        |t              r|j                         S t        j                  j                  | |      S N)
isinstancer   to_dictjsonJSONEncoderdefault)selfobjs     0/usr/share/netplan/netplan_cli/cli/state_diff.pyr   zDiffJSONEncoder.default   s3    c<(;;=  ''c22    N)__name__
__module____qualname__r    r   r   r   r      s    3r   r   c                      e Zd ZdZdedefdZdefdZd+de	defdZ
defd	Zd
e	de	dedefdZdededdfdZdedefdZdedefdZde	de	fdZdededdfdZdededdfdZdededdfdZdededdfdZdede	ddfdZdededdfdZdedefdZdedee   fd Zd!ee   d"ee	   dedefd#Zdefd$Zdeddfd%Z defd&Z!d'edefd(Z"d)e	defd*Z#y),NetplanDiffStatez
    DiffState is mainly responsible for getting both system's and Netplan's configuration
    state, compare them and provide a data-structure containing the differences it found.
    system_statenetplan_statec                 .    || _         || _        i | _        y r   )r    r!   route_lookup_table_names)r   r    r!   s      r   __init__zNetplanDiffState.__init__,   s    (*(*%r   returnc                    di i}| j                         }| j                         }t        t        |j	                               t        |j	                               z         }|D ]
  }i |d   |<    |j                         D ]  \  }}|d   |   j                  |        |j                         D ]  \  }}|d   |   j                  |        | j                  j                  D ]!  }|j                  |d   |j                     d<   # |S )z
        Return the states of both the system and Netplan in a common representation
        that makes it easier to compare them.
        
interfacesdata_sources)_get_system_interfaces_get_netplan_interfacessetlistkeysitemsupdater    interface_listr(   name)r   
full_statesystem_interfacesnetplan_interfacesall_interfaces	interfaceconfigs          r   get_full_statezNetplanDiffState.get_full_state2   s0    "

 !779!99; T"3"8"8":;dCUCZCZC\>]]^' 	5I24J|$Y/	5 "3!8!8!: 	?Iv|$Y/66v>	? "4!9!9!; 	?Iv|$Y/66v>	? **99 	^IGPG]G]J|$Y^^4^D	^ r   r6   c                    | j                         }| j                  |j                  di             }|r|j                  |      x}r||i}ni }| j                         }| j	                  ||       |j                         D ]  \  }}|j                  di       j                  d      }|j                  di       j                  d      }| j                  |||      }| j                  ||       | j                  ||       | j                  ||       | j                  ||       | j                  ||       | j                  ||       |d   j                  |        t        t        |d   j                         d             |d<   |S )a  
        Compare the configuration of interfaces currently found in the system against Netplan configuration.
        A number of heuristics are used to eliminate configuration that is automatically set in the system,
        such as certain routes and IP addresses. That is necessary because this configuration will not be found
        in Netplan. For example, if Netplan is enabling DHCP on an interface and not defining any extra IP addresses,
        we don't count the IPs automatically assigned to the interface as a difference. We do though count the eventual
        absence of addresses that should be assigned by DHCP as a difference.
        r'   r    idindexc                 *    | d   j                  d      S )N   r;   )get)ifaces    r   <lambda>z+NetplanDiffState.get_diff.<locals>.<lambda>u   s    [`ab[c[g[gho[p r   key)r8   _get_comparable_interfacesr>   _create_new_report_analyze_missing_interfacesr.   _create_new_iface_analyze_ip_addresses_analyze_nameservers_analyze_search_domains_analyze_mac_addresses_analyze_routes_analyze_parent_linksr/   dictsorted)	r   r6   r2   r'   r7   report	netdef_idr;   r?   s	            r   get_diffzNetplanDiffState.get_diffO   sx    ((*
44Z^^LRT5UV
#	22v2'0

((*((;!+!1!1!3 	/Iv

>26::4@IJJ~r266w?E**9iGE&&vu5%%fe4((7''6  /&&vu5< ''.	/  $F6,+?+E+E+GMp$qr|r   c                     i i i dS )N)r'   missing_interfaces_systemmissing_interfaces_netplanr   )r   s    r   rD   z#NetplanDiffState._create_new_reportx   s    )+*,
 	
r   rP   r;   c                     ||||i i diS )N)r;   r1   r:   r    r!   r   )r   rP   r6   r;   s       r   rF   z"NetplanDiffState._create_new_iface   s#    ! "!#
 	
r   r7   r?   Nc                 $   t        |j                               d   }|j                  di       j                  dg       D ch c]  }| }}| j                  |      }|j                  di       j                  dd      }|j                  di       j                  dd      }|j                  di       j                  dg       }t	               }	|j                  di       j                  di       j                         D ]t  \  }
}t        j                  |
      }|j                  d	g       }h d
j                  |      s|	j                  |
       d|v r~|j                  rrt        |j                  t        j                        rd|vr|	j                  |
       t        |j                  t        j                        rd|vr|	j                  |
       t        |j                  t        j                        rddhj                  |      rd}t        |j                  t        j                        rd|v rd}|j                  di       j                  d      }d|v s^|du sd|	j                  |
       w |j                  |	      }|	j                  |      }|rd||   d   d<   |rd||   d   d<   |r+||   d   j!                  dt        t#        |            i       |r,||   d   j!                  dt        t#        |            i       y y c c}w )Nr   r!   	addressesdhcp4Fdhcp6
link_localr    flags>   radhcplinkdynamicr^   ipv4ipv6r]   r_   	accept_rar\   Tmissing_dhcp4_addressmissing_dhcp6_addressmissing_addresses)r,   r-   r>   _normalize_ip_addressesr+   r.   	ipaddressip_interfaceintersectionaddis_link_localr   ipIPv4AddressIPv6Address
differencer/   rN   )r   r7   r?   r1   rl   netplan_ipsrc   rd   rZ   
system_ipsaddr	addr_datar[   rb   present_only_in_netplanpresent_only_in_systems                   r   rG   z&NetplanDiffState._analyze_ip_addresses   s   EJJL!!$$*JJ$C$G$GUW$XYbrYY22;? &

?B ? C CGU S &

?B ? C CGU SZZ488rJ
U
%zz."=AA+rRXXZ "	%OD)''-BMM'2.E 5AA%Ht$
 2#3#3beeY%:%:;j@XNN4(beeY%:%:;j@XNN4( "%%!6!67I&33E:,1)"%%!6!67U?,1) 

?B7;;KHIu}e!3t$E"	%H #."8"8"D!+!6!6{!C CGE$K'(?@ CGE$K'(?@!$K(//#T&1G*H%I1  #$K'..#T&1H*I%J0  #s Zs   	Lr'   c                     i }|j                         D ]O  \  }}|j                  d      |j                  d      )|j                  di       j                  d      sK|||<   Q |S )a   In order to compare interfaces, they must exist in the system AND in Netplan.
            Here we filter out interfaces that don't have a system_state, a netplan_state
            or a netdef ID.

            There is a special case where the interface will have a system_state and a netdef_id
            but will be missing in Netplan. That will happen when the user removes the interface
            only from Netplan but doesn't run netplan apply.
        r    r!   r:   )r.   r>   )r   r'   filteredr6   r7   s        r   rC   z+NetplanDiffState._get_comparable_interfaces   ss     !+!1!1!3 	)Ivzz.)1VZZ5P5X::nb155d;"(HY	) r   rW   c                 l    t               }|D ]$  }| j                  |      }|j                  |       & |S )zm Apply some transformations to IP addresses so their representation
        will match the system's.
        )r+   _compress_ipv6_addressrj   )r   rW   new_ips_setrl   s       r   rf   z(NetplanDiffState._normalize_ip_addresses   s>     e 	 B,,R0BOOB	  r   addressc                     	 t        j                  |      }d|v r|j                  S t        |j                        S # t
        $ r |cY S w xY w)z
        Compress IPv6 addresses to match the system representation
        Example: 1:2:0:0::123/64 -> 1:2::123/64
                 1:2:0:0::123 -> 1:2::123
        If "address" is not an IPv6Address, return the original value
        /)rg   rh   with_prefixlenstrrl   
ValueError)r   r{   rr   s      r   ry   z'NetplanDiffState._compress_ipv6_address   sL    	))'2Dg~***tww< 	N	s   $< < A
	A
c                 v   t        |j                               d   }|j                  di       j                  di       }t        |j                  di       j                  dg             }t        |j                  di       j                  dg             }|D ch c]  }||   dk(  s| }}|D ch c]  }||   dk(  s| }	}|D ch c]  }||   d	k(  s| }
}|j                  di       j                  d
      du}d|j                  di       j                  dg       v }|s|	s|
rK|j                  di       j                  d      r||z
  }|r||	z
  }|D ch c]	  }||
v s| }}|r|r||z
  }n|s|j                  di       j                  d      r<|D ch c]1  }t	        t        j                  |      t
        j                        s|3 }}|j                  di       j                  d      r<|D ch c]1  }t	        t        j                  |      t
        j                        s|3 }}|j                  |      }|j                  |      }|r"||   d   j                  dt        |      i       |r#||   d   j                  dt        |      i       y y c c}w c c}w c c}w c c}w c c}w c c}w )Nr   r(   dnsr!   nameservers_addressesr    DHCPv4DHCPv6NDiscrb   Fra   rZ   rX   rY   missing_nameservers_addresses)r,   r-   r>   r+   r   rg   
ip_addressrm   rn   ro   r/   )r   r7   r?   r1   r(   netplan_nameserverssystem_nameserversnsdhcp4_nsdhcp6_nsndisc_nsaccept_ra_enabledlink_local_enabledlink_local_nsrt   ru   s                   r   rH   z%NetplanDiffState._analyze_nameservers   s   EJJL!!$zz."599%D
 "&**_b"A"E"EF]_a"bc NB!?!C!CD[]_!`a!-N2b1AX1MBNN!-N2b1AX1MBNN!-M2b1AW1LBMM #JJ;??LTYY#vzz/2'F'J'J<Y['\\x8zz/2.227;%7(%B" !%7(%B"*<OBhROMO!&7%7-%G" '::or266w?7I *n1;I<P<PQS<TV_VkVk1l +- *n& *n::or266w?7I *n1;I<P<PQS<TV_VkVk1l +- *n& *n #6"@"@AS"T!3!>!>?R!S!$K(///6L1M1  #$K'../6M1N0  #] ONM P*n*ns<   J'J1J"?J"	J'J'	J,%J,6J196J6c                    t        |j                               d   }t        |j                  di       j                  dg             }t        |j                  di       j                  dg             }|j                  di       j                  di       }|D ch c]  }||   dk(  s| }}|D ch c]  }||   dk(  s| }	}|s|	rQ|j                  di       j                  d	      r||z
  }|j                  di       j                  d
      du}
|
rT||	z
  }nN|sL|j                  di       j                  d	      s!|j                  di       j                  d      r
t               }|j	                  |      }|j	                  |      }|r"||   d   j                  dt        |      i       |r#||   d   j                  dt        |      i       y y c c}w c c}w )Nr   r!   nameservers_searchr    r(   searchr   r   rX   rb   FrY   missing_nameservers_search)r,   r-   r+   r>   ro   r/   )r   r7   r?   r1   netplan_search_domainssystem_search_domainsr(   sdhcp4_searchdhcp6_searchr   rt   ru   s                r   rI   z(NetplanDiffState._analyze_search_domains7  s   EJJL!!$!$VZZ%D%H%HI]_a%b!c #FJJ~r$B$F$FG[]_$` azz."599(BG#/Oa<?h3NOO#/Oa<?h3NOO<zz/2.227;(=(L% !'

?B ? C CK PX] ] (=(L% *::or266w?6::o_aCbCfCfgnCo,/E)"8"C"CDY"Z!6!A!ABX!Y!$K(//,d3I.J1  #$K'..,d3J.K0  #; POs   G'G1G?Gc                 X   t        |j                               d   }|j                  di       j                  d      }|j                  di       j                  d      }|rt        |      sy |r<|r9||k7  r3||   d   j	                  d|i       ||   d   j	                  d|i       y y y y )Nr   r    
macaddressr!   missing_macaddress)r,   r-   r>   r   r/   )r   r7   r?   r1   system_macaddressnetplan_macaddresss         r   rJ   z'NetplanDiffState._analyze_mac_addresses^  s    EJJL!!$"JJ~r:>>|L#ZZ<@@N &9:L&M!3 $66dN+22(*<4  dO,33(*;5 	 7 "4r   c                 .   t        |j                               d   }t        |j                  di       j                  dg             }t        |j                  di       j                  dg             }| j	                  |      }| j                  |j                  di             x}r|j                  |       |j                  di       j                  di       D cg c]  }| }}| j                  |||      }|j                  |      }	|j                  |      }
|
r3||   d   j                  dt        |
d       D cg c]  }| c}i       |	r4||   d   j                  dt        |	d	       D cg c]  }| c}i       y y c c}w c c}w c c}w )
Nr   r!   routesr    rW   missing_routesc                     | j                   S r   tors    r   r@   z2NetplanDiffState._analyze_routes.<locals>.<lambda>  s    cdcgcg r   rA   c                     | j                   S r   r   r   s    r   r@   z2NetplanDiffState._analyze_routes.<locals>.<lambda>  s    dedhdh r   )
r,   r-   r+   r>   _normalize_routes_normalize_gatewaysr/   _filter_system_routesro   rN   )r   r7   r?   r1   netplan_routessystem_routesnetplan_gatewaysrl   system_addressesrt   ru   routes               r   rK   z NetplanDiffState._analyze_routesq  s   EJJL!!$VZZ<@@2NOFJJ~r:>>xLM//?  $77

?TV8WXXX!!"23 *0NB)G)K)KKY[)\]2B]]22=BRTZ["0";";M"J!.!9!9.!I!$K(// f=SYg6h"iU5"i1  #$K'.. f=TZh6i"jU5"j0  # ^ #j
 #ks   	F 	F
5	F
rO   c                      j                   j                  D ch c]  }| }} j                  j                  D ch c]  }|j                  s|j                   }}|j                  |      }t        t         fd|            }g } j                  j                  D ],  }|j                  |vs|j                  |j                         . t        |      }t        |      }rt        fd|      }t        fd|      } j                  j                         }|D ]O  } j                   j                  j                  |      j                  }	dt        j                  |	d      i|d   |<   Q |D ]J  }|j                  |      j                  dd      |j                  |      j                  d      d|d	   |<   L y c c}w c c}w )
Nc                 h    j                   j                  j                  |       j                  dk7  S )Nwifis)r!   netdefsr>   type)ir   s    r   r@   z>NetplanDiffState._analyze_missing_interfaces.<locals>.<lambda>  s*    T-?-?-G-G-K-KA-N-S-SW^-^ r   c                     | k(  S r   r   r   r6   s    r   r@   z>NetplanDiffState._analyze_missing_interfaces.<locals>.<lambda>  s    AN r   c                     | k(  S r   r   r   s    r   r@   z>NetplanDiffState._analyze_missing_interfaces.<locals>.<lambda>  s    1	> r   r   otherrS   r;   )r   r;   rT   )r!   r   r    r0   rP   ro   r,   filterappendr1   rN   get_datar>   r   r
   )
r   rO   r6   r?   r4   system_interfaces_netdef_idsnetplan_onlysystem_onlyr    
iface_types
   ` `       r   rE   z,NetplanDiffState._analyze_missing_interfaces  s   151C1C1K1KLeLLEIEVEVEeEe'yEinixix'y$'y)445QR F#^`lmn&&55 	/E&88""5::.	/ l+[)!":LIL !9;GK((113! 	E++3377>CCJ((W=:F./6	 ! 	E$((/33FGD%))%044W=;F/07	9 M'ys   	GG	G	c                 b   t        |j                               d   }|j                  di       j                  d      |j                  di       j                  d      g}|j                  di       j                  d      |j                  di       j                  d      g}|j                  di       j                  d      |j                  di       j                  d      g}|j                  di       j                  dg       |j                  di       j                  dg       g}|ddgk7  r1|d   |d	   k7  r&|d   r|d   ||   d   d
<   |d	   r|d	   ||   d   d
<   |ddgk7  r1|d   |d	   k7  r&|d   r|d   ||   d   d<   |d	   r|d	   ||   d   d<   |ddgk7  r1|d   |d	   k7  r&|d   r|d   ||   d   d<   |d	   r|d	   ||   d   d<   |g g gk7  rZt        |d         }t        |d	         }	||	k7  r8|	|z
  x}
rt        |
      ||   d   d<   ||	z
  x}rt        |      ||   d   d<   yyyy)z
        Analyse if interfaces such as bonds, bridges and VRFs are correctly attached to their
        members and vice versa.
        r   r    bondr!   bridgevrfr'   Nr=   missing_bond_linkmissing_bridge_linkmissing_vrf_linkmissing_interfaces)r,   r-   r>   r+   )r   r7   r?   r1   r   r   r   r'   systemnetplanmissing_systemmissing_netplans               r   rL   z&NetplanDiffState._analyze_parent_links  s   
 EJJL!!$

>2.226:FJJXZ<[<_<_`f<gh**^R044X>

?\^@_@c@cdl@mnzz."-11%8&**_VX:Y:]:]^c:dejj488rJFJJWfhjLkLoLop|  A  MB  C
D$<DGtAw$6AwDHGdO,-@AAwCG7dN+,?@dD\!fQi6!9&<ayFLQidO,-BCayEKAYdN+,AB4,3q6SV#31vCFq6dO,-?@1vBEa&dN+,>?"b!A'F*Q-(G %,v%55>5HL^H\E$K/0DE&,w&66?6IMoI^E$K01EF 7	 !	 "r   r   c                    t               }|D ]  }|j                  t        j                  k(  r| j	                  d      |_        | j                  |j                        |_        | j                  |j                        |_        | j                  |j                        |_        |j                  dk7  r5|j                  j                  d      }|d   dk(  s|d   dk(  r
|d   |_        |j                  |        |S )zo Apply some transformations to Netplan routes so their representation
        will match the system's.
        mainr   r}   r=   32128r   )r+   tabler   _TABLE_UNSPEC_$_default_route_tables_name_to_numberry   r   	from_addrviasplitrj   )r   r   new_routes_setr   	ip_prefixs        r   r   z"NetplanDiffState._normalize_routes  s      	&E{{l999"GGO 22588<EH"99%//JEO33EII>EI xx9$!HHNN3/	Q<4'9Q<5+@(|EHu%#	&& r   c                 2   t               }| j                  j                         }|j                  d      }|j	                         D cg c]  }|j                  d      |k(  r| }}|D cg c]  }|j                  dg       D ]  }|  }}}|j                  d      x}	r|D cg c]N  }|j                  d      dk(  r8|j                  d      t
        j                  k(  r|j                  d      dk(  r|P }
}t        d|	t
        j                  d	      }t        |
      d
k(  rI|
d   j                  d      x}r||_	        |
d   j                  d      x}r| j                  |      |_        |j                  |       |j                  d      x}r|D cg c]N  }|j                  d      dk(  r8|j                  d      t        j                  k(  r|j                  d      dk(  r|P }
}| j                  |      }t        d|t        j                  d	      }t        |
      d
k(  rI|
d   j                  d      x}r||_	        |
d   j                  d      x}r| j                  |      |_        |j                  |       |S c c}w c c}}w c c}w c c}w )a   Convert the gateway4 and gateway6 properties to NetplanRoutes.
        The only information stored by these properties is the destination IP for
        the default route. Networkd and Network Manager will set a default metric
        for it when the route is installed. As we have no control over it, there
        will always be a diff. The same is true for the route table number.
        To avoid the noise in the diff report when these properties are used,
        we use the following heuristic: if there is one and only one static default
        route in the system and gateway4 and/or gateway6 are used, we set the same
        metric and table as found in the system.
        r:   r   gateway4r   r   familyprotocolstatic)r   r   r   r   r=   r   metricr   gateway6)r+   r    r   r>   valuesr   valuer   lenr   r   r   rj   r   ry   )r   r7   
routes_setr3   r6   r?   ifacesr   r   r   default_routesr   r   r   s                 r   r   z$NetplanDiffState._normalize_gateways  s    U
 --668JJt$	%6%=%=%? 3EYYt_	1  3 3%+QE8R9PQ%Q%QQzz*--8-17 E!&4I!="'))H"5"F"'))J"78"C $ EN E
 !I8GMM\deE>"a'+A.228<<6<#)EL*1-11'::5:"&"K"KE"REKNN5!zz*--8-17 E!&4I!="'))H"5"G"'))J"78"C $ EN E 228<H I8HNN]efE>"a'+A.228<<6<#)EL*1-11'::5:"&"K"KE"REKNN5!O3QE Es   J, J	&AJAJr   r   c                 z   |D cg c]*  }t        t        j                  |      j                        , }}t	        t        d |            }|D cg c]*  }t        t        j                  |      j                        , }}|j                  di       j                  dg       }t               }|D ]  }	|	j                  dk(  r9|	j                  dk7  r*t        j                  |	j                        j                  sL|	j                  dk(  r\|j                  di       j                  d      }
|	j                  dk(  r|
d	ur|	j                  dk7  rpt        j                  |	j                        }|j                  rE|	j                  t        j                  k(  rd
|v r|	j                  t         j                  k(  rd|v r|	j                  dk(  rH|	j"                  dk(  r9|	j                  |v s)t        j                  |	j                        j$                  rg|	j                  t        j                  k(  r |	j"                  dk(  r|	j                  dk(  r|	j                  t        j                  k(  r-|	j                  dk7  r|	j                  |v s|	j                  |v r|j'                  |	        |S c c}w c c}w )a  
        Some routes found in the system are installed automatically/dynamically without
        being configured in Netplan.
        Here we implement some heuristics to remove these routes from the list we want
        to compare. We do that because these type of routes will probably never be found in the
        Netplan configuration so there is no point in comparing them against Netplan.
        c                     | dk7  S )Nz	fe80::/64r   )ns    r   r@   z8NetplanDiffState._filter_system_routes.<locals>.<lambda>4  s    qK/? r   r!   rZ   r^   r   r]   rb   r\   Fra   r`   hostlocal	multicastzff00::/8)r   rg   rh   networkr,   r   rl   r>   r+   scoper   rk   r   r   r   r   r   r   is_loopbackrj   )r   r   r   r7   rl   local_networksrW   rZ   r   r   rb   route_tos               r   r   z&NetplanDiffState._filter_system_routes)  s;    M]]b#i44R8@@A]]f%?PQBRSBS//3667S	SZZ488rJ
" &	E{{f$Y)>yG]G]^c^f^fGgGuGu ~~' 

?B7;;KHI~~%)5*@ xx9$$11%((;))||x~~5&J:N ||w}}4:9M  v%%***?XX*i.D.DUXX.N.Z.Z ||x~~-%**2KPUPXPX\fPf .5>>T3I^3uxx97LJJuM&	N [ ^ Ts   /J3/J8c                    | j                   j                         }i }| j                  j                  j	                         D ]q  \  }}i }dd|ii||<   ||   d   }t        j                  |j                  d      |d<   |j                  |d<   |j                  |d<   |j                  |d<   |j                  |j                  |d<   |j                  D cg c]  }| }}|rWi |d	<   |D ]M  }i }	|j                  r|j                  |	d
<   |j                  r|j                  |	d<   d|	i|d	   t        |      <   O t!        |j"                        x}
r|
|d<   t!        |j$                        x}r||d<   t!        |j&                        x}r||d<   |j(                  x}r||d<   |j*                  x}r||d<   |j,                  x}r||d<   |j.                  j                  d      x}r|j0                  |d<   |j.                  j                  d      x}r|j0                  |d<   |j.                  j                  d      x}r|j0                  |d<   ||vrUd}|j	                         D ])  \  }}|j                  d      x}s||k(  s d}||   ||<   + |rN|j3                  |       a|j3                  |       t | j5                  |       |S c c}w )Nr!   r:   r   r   rX   rY   rZ   rb   rW   labellifetimer[   r   r   r   r   r   r   r   r   r   FT)r    r   r!   r   r.   r
   r>   r   rX   rY   rZ   rb   rW   r   r   r   r,   nameserver_addressesnameserver_searchr   	_gateway4	_gateway6r   linksr:   r/   _netplan_state_find_parents)r   r3   r'   r6   r7   r?   	iface_refrr   rW   r[   nameserversr   r   r   r   macr   r   r   
found_somerB   r   rP   s                          r   r*   z(NetplanDiffState._get_netplan_interfacesa  s    --668
!%!3!3!;!;!A!A!C J	)IvE /$	1BCE)i(9I , 0 0g FIf!'Ig!'Ig&,&7&7Il#+)/)9)9	+&*0*:*:;$;I;)+	+&% IDEzz)-g}},0MMj)9@%8HIk*3t95I #6#>#>??{?5@	12f6677v728	./fmm,,v,&,	(#!+++x+(0	*%!+++x+(0	*%'''s'*-	,'))(33v3&,ii	(#||''//t/$(GG	&!ll&&u--s-#&66	%  11 #
"3"9"9"; ?JC$)IIdO3y3$	1)-J.3I.>JsO	? "%%e,!!%(UJ	)X 	((4{ <s   	K	c                    t        t              }|j                         D ]  \  }}|d   j                  d      x}r||   j	                  |       |d   j                  d      x}r||   j	                  |       |d   j                  d      x}sq||   j	                  |        |j                         D ]  \  }}t        |      ||   d   d<    y)z* Associates interfaces with their parents r!   r   r   r   r'   N)r   r+   r.   r>   rj   r,   )r   r'   parentsr6   r7   r^   memberss          r   r   z,NetplanDiffState._netplan_state_find_parents  s    c"!+!1!1!3 	-Ivo.228<<t<!!),o.226::t:!!),o.22599t9!!),	- #*--/ 	QIwCG=Jy!/2<@	Qr   c                    i }| j                   j                         j                         D ]  \  }}|dk(  r|j                  d      }dd|ii||<   |j                  d      x}r|||   d   d<   ||   d   }|j                  d      x}r||d<   i }|j                  dg       D ]k  }	t	        |	j                               d   }
|	j                  |
      j                  d      }|
 d	| }d
|	j                  |
      j                  d
g       i||<   m |r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r"|D cg c]  }| j                  |       c}|d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}s||d<    |S c c}w )Nznetplan-global-stater   r    r:   r;   rW   r   prefixr}   r[   dns_addressesr   
dns_searchr   r   r   r'   r   r   r   )r    r   r.   r>   r,   r-   _system_route_to_netplan)r   r'   r6   r7   device_typerP   r   r;   rW   rr   rl   r  	full_addrr   r   r   r   r   uplink_interfacesr   r   r   s                         r   r)   z'NetplanDiffState._get_system_interfaces  sa   
!%!2!2!;!;!=!C!C!E /	'Iv22 **V,K%3fk5J$KJy!"JJt,,y,>G
9%n5d;"9-n=I

7++u+%*	'"I

;3 P$))+&q)"))(3!d!F8,	(/"1A1A'21N'O	)$P )2	+&$jj99{95@	12L11v128	./H--v-Y_&`PUt'D'DU'K&`	(#jj..s.*-	,'$*JJ|$<< <*;	,'zz&))t)$(	&!H--v-&,	(#jj''s'#&	% _/	'b # 'as    G=system_routec                    i }|j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}r||d<   |j                  d      x}	r|	|d<   |j                  d	      x}
r|
|d	<   |j                  d
      x}r| j                  |      |d
<   t        di |S )Nr   r   r   fromr   r   r   r   r   r   r   )r>   r   r   )r   r
  r   r   r   r   r   r   r   
route_typer   r   s               r   r  z)NetplanDiffState._system_route_to_netplan  s9   !%%h//6/$E(O!!$''2'E$K""5))3)E%L$((0090!*E+!%%h//6/$E(O $$W--5-"E'N%))&11:1&E&M#''
3383 (E* $$W--5-!FFuME'N$e$$r   r1   c                     |j                         rt        |      S | j                  st               | _        | j                  j	                  |d      S )Nr   )isdigitintr#   r   r>   )r   r1   s     r   r   z5NetplanDiffState._default_route_tables_name_to_number  sB    <<>t9,,,>,@D),,00q99r   ) )$r   r   r   __doc__r   r	   r$   rM   r8   r   rQ   rD   r  rF   rG   rC   r+   rf   ry   rH   rI   rJ   rK   rE   rL   r   r   r   r   r,   r   r*   r   r)   r  r   r   r   r   r   r   &   s   
+%6 +GY + :'# 't 'R
D 
	
3 	
3 	
s 	
t 	
>D > >$ >@T d ,	 	 	c c ;4 ; ; ;z%d %4 %D %NT $ 4 &d 4 D 6!$ !3 !4 !F&_D &_ &_$ &_P  46$ 6;|3L 6p6;|3L 6`deh`i 6sw 6| 6pP PdQd Qt Q4 4l%T %l %0: : :r   r   )collectionsr   rg   r   socketr   r   typingr   netplan.netdefr   netplan_cli.cli.stater   r	   r
   netplan_cli.cli.utilsr   r   r   r   r   r   r   r   <module>r     s@   $ $   $  ' U U I3d&& 3p: p:r   