
    th͑                        U d dl Z d dlZd dlZd dlmZmZmZmZ d dlm	Z	m
Z
mZ d dlmZmZmZmZmZmZmZmZmZmZ erd dlmZ  ej2                  e      ZdZdg diZg dZd	d
dddddddddddddddddddddddd dd!d"Zee ee ef   f   e!d#<   d$e"d%dfd&Z#d' Z$ G d( d)e%      Z&d* Z' G d+ d,      Z( G d- d.      Z)d/ Z*d6d0Z+d1 Z,d2 Z-	 	 d7d3e"d4e.d%e(fd5Z/y)8    N)TYPE_CHECKINGAnyDictOptional)	lifecyclesafeyamlutil)
find_interface_name_from_macget_interfaces_by_macipv4_mask_to_net_prefixipv6_mask_to_net_prefixis_ip_networkis_ipv4_addressis_ipv4_networkis_ipv6_addressis_ipv6_networknet_prefix_to_ipv4_maskRenderer   versionconfignetwork_state)	addressesdhcp4dhcp4-overridesdhcp6dhcp6-overridesgateway4gateway6
interfacesmatchmtunameserversrendererset-name	wakeonlan	accept-raoptionalz	ad-selectzarp-intervalzarp-ip-targetzarp-validatez
down-delayzfail-over-mac-policyz	lacp-ratezmii-monitor-intervalz	min-linksmodegratuitous-arpprimaryzprimary-reselect-policyzup-delayztransmit-hash-policy)zbond-ad-selectzbond-arp-intervalzbond-arp-ip-targetzbond-arp-validatezbond-downdelayzbond-fail-over-maczbond-lacp-ratezbond-miimonzbond-min-linksz	bond-modezbond-num-grat-arpzbond-primaryzbond-primary-reselectzbond-updelayzbond-xmit-hash-policyzageing-timepriorityzforward-delayz
hello-timezmax-agez	path-costzport-prioritystp)bridge_ageingbridge_bridgeprio	bridge_fdbridge_gcintbridge_hellobridge_maxagebridge_maxwaitbridge_pathcostbridge_portprio
bridge_stpbridge_waitport)bondbridgeNET_CONFIG_TO_V2diktreturnc                 F    d| v sd| v rt        j                  ddd       yy)z8Warn about deprecations of v2 properties for all devicesr    r!   z$The use of `gateway4` and `gateway6`z22.4zbFor more info check out: https://docs.cloud-init.io/en/latest/topics/network-config-format-v2.html)
deprecateddeprecated_versionextra_messageN)r   	deprecate)r>   s    =/usr/lib/python3/dist-packages/cloudinit/net/network_state.pywarn_deprecated_all_devicesrF   X   s0    TZ4/=%X	
 0    c                 L    t        |       }|D ]  }|j                  |        |S N)setdiscard)expectedactualmissingkeys       rE   	diff_keysrP   c   s+    (mG NrG   c                       e Zd Zy)InvalidCommandN)__name__
__module____qualname__ rG   rE   rR   rR   j   s    rG   rR   c                       fd}|S )Nc                 F     t        j                          fd       }|S )Nc                 `    rt        |      }|rt        d|d       | |g|i |S )NzCommand missing z of required keys )rP   rR   )selfcommandargskwargsmissing_keysfuncrequired_keyss        rE   	decoratorz7ensure_command_keys.<locals>.wrapper.<locals>.decoratorp   sE    (@('8  g7777rG   )	functoolswraps)r_   ra   r`   s   ` rE   wrapperz$ensure_command_keys.<locals>.wrappero   s&    			8 
	8 rG   rV   )r`   rd   s   ` rE   ensure_command_keysre   n   s     NrG   c                       e Zd ZefdedefdZedefd       Zed        Z	ed        Z
ed        Zed	        ZddZddZd Zd Zededd fd       Zy
)NetworkStater   r   c                     t        j                  |      | _        || _        |j	                  dd      | _        d | _        y )Nuse_ipv6F)copydeepcopy_network_state_versiongetri   _has_default_route)rZ   r   r   s      rE   __init__zNetworkState.__init__   s8     #mmM:%))*e<"&rG   r?   c                      | j                   d   S )Nr   )rl   rZ   s    rE   r   zNetworkState.config   s    ""8,,rG   c                     | j                   S rI   )rm   rr   s    rE   r   zNetworkState.version   s    }}rG   c                 J    	 | j                   d   d   S # t        $ r g cY S w xY w)Ndnsr%   rl   KeyErrorrr   s    rE   dns_nameserverszNetworkState.dns_nameservers   s1    	&&u-m<< 	I	    ""c                 J    	 | j                   d   d   S # t        $ r g cY S w xY w)Nru   searchrv   rr   s    rE   dns_searchdomainszNetworkState.dns_searchdomains   s1    	&&u-h77 	I	ry   c                 \    | j                   | j                         | _         | j                   S rI   )ro   _maybe_has_default_routerr   s    rE   has_default_routezNetworkState.has_default_route   s+    ""*&*&C&C&ED#&&&rG   Nc              #      K   | j                   j                  di       }|j                         D ]  }|| 
 ||      s|  y w)Nr"   )rl   rn   values)rZ   filter_funcifacesifaces       rE   iter_interfaceszNetworkState.iter_interfaces   sK     $$((r:]]_ 	 E"u%K	 s   ?A	A	c              #   v   K   | j                   j                  dg       D ]  }| ||      s| |  y wNroutesrl   rn   )rZ   r   routes      rE   iter_routeszNetworkState.iter_routes   s@     ((,,Xr: 	E&u%K	s   *99c                    | j                         D ]  }| j                  |      s y | j                         D ]E  }|j                  dg       D ].  }|j                  dg       D ]  }| j                  |      s   y 0 G y)NTsubnetsr   F)r   _is_default_router   rn   )rZ   r   r   subnets       rE   r~   z%NetworkState._maybe_has_default_route   s    %%' 	E%%e,	 ))+ 	$E))Ir2 $#ZZ"5 $E--e4#$$	$
 rG   c                 X    d}|j                  d      dk(  xr |j                  d      |v S )N)z::z0.0.0.0prefixr   network)rn   )rZ   r   default_netss      rE   r   zNetworkState._is_default_route   s0    (IIh1$M9)=)M	
rG   c                 4    i }d|v r|d   |d<    | d|ifi |S )zInstantiates a `NetworkState` without interpreting its data.

        That means only `config` and `version` are copied.

        :param network_state: Network state data.
        :return: Instance of `NetworkState`.
        r   r   rV   )clsr   r]   s      rE   to_passthroughzNetworkState.to_passthrough   s5     % -i 8F9Hm,777rG   rI   )rS   rT   rU   NETWORK_STATE_VERSIONdictintrp   propertyr   r   rx   r|   r   r   r   r~   r   classmethodr   rV   rG   rE   rg   rg      s    2G'!',/' - - -       ' '
 	
 84 8N 8 8rG   rg   c                      e Zd Zi g g g ddddZeddf	 d)dZedefd       Zed        Z	e	j                  d	        Z	d
 Zd Zd Zd Zd*dZd*dZd*dZ edg      d        Z edg      d        Z eg d      d        Z eg d      d        Z eddg      d        Z edg      d        Zd Z edg      d        Z edg      d        Z edg      d         Zd! Zd" Zd# Zd$ Z d% Z!d+d&Z"d,d'Z#d( Z$y)-NetworkStateInterpreterr%   r{   FN)r"   r   ru   ri   r   c                    || _         || _        t        j                  | j                        | _        || j
                  d<   d| _        i | _        || _        | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                   | j"                  | j$                  | j&                  | j(                  | j*                  d| _        y )Nr   F)r;   bondsr<   bridges	ethernets
infinibandloopback
nameserverphysicalr   vlanvlanswifis)rm   _configrj   rk   initial_network_staterl   _parsed_interface_dns_map	_rendererhandle_bondhandle_bondshandle_bridgehandle_bridgeshandle_ethernetshandle_infinibandhandle_loopbackhandle_nameserverhandle_physicalhandle_routehandle_vlanhandle_vlanshandle_wifiscommand_handlers)rZ   r   r   r&   s       rE   rp   z NetworkStateInterpreter.__init__   s      "mmD,F,FG(.H%(*!$$&&((**..00,,00,,&&$$&&&&!
rG   r?   c                    ddl m} | j                  dk(  rJt        | j                  |      r4t
        j                  d       t        j                  | j                        S t        | j                  | j                        S )Nr   r      zPassthrough netplan v2 configr   )cloudinit.net.netplanr   rm   
isinstancer   LOGdebugrg   r   r   rl   )rZ   NetplanRenderers     rE   r   z%NetworkStateInterpreter.network_state   sW    E==A*T^^_"MII56..t||<<D//GGrG   c                 8    | j                   j                  d      S Nri   r   rr   s    rE   ri   z NetworkStateInterpreter.use_ipv6  s    ""&&z22rG   c                 >    | j                   j                  d|i       y r   )rl   update)rZ   vals     rE   ri   z NetworkStateInterpreter.use_ipv6  s    ""J#45rG   c                 t    | j                   | j                  | j                  d}t        j                  |      S )Nr   )rm   r   rl   r   dumps)rZ   states     rE   dumpzNetworkStateInterpreter.dump  s1    }}ll!00

 ~~e$$rG   c                 (   d|vr t         j                  d       t        d      t        |d      }t	        ||      }|r%d|z  }t         j                  |       t        |      |D cg c]	  }|dvs| c}D ]  }t        | |||           y c c}w )Nr   z$Invalid state, missing version fieldzInvalid state, missing keys: %sr   )r   error
ValueErrorNETWORK_STATE_REQUIRED_KEYSrP   setattr)rZ   r   r`   r^   msgkrO   s          rE   loadzNetworkStateInterpreter.load  s    E!II<=CDD3E)4DE 63|DCIIcNS/!  -E!0DAE 	+CD#uSz*	+Es   (	B2Bc                 @    t        j                  | j                        S rI   )r   r   rl   rr   s    rE   dump_network_statez*NetworkStateInterpreter.dump_network_state(  s    ~~d1122rG   c                 4    | j                   | j                  dS )N)r   r   )rm   r   rr   s    rE   as_dictzNetworkStateInterpreter.as_dict+  s    ==DLLAArG   c                     | j                   dk(  r| j                  |       d| _        y | j                   dk(  r| j                  |       d| _        y y )Nr   skip_brokenTr   )rm   parse_config_v1r   parse_config_v2)rZ   r   s     rE   parse_configz$NetworkStateInterpreter.parse_config.  sO    ==A  [ 9DL]]a  [ 9DL  rG   c                 "   | j                   D ]   }|d   }	 | j                  |   }	  ||       " | j                  j                         D ]*  \  }}d }	 | j                  d   |   }|s|\  }	}
|	|
d|d	<   , y # t        $ r}t        d|z        |d }~ww xY w# t        $ rA |s t
        j                  d|d       t
        j                  | j                                Y w xY w# t        $ r }t        dj                  |            |d }~ww xY w)
Ntypez"No handler found for  command '%s'Skipping invalid command: %sTexc_infor"   zINameserver specified for interface {0}, but interface {0} does not exist!r   ru   )r   r   rw   RuntimeErrorrR   r   warningr   r   r   itemsrl   r   format)rZ   r   r[   command_typehandlere	interfaceru   r   r%   r{   s              rE   r   z'NetworkStateInterpreter.parse_config_v16  sD   || 	9G"6?L//=
	9 	9$ #55;;= 	NIsE++L9)D &)#V#.$ e	  "8<G " 9"KK6$    IId55789   88>y8I sA   A8BC%8	BBBAC"!C"%	D.D		Dc                    ddl m} t        | j                  |      ry | j                  j                         D ]4  \  }}|dv r	 | j                  |   }	  ||       | j                  |       6 y # t        $ r}t        d|z        |d }~ww xY w# t        $ rA |s t        j                  d|d       t        j                  | j                                Y w xY w)Nr   r   )r   r&   z!No handler found for command '%s'r   Tr   )r   r   r   r   r   r   r   rw   r   
_v2_commonrR   r   r   r   r   )rZ   r   r   r   r[   r   r   s          rE   r   z'NetworkStateInterpreter.parse_config_v2Y  s    Ednno6%)\\%7%7%9 	9!L'66//=

9 (	9
  "7,F " 9"KK6$    IId55789s+   A0B0	B9BBACCnamec                 $    | j                  |      S rI   r   rZ   r[   s     rE   r   z'NetworkStateInterpreter.handle_loopbacku  s    ##G,,rG   c                 ~   | j                   j                  di       }|j                  |d   i       }|j                  di       j                         D ]  \  }}|j                  ||i        t	        |j                  d            }| j
                  sJ|D ]E  }|j                  d      j                  d      st        |j                  d            s>d| _         n |j                  d	d
      }|t        j                  |      }|j                  dd
      }	|	t        j                  |	      }	|j                  dd
      }
|
t        j                  |
      }
|j                  |j                  d      |j                  d      |j                  d      |j                  d      dd|j                  d      d
d
|||	|
|j                  d      d       |d   r|d   j                         |d<   |j                  d|j                  d            }| j                   d   j                  ||i       | j                          y
)z
        command = {
            'type': 'physical',
            'mac_address': 'c0:d6:9f:2c:e8:80',
            'name': 'eth0',
            'subnets': [
                {'type': 'dhcp4'}
             ],
            'accept-ra': 'true'
        }
        r"   r   paramsr   r   6addressTr)   Nr(   r*   	config_idmac_addressinetmanualr$   keep_configuration)r   r   r   r   r   r+   r$   r   gatewayr   r)   r(   r*   r   )rl   rn   r   r   _normalize_subnetsri   endswithr   r	   is_truelowerr   )rZ   r[   r"   r   paramr   r   r   	accept_rar(   r*   	iface_keys               rE   r   z'NetworkStateInterpreter.handle_physicaly  s    ((,,\2>
wv3!++h399; 	'JE3LL%&	' %W[[%;< }}! ::f%..s3JJy)8 %)DM KKT2	 Y/IKKT2	 Y/I;;z40||H-H$[[5F+F+&{{=9 {{5)"&&$&-kk2F&G	
& #(#7#=#=#?E- KKW[[-@A	L)00)U1CD!rG   )r   vlan_id	vlan_linkc                    | j                   j                  di       }| j                  |       |j                  |j                  d      i       }|j                  d      |d<   |j                  d      |d<   |j                  |d   |i       y)z
        auto eth0.222
        iface eth0.222 inet static
                address 10.10.10.1
                netmask 255.255.255.0
                hwaddress ether BC:76:4E:06:96:B3
                vlan-raw-device eth0
        r"   r   r  zvlan-raw-devicer  N)rl   rn   r   r   )rZ   r[   r"   r   s       rE   r   z#NetworkStateInterpreter.handle_vlan  s     ((,,\2>
W%w{{62B7#*;;{#; ";;y1i5=%01rG   )r   bond_interfacesr   c                    | j                  |       | j                  j                  d      }|j                  |j                  d      i       }|j                  d      j                         D ]  \  }}|j	                  ||i        |j	                  ddi       | j                  d   j	                  |d   |i       |j                  d      D ]  }||vr|dd}| j                  |       | j                  j                  di       }|j                  |      }|j                  d      |d	<   |j                  d      j                         D ]  \  }}|j	                  ||i        | j                  d   j	                  ||i        y
)aU  
        #/etc/network/interfaces
        auto eth0
        iface eth0 inet manual
            bond-master bond0
            bond-mode 802.3ad

        auto eth1
        iface eth1 inet manual
            bond-master bond0
            bond-mode 802.3ad

        auto bond0
        iface bond0 inet static
             address 192.168.0.10
             gateway 192.168.0.1
             netmask 255.255.255.0
             bond-slaves none
             bond-mode 802.3ad
             bond-miimon 100
             bond-downdelay 200
             bond-updelay 200
             bond-lacp-rate 4
        r"   r   r   zbond-slavesnoner  r;   )r   r   zbond-masterN)r   rl   rn   r   r   )	rZ   r[   r"   r   r  r   ifnamecmdbond_ifs	            rE   r   z#NetworkStateInterpreter.handle_bond  sw   6 	W%((,,\:
w{{62B7!++h/557 	'JE3LL%&	'mV,-L)00%-1GH kk"34 	HFZ'""
 $$S),,00rBJ nnV,G%,[[%8GM"%kk(399; -
ss|,--44fg5FG	HrG   bridge_interfacesc                    | j                   j                  di       }|j                  d      D ]  }||v rd|i}| j                  |        | j                   j                  di       }| j                  |       |j                  |j                  d      i       }|d   |d<   |j                  di       j                         D ]  \  }}|j	                  ||i        |j                  d      }|Lt        |t              s<|dv rd	}n"|d
v rd}nt        dj                  |            |j	                  d|i       |j	                  |d   |i       y)a  
            auto br0
            iface br0 inet static
                    address 10.10.10.1
                    netmask 255.255.255.0
                    bridge_ports eth0 eth1
                    bridge_stp off
                    bridge_fd 0
                    bridge_maxwait 0

        bridge_params = [
            "bridge_ports",
            "bridge_ageing",
            "bridge_bridgeprio",
            "bridge_fd",
            "bridge_gcint",
            "bridge_hello",
            "bridge_hw",
            "bridge_maxage",
            "bridge_maxwait",
            "bridge_pathcost",
            "bridge_portprio",
            "bridge_stp",
            "bridge_waitport",
        ]
        r"   r  r   bridge_portsr   r9   N)on1r   T)off0r   Fz2Cannot convert bridge_stp value ({stp}) to boolean)r/   )	rl   rn   r   r   r   r   boolr   r   )	rZ   r[   r"   r
  r  r   r  r   r9   s	            rE   r   z%NetworkStateInterpreter.handle_bridge  sg   > ((,,\2>
kk"56 	&F# C   %	& ((,,\2>
W%w{{62B7 '(; <n!++h399; 	'JE3LL%&	' YY|,
!*Z*F^+!
."
 %v*v5  LL,
345=%01rG   c                 &    | j                  |       y rI   r   r   s     rE   r   z)NetworkStateInterpreter.handle_infinibandB  s    W%rG   c                     g }g }d|v r0|d   }t        |t              s|g}|D ]  }|j                  |        d|v r0|d   }t        |t              s|g}|D ]  }|j                  |        ||fS )Nr   r{   )r   listappend)rZ   r[   r%   r{   addrsaddrpathspaths           rE   
_parse_dnsz"NetworkStateInterpreter._parse_dnsF  s    I&EeT* )""4()wH%EeT* $d#$F""rG   r   c                     | j                   j                  d      }| j                  |      \  }}d|v r||f| j                  |d   <   y |d   j	                  |       |d   j	                  |       y )Nru   r   r%   r{   )rl   rn   r  r   extend)rZ   r[   ru   r%   r{   s        rE   r   z)NetworkStateInterpreter.handle_nameserverW  sw    !!%%e,"oog6V'!=D##GK$89
 %%k2M  (rG   c                 x    | j                   j                  d      }| j                  |      \  }}||d||   d<   y )Nr"   r   ru   )rl   rn   r  )rZ   r[   r   _ifacer%   r{   s         rE   _handle_individual_nameserverz5NetworkStateInterpreter._handle_individual_nameserverd  s>    $$((6"oog6V/:fMuerG   destinationc                 R    | j                   d   j                  t        |             y r   )rl   r  _normalize_router   s     rE   r   z$NetworkStateInterpreter.handle_routej  s!    H%,,-=g-FGrG   c                 *    | j                  |d       y)a  
        v2_command = {
          bond0: {
            'interfaces': ['interface0', 'interface1'],
            'parameters': {
               'mii-monitor-interval': 100,
               'mode': '802.3ad',
               'xmit_hash_policy': 'layer3+4'}},
          bond1: {
            'bond-slaves': ['interface2', 'interface7'],
            'parameters': {
                'mode': 1,
            }
          }
        }

        v1_command = {
            'type': 'bond'
            'name': 'bond0',
            'bond_interfaces': [interface0, interface1],
            'params': {
                'bond-mode': '802.3ad',
                'bond_miimon: 100,
                'bond_xmit_hash_policy': 'layer3+4',
            }
        }

        r;   cmd_typeN_handle_bond_bridger   s     rE   r   z$NetworkStateInterpreter.handle_bondso  s    : 	  6 :rG   c                 *    | j                  |d       y)a  
        v2_command = {
          br0: {
            'interfaces': ['interface0', 'interface1'],
            'forward-delay': 0,
            'stp': False,
            'maxwait': 0,
          }
        }

        v1_command = {
            'type': 'bridge'
            'name': 'br0',
            'bridge_interfaces': [interface0, interface1],
            'params': {
                'bridge_stp': 'off',
                'bridge_fd: 0,
                'bridge_maxwait': 0
            }
        }

        r<   r'  Nr)  r   s     rE   r   z&NetworkStateInterpreter.handle_bridges  s    . 	  8 <rG   c                    t               }|j                         D ])  \  }}|dd}|j                  di       }|j                  dd      }|s t        j	                  d|t        |             ||d<   |}|j                  d      }	|	r|	}n#|r!|r|j                         }
t        |
      }|r|}||d	<   |j                  d
d      }|rd
|i|d<   dD ]  }||v s||   ||<    t        |       | j                  |      }t        |      dkD  r|j                  d|i       t        j	                  d|       | j                  |       , y)a  
        ethernets:
          eno1:
            match:
              macaddress: 00:11:22:33:44:55
              driver: hv_netvsc
            wakeonlan: true
            dhcp4: true
            dhcp6: false
            addresses:
              - 192.168.14.2/24
              - 2001:1::1/64
            gateway4: 192.168.14.1
            gateway6: 2001:1::2
            nameservers:
              search: [foo.local, bar.local]
              addresses: [8.8.8.8, 8.8.4.4]
          lom:
            match:
              driver: ixgbe
            set-name: lom1
            dhcp6: true
            accept-ra: true
          switchports:
            match:
              name: enp2*
            mtu: 1280

        command = {
            'type': 'physical',
            'mac_address': 'c0:d6:9f:2c:e8:80',
            'name': 'eth0',
            'subnets': [
                {'type': 'dhcp4'}
             ]
        }
        r   )r   r   r#   
macaddressNzHNetworkState Version2: missing "macaddress" info in config entry: %s: %sr   r'   r   driverr   )r$   r#   r(   r)   r*   r   r   z!v2(ethernets) -> v1(physical):
%s)r   r   rn   r   r   strr   r
   rF   _v2_to_v1_ipcfglenr   r   )rZ   r[   ifaces_by_macethcfgphy_cmdr#   r   r   set_namelcase_mac_addressmacr.  rO   r   s                  rE   r   z(NetworkStateInterpreter.handle_ethernets  sf   Z ./ .	*HC "G GGGR(E))L$7K		.H	 &1GM" Dwwz*H$/$5$5$7!23DED"GFOYYx.F%-v$6!M ,#:#&s8GCL, (,**3/G7|a	734II:GD  )].	*rG   c                 ~   |j                         D ]  \  }}d||j                  d      |j                  d      |j                  d      d}d|v r|d   |d<   t        |       | j                  |      }t	        |      dkD  r|j                  d|i       t        j                  d	|       | j                  |        y
)aq  
        v2_vlans = {
            'eth0.123': {
                'id': 123,
                'link': 'eth0',
                'dhcp4': True,
            }
        }

        v1_command = {
            'type': 'vlan',
            'name': 'eth0.123',
            'vlan_link': 'eth0',
            'vlan_id': 123,
            'subnets': [{'type': 'dhcp4'}],
        }
        r   idlinkr-  )r   r   r  r  r   r$   r   r   zv2(vlans) -> v1(vlan):
%sN)	r   rn   rF   r0  r1  r   r   r   r   )rZ   r[   r   r4  vlan_cmdr   s         rE   r   z$NetworkStateInterpreter.handle_vlans  s    $ ! 	'ID#774= WWV_"ww|4H |"%e*',**3/G7|aG 45II2H=X&	'rG   c                 .    t         j                  d       y )NzOWifi configuration is only available to distros with netplan rendering support.)r   r   r   s     rE   r   z$NetworkStateInterpreter.handle_wifis)  s    *	
rG   c                 2   t         j                  d|       |j                         D ]n  \  }}d|v s|j                  d      j                  d      }|j                  d      j                  d      }ddi}|r||d<   |r||d<   | j	                  ||       p y )Nzv2_common: handling config:
%sr%   r{   r   r   r   r   )r   r   r   rn   r"  )rZ   r4  r   dev_cfgr{   ru   name_cmds          rE   r   z"NetworkStateInterpreter._v2_common/  s    		3S9!iik 
	DNE7' ]377Akk-044[A"L1)/HX&*-HY'228UC
	DrG   c                   
 t        d t        j                  |      j                         D              
|j                         D ]C  \  }}t        d |j                         D              }|j                  di       }|j	                  dd      }|r||d<   d|d||d	z   |j                  d
      dt        
fd|j                         D              i}d|v r|d   |d<   d|v r|d   |d<   t        |       | j                  |      }	t        |	      dkD  r|j                  d|	i       t        j                  d|||       |dk(  r| j                  |       |dk(  r| j                  |       +t        dj                  |             y)z(Common handler for bond and bridge typesc              3   *   K   | ]  \  }}||f  y wrI   rV   .0r   vs      rE   	<genexpr>z>NetworkStateInterpreter._handle_bond_bridge.<locals>.<genexpr>A  s      
q!QF
s   c              3   :   K   | ]  \  }}|t         vr||f  y wrI   )NETWORK_V2_KEY_FILTER)rD  rO   values      rE   rF  z>NetworkStateInterpreter._handle_bond_bridge.<locals>.<genexpr>F  s)       S%33 es   
parameterszgratuitious-arpNr,   r   r   _interfacesr"   r   c              3   2   K   | ]  \  }}|   |f  y wrI   rV   )rD  r   rE  v2key_to_v1s      rE   rF  z>NetworkStateInterpreter._handle_bond_bridge.<locals>.<genexpr>V  s     Ntq!A2Ns   r$   r-  r   r   r   zv2(%s) -> v1(%s):
%sr<   r;   z Unknown command type: {cmd_type}r'  )r   r=   rn   r   poprF   r0  r1  r   r   r   r   r   r   r   )rZ   r[   r(  	item_nameitem_cfgitem_paramsr   
grat_valuev1_cmdr   rM  s             @rE   r*  z+NetworkStateInterpreter._handle_bond_bridge=  s     
/33H=CCE
 
 $+==? (	Ix $,NN$4 K !__\26F$5t<J+5'( 	=((,,|*D$Nv||~NN	F   (ux'(0(>}%'1**84G7|ay'23II-x6J8#""6*V#  ( 6==!) >  I(	rG   c                 @   d }g }|j                  d      r.ddi} ||j                  di       |       |j                  |       |j                  d      r5ddi}d| _         ||j                  di       |       |j                  |       d}d}i }|j                  d	g       D ]  }d
|d}d|v r+d|v rQ|O|j                  d      }|j                  d|i       n*d|v r&|$|j                  d      }|j                  d|i       d|v ra|s_|j                  d      j                  d	      }	|	r|	|d<   |j                  d      j                  d      }
|
r|
|d<   |j                  |       |j                  |        g }|j                  dg       D ]m  }|j                  t	        |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      d             o t        |      rt        |      r||d   d<   |S )z7Common ipconfig extraction from v2 to v1 subnets array.c                     d| v r	| d   |d<   y y )Nzroute-metricmetricrV   )	overridesr   s     rE   _add_dhcp_overrideszDNetworkStateInterpreter._v2_to_v1_ipcfg.<locals>._add_dhcp_overridesr  s    *#,^#<x  +rG   r   r   r   r   Tr   Nr   static)r   r   :r!   r   r    r%   rx   r{   
dns_searchr   toviarV  r$   table)r#  r   rV  r$   r^  r   )rn   r  ri   r   r%  r1  )rZ   r4  rX  r   r   r    r!   r%   r   r   r{   r   r   s                rE   r0  z'NetworkStateInterpreter._v2_to_v1_ipcfgo  s"   	= 777g&F(92 >GNN6"777g&F DM(92 >GNN6"ww{B/ 	#G "F
 g~$)9"wwz2HMM9h"78$)9"wwz2HMM9h"78#KGGM266{C	5>K 12/33H=06K-k*NN6"1	#4 WWXr* 	EMM ',yy#(99U#3"'))H"5$yy/!&7!3
	 w<CK#)GAJx rG   )r&   zOptional[Renderer])T)r?   NrI   )%rS   rT   rU   r   r   rp   r   rg   r   ri   setterr   r   r   r   r   r   r   re   r   r   r   r   r   r   r  r   r"  r   r   r   r   r   r   r   r*  r0  rV   rG   rE   r   r      s   
 	 &)-	
 '	
: H| H H 3 3 __6 6%+ 3B !F98 &"- #- &"?" #?"B 9:2 ;2  >?2H @2Hh &"567>2 8>2@ &"& #&#" )%
) &
) )%N &N
 -)H *H;>=2]*~!'F
D0dBrG   r   c                 V   t        j                  |       } t        d | j                         D              }| j	                  d      dv r|j                  t        |d             | j	                  dg       D cg c]  }t        |       c}|d<   d }dD ]  } |||        |S c c}w )	Nc              3   0   K   | ]  \  }}|s	||f  y wrI   rV   rC  s      rE   rF  z$_normalize_subnet.<locals>.<genexpr>  s     @DAqa!Q@s   
	r   )rY  static6)r   
ip_addressaddress_keysr   c                 b    || v r+t        | |   t              s| |   j                         | |<   y y y rI   )r   r  split)snetr   s     rE   listifyz"_normalize_subnet.<locals>.listify  s3    4<
4:t <d))+DJ !=<rG   )r[  rx   )rj   rk   r   r   rn   r   _normalize_net_keysr%  )r   normal_subnetrri  r   s        rE   _normalize_subnetrm    s    ]]6"F@FLLN@@Mzz&22	
 &,ZZ"%= !M(, / "q!" s   9B&c                    | j                         D ci c]  \  }}|s|dk(  s|| }}}d}|D ]  }|j                  |      s|} n |s7ddj                  |      d| }t        j	                  |       t        |      t        |j                  |            }|dk(  rt        |j                  d            }	|	s"d}t        j	                  |       t        |      t        |	      rd	}n4t        |	      rd
}n&d|	 d}t        j	                  |       t        |      t        |      s%t        j	                  d|       t        d| d      t        |      }
t        |      }|j                  d      }d|v r[|j                  d      \  }}}|||<   |
rt        |      }nl|rt        |      }n^t        j	                  d|       t        d| d      d|v rt        |d         }n&|r|rt        |      }n|r|
rt        |      }n|
rdnd}d|v r1t        |d         t        |      k7  rt        j!                  d||       ||d<   |
r	d|v r|d= |S |rt#        |d         |d<   |S c c}}w )a  Normalize dictionary network keys returning prefix and address keys.

    @param network: A dict of network-related definition containing prefix,
        netmask and address_keys.
    @param address_keys: A tuple of keys to search for representing the address
        or cidr. The first address_key discovered will be used for
        normalization.

    @returns: A dict containing normalized prefix and matching addr_key.
    r   Nz No config network address keys [,z] found in defaultr   zGateway IP is emptyz	0.0.0.0/0z::/0zInvalid Gateway IP: ''z$Address %s is not a valid ip networkzAddress z is not a valid ip addressnetmask/r   @      z;Overwriting existing 'prefix' with '%s' in network info: %s)r   rn   joinr   r   r   r/  r   r   r   r   r   	partitionr   r   r   r   r   )r   re  r   rE  netaddr_keyrO   messager  gw_ipipv6ipv4rr  	addr_part_maybe_prefixr   s                    rE   rj  rj    s{    $MMO
;DAqqAF1a4
;C
;H 773<H HH\"
 			'!!swwx !DyCGGI&'+GIIgW%%5!DU#D-eWA6GIIgW%%		8$?8D6)CDEE4 D4 Dggi G
d{%)^^C%8"	1l!H,\:F,\:F II<dCxv-GHII	SS]#	T(1	T(133s8}-V<I	

 CM I J 
0X?IJ] <s
   I+I+c                 <   t        d | j                         D              }d|v r|d   |d<   |d= |j                  t        |d             |j	                  d      }|r	 t        |      |d<   |S |S # t        $ r }t        dj                  |            |d}~ww xY w)	a  normalize a route.
    return a dictionary with only:
       'type': 'route' (only present if it was present in input)
       'network': the network portion of the route as a string.
       'prefix': the network prefix for address as an integer.
       'metric': integer metric (only if present in input).
       'netmask': netmask (string) equivalent to prefix iff network is ipv4.
    c              3   4   K   | ]  \  }}|d vs||f  yw)) NNrV   rC  s      rE   rF  z#_normalize_route.<locals>.<genexpr>7  s$      1aAZ,?As   	r#  r   )r   r#  rd  rV  z(Route config metric {} is not an integerN)	r   r   r   rj  rn   r   r   	TypeErrorr   )r   normal_routerV  r   s       rE   r%  r%  -  s       ;;= L $".}"=Y''A	
 h'F	%([L"
 <	  	:AA&I	s    A2 2	B;BBc                 F    | sg } | D cg c]  }t        |       c}S c c}w rI   )rm  )r   ss     rE   r   r   O  s$    *12Qa 222s   
net_configr   c                     d}| j                  d      }| j                  d      }|dk(  r| }|r.|,t        |||      }|j                  |       |j                  }|st	        d|        |S )zfParses the config, returns NetworkState object

    :param net_config: curtin network config dict
    Nr   r   r   )r   r   r&   r   zpNo valid network_state object created from network config. Did you specify the correct version? Network config:
)rn   r   r   r   r   )r  r   r&   r   r   r   nsis          rE   parse_net_config_datar  U  s     EnnY'G^^H%F!| 6%%FX
 	[1!!El
 	
 LrG   )rV   )TN)0rj   rb   loggingtypingr   r   r   r   	cloudinitr   r   r	   cloudinit.netr
   r   r   r   r   r   r   r   r   r   cloudinit.net.rendererr   	getLoggerrS   r   r   r   rH  r=   r/  __annotations__r   rF   rP   	ExceptionrR   re   rg   r   rm  rj  r%  r   r  r  rV   rG   rE   <module>r     s`      5 5 / /   /g! -  * &+-+&4%-%-!!:"!7$ ''$$"&*%/ $sDcN*+ D
d 
t 
	Y 	$S8 S8l[ [|:YxD3  	rG   