HEX
Server: Apache
System: Linux scp1.abinfocom.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: confeduphaar (1010)
PHP: 8.1.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //lib/python3/dist-packages/cloudinit/net/__pycache__/network_state.cpython-38.pyc
U

Ӈgb��@s�UddlZddlZddlZddlmZmZmZmZddlm	Z	m
Z
mZddlm
Z
mZmZmZmZmZmZmZmZer�ddlmZe�e�ZdZdddd	giZd
ddd
ddddddddddddgZddddddd d!d"d#d$d%d&d'd(d)�d*d+d,dd-d.dd/d0d1dd2�d3�Zeeeeeffe d4<e!dd5�d6d7�Z"d8d9�Z#Gd:d;�d;e$�Z%d<d=�Z&Gd>d?�d?�Z'Gd@dA�dA�Z(dBdC�Z)dOdEdF�Z*dGdH�Z+dIdJ�Z,dPe!e-e'dL�dMdN�Z.dS)Q�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_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-delayzfail-over-mac-policyz	lacp-ratezmii-monitor-intervalz	min-links�mode�gratuitous-arpZprimaryzprimary-reselect-policyzup-delayztransmit-hash-policy)zbond-ad-selectzbond-arp-intervalzbond-arp-ip-targetzbond-arp-validatezbond-downdelayzbond-fail-over-maczbond-lacp-ratezbond-miimonzbond-min-linksz	bond-modezbond-num-grat-arpzbond-primaryzbond-primary-reselectzbond-updelayzbond-xmit-hash-policyzageing-timeZpriorityz
forward-delayz
hello-timezmax-agez	path-costz
port-priority�stp)Z
bridge_ageingZbridge_bridgeprioZ	bridge_fdZbridge_gcintZbridge_helloZ
bridge_maxageZbridge_maxwaitZbridge_pathcostZbridge_portprio�
bridge_stpZbridge_waitport)�bond�bridge�NET_CONFIG_TO_V2)�dikt�returncCs$d|ksd|kr tjdddd�dS)z8Warn about deprecations of v2 properties for all devicesrrz$The use of `gateway4` and `gateway6`z22.4zbFor more info check out: https://docs.cloud-init.io/en/latest/topics/network-config-format-v2.html)Z
deprecatedZdeprecated_versionZ
extra_messageN)rZ	deprecate)r/�r1�=/usr/lib/python3/dist-packages/cloudinit/net/network_state.py�warn_deprecated_all_devicesWs�r3cCs t|�}|D]}|�|�q|S�N)�set�discard)ZexpectedZactualZmissing�keyr1r1r2�	diff_keysbsr8c@seZdZdS)�InvalidCommandN)�__name__�
__module__�__qualname__r1r1r1r2r9isr9cs�fdd�}|S)Ncst�����fdd��}|S)Ncs4�r"t�|�}|r"td|�f���||f|�|�S)Nz&Command missing %s of required keys %s)r8r9)�self�command�args�kwargs�missing_keys)�func�
required_keysr1r2�	decoratoros
��z7ensure_command_keys.<locals>.wrapper.<locals>.decorator)�	functools�wraps)rBrD�rC)rBr2�wrapperns
z$ensure_command_keys.<locals>.wrapperr1)rCrHr1rGr2�ensure_command_keysmsrIc@s�eZdZefeed�dd�Zeed�dd��Zedd��Z	ed	d
��Z
edd��Zed
d��Zddd�Z
ddd�Zdd�Zdd�Zeedd�dd��ZdS)�NetworkState)rrcCs*t�|�|_||_|�dd�|_d|_dS)N�use_ipv6F)�copy�deepcopy�_network_state�_version�getrK�_has_default_route)r=rrr1r1r2�__init__�szNetworkState.__init__�r0cCs
|jdS)Nr)rN�r=r1r1r2r�szNetworkState.configcCs|jSr4)rOrTr1r1r2r�szNetworkState.versioncCs.z|jddWStk
r(gYSXdS)N�dnsr"�rN�KeyErrorrTr1r1r2�dns_nameservers�szNetworkState.dns_nameserverscCs.z|jddWStk
r(gYSXdS)NrU�searchrVrTr1r1r2�dns_searchdomains�szNetworkState.dns_searchdomainscCs|jdkr|��|_|jSr4)rQ�_maybe_has_default_routerTr1r1r2�has_default_route�s

zNetworkState.has_default_routeNccs>|j�di�}|��D]"}|dkr*|Vq||�r|VqdS)Nr)rNrP�values)r=�filter_funcZifaces�ifacer1r1r2�iter_interfaces�szNetworkState.iter_interfacesccs6|j�dg�D]"}|dk	r*||�r0|Vq|VqdS�N�routes�rNrP)r=r^�router1r1r2�iter_routes�s
zNetworkState.iter_routescCsh|��D]}|�|�rdSq|��D]<}|�dg�D]*}|�dg�D]}|�|�rFdSqFq6q&dS)NT�subnetsrbF)re�_is_default_router`rP)r=rdr_�subnetr1r1r2r[�s

z%NetworkState._maybe_has_default_routecCs d}|�d�dko|�d�|kS)N)z::z0.0.0.0�prefixr�network)rP)r=rdZdefault_netsr1r1r2rg�s�zNetworkState._is_default_route)rr0cCs(i}d|kr|d|d<|d|if|�S)z�Instantiates a `NetworkState` without interpreting its data.

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

        :param network_state: Network state data.
        :return: Instance of `NetworkState`.
        rrr1)�clsrr@r1r1r2�to_passthrough�s	zNetworkState.to_passthrough)N)N)r:r;r<�NETWORK_STATE_VERSION�dict�intrR�propertyrrrXrZr\r`rer[rg�classmethodrlr1r1r1r2rJs*��




	
rJc@s�eZdZigggd�ddd�Zeddfdd�dd�Zeed	�d
d��Zedd
��Z	e	j
dd
��Z	dd�Zdd�Zdd�Z
dd�ZdJdd�ZdKdd�ZdLdd�Zedg�dd ��Zedg�d!d"��Zedd#d$g�d%d&��Zedd'd(g�d)d*��Zedd+g�d,d-��Zedg�d.d/��Zd0d1�Zed2g�d3d4��Zed2g�d5d6��Zed7g�d8d9��Zd:d;�Zd<d=�Zd>d?�Zd@dA�Z dBdC�Z!dd	�dDdE�Z"dMdFdG�Z#dHdI�Z$dS)N�NetworkStateInterpreter�r"rYFN)rrbrUrKrzOptional[Renderer])r#cCsv||_||_t�|j�|_||jd<d|_i|_||_|j	|j
|j|j|j
|j|j|j|j|j|j|j|jd�
|_dS)NrF)
r,Zbondsr-ZbridgesZ	ethernetsZ
infinibandZloopback�
nameserver�physicalrd�vlanZvlansZwifis)rO�_configrLrM�initial_network_staterN�_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)r=rrr#r1r1r2rR�s*
�z NetworkStateInterpreter.__init__rScCsHddlm}|jdkr8t|j|�r8t�d�t�|j	�St|j
|jd�S)Nrr�zPassthrough netplan v2 config�r)�cloudinit.net.netplanrrO�
isinstancer{�LOG�debugrJrlrwrN)r=�NetplanRendererr1r1r2r�s

z%NetworkStateInterpreter.network_statecCs|j�d�S�NrKrcrTr1r1r2rKsz NetworkStateInterpreter.use_ipv6cCs|j�d|i�dSr�)rN�update)r=�valr1r1r2rKscCs|j|j|jd�}t�|�S)N)rrr)rOrwrNr�dumps)r=�stater1r1r2�dumps
�zNetworkStateInterpreter.dumpcCsvd|krt�d�td��t|d}t||�}|rNd|}t�|�t|��dd�|D�D]}t||||�q\dS)Nrz$Invalid state, missing version fieldzInvalid state, missing keys: %scSsg|]}|dkr|�qS)r�r1)�.0�kr1r1r2�
<listcomp>$sz0NetworkStateInterpreter.load.<locals>.<listcomp>)r��error�
ValueError�NETWORK_STATE_REQUIRED_KEYSr8�setattr)r=r�rCrA�msgr7r1r1r2�loads


zNetworkStateInterpreter.loadcCst�|j�Sr4)rr�rNrTr1r1r2�dump_network_state'sz*NetworkStateInterpreter.dump_network_statecCs|j|jd�S)N)rr)rOrwrTr1r1r2�as_dict*szNetworkStateInterpreter.as_dictTcCs>|jdkr|j|d�d|_n|jdkr:|j|d�d|_dS)Nr��skip_brokenTr�)rO�parse_config_v1ry�parse_config_v2)r=r�r1r1r2�parse_config-s

z$NetworkStateInterpreter.parse_configcCs|jD]�}|d}z|j|}Wn0tk
rP}ztd|�|�W5d}~XYnXz||�Wqtk
r�|sv�ntjd|dd�t�|���YqXq|j	�
�D]l\}}d}z|jd|}Wn2tk
r�}ztd�
|��|�W5d}~XYnX|r�|\}	}
|	|
d�|d	<q�dS)
N�typez"No handler found for  command '%s'�Skipping invalid command: %sT��exc_inforzINameserver specified for interface {0}, but interface {0} does not exist!rsrU)rwr�rW�RuntimeErrorr9r��warningr�r�rz�itemsrNr��format)r=r�r>�command_type�handler�e�	interfacerUr_r"rYr1r1r2r�5sL
�������z'NetworkStateInterpreter.parse_config_v1cCs�ddlm}t|j|�rdS|j��D]�\}}|dkr8q&z|j|}Wn0tk
rv}ztd|�|�W5d}~XYnXz||�|�	|�Wq&t
k
r�|s��ntjd|dd�t�
|���Yq&Xq&dS)Nrr)rr#z!No handler found for command '%s'r�Tr�)r�rr�r{rwr�r�rWr��
_v2_commonr9r�r�r�r�)r=r�r�r�r>r�r�r1r1r2r�Xs4���z'NetworkStateInterpreter.parse_config_v2�namecCs
|�|�Sr4�r��r=r>r1r1r2r�tsz'NetworkStateInterpreter.handle_loopbackcCs\|j�di�}|�|di�}|�di���D]\}}|�||i�q.t|�d��}|js�|D],}|�d��d�s�t|�d��r^d|_q�q^|�d	d
�}|d
k	r�t�	|�}|�dd
�}	|	d
k	r�t�	|	�}	|�dd
�}
|
d
k	r�t�	|
�}
|�|�d
�|�d�|�d�|�d�dd|�d�d
d
|||	|
d�
�|�d
|�d��}|jd�||i�|�
�d
S)z�
        command = {
            'type': 'physical',
            'mac_address': 'c0:d6:9f:2c:e8:80',
            'name': 'eth0',
            'subnets': [
                {'type': 'dhcp4'}
             ],
            'accept-ra': 'true'
        }
        rr��paramsrfr��6�addressTr&Nr%r'�	config_id�mac_address�inetZmanualr!)
r�r�r�r�r�r(r!r��gatewayrfr&r%r')rNrPr�r��_normalize_subnetsrK�endswithrrZis_truer�)r=r>rr_�paramr�rfrhZ	accept_rar%r'Z	iface_keyr1r1r2r�xsP�


��z'NetworkStateInterpreter.handle_physical�vlan_id�	vlan_linkcCs\|j�di�}|�|�|�|�d�i�}|�d�|d<|�d�|d<|�|d|i�dS)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
        rr�r�zvlan-raw-devicer�N)rNrPr�r�)r=r>rr_r1r1r2r��s

z#NetworkStateInterpreter.handle_vlan�bond_interfacesr�c	Cs|�|�|j�d�}|�|�d�i�}|�d���D]\}}|�||i�q6|�ddi�|jd�|d|i�|�d�D]�}||kr�|dd�}|�|�|j�di�}|�|�}|�d�|d	<|�d���D]\}}|�||i�q�|jd�||i�q~d
S)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
        rr�r�zbond-slavesZnoner�r,)r�r�zbond-masterN)r�rNrPr�r�)	r=r>rr_r�r��ifname�cmdZbond_ifr1r1r2r|�s&
�

z#NetworkStateInterpreter.handle_bond�bridge_interfacesc	Cs|j�di�}|�d�D] }||kr&qd|i}|�|�q|j�di�}|�|�|�|�d�i�}|d|d<|�di���D]\}}|�||i�q�|�d�}|dk	r�t|t�s�|dkr�d	}n|d
kr�d}ntdj|d
���|�d|i�|�|d|i�dS)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",
        ]
        rr�r�Zbridge_portsr�r+N)Zon�1rT)Zoff�0rFz2Cannot convert bridge_stp value ({stp}) to boolean)r*)	rNrPr�r�r�r��boolr�r�)	r=r>rr�r�r_r�r�r+r1r1r2r~�s6�

��z%NetworkStateInterpreter.handle_bridgecCs|�|�dSr4r�r�r1r1r2r�<sz)NetworkStateInterpreter.handle_infinibandcCsxg}g}d|kr<|d}t|t�s(|g}|D]}|�|�q,d|krp|d}t|t�s\|g}|D]}|�|�q`||fS)Nr�rY)r��list�append)r=r>r"rYZaddrs�addr�paths�pathr1r1r2�
_parse_dns@s

z"NetworkStateInterpreter._parse_dnsr�cCsV|j�d�}|�|�\}}d|kr6||f|j|d<n|d�|�|d�|�dS)NrUr�r"rY)rNrPr�rz�extend)r=r>rUr"rYr1r1r2r�Qs�z)NetworkStateInterpreter.handle_nameservercCs0|j�d�}|�|�\}}||d�||d<dS)NrrsrU)rNrPr�)r=r>r_Z_ifacer"rYr1r1r2�_handle_individual_nameserver^sz5NetworkStateInterpreter._handle_individual_nameserver�destinationcCs|jd�t|��dSra)rNr��_normalize_router�r1r1r2r�dsz$NetworkStateInterpreter.handle_routecCs|j|dd�dS)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�r1r1r2r}isz$NetworkStateInterpreter.handle_bondscCs|j|dd�dS)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�r1r1r2r�sz&NetworkStateInterpreter.handle_bridgescCst�}|��D�]\}}|dd�}|�di�}|�dd�}|sPt�d|t|��||d<|}|�d�}	|	rp|	}n |r�|r�|��}
t|
�}|r�|}||d	<|�d
d�}|r�d
|i|d<dD]}
|
|kr�||
||
<q�t|�|�	|�}t
|�d
kr�|�d|i�t�d|�|�|�qdS)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'}
             ]
        }
        ru)r�r�r Z
macaddressNzHNetworkState Version2: missing "macaddress" info in config entry: %s: %sr�r$r��driverr�)r!r r%r&r'rrfz!v2(ethernets) -> v1(physical):
%s)
r
r�rPr�r��str�lowerr	r3�_v2_to_v1_ipcfg�lenr�r�)r=r>Z
ifaces_by_macZeth�cfgZphy_cmdr r�r�Zset_nameZlcase_mac_addressZmacr�r7rfr1r1r2r��sH-��

z(NetworkStateInterpreter.handle_ethernetscCs�|��D]x\}}d||�d�|�d�d�}d|kr>|d|d<t|�|�|�}t|�dkrj|�d|i�t�d|�|�|�qd	S)
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'}],
        }
        rv�id�link)r�r�r�r�r!rrfzv2(vlans) -> v1(vlan):
%sN)	r�rPr3r�r�r�r�r�r�)r=r>rvr�Zvlan_cmdrfr1r1r2r�s�
z$NetworkStateInterpreter.handle_vlanscCst�d�dS)NzOWifi configuration is only available to distros with netplan rendering support.)r�r�r�r1r1r2r�"s�z$NetworkStateInterpreter.handle_wifiscCsvt�d|�|��D]\\}}d|kr|�d��d�}|�d��d�}ddi}|rX||d<|rd||d<|�||�qdS)Nzv2_common: handling config:
%sr"rYrr�rtr�)r�r�r�rPr�)r=r�r_Zdev_cfgrYrUZname_cmdr1r1r2r�(sz"NetworkStateInterpreter._v2_commonc
s.tdd�t�|���D���|��D�]\}}tdd�|��D��}|�di�}|�dd�}|rh||d<d|d	||d
|�d�dt�fd
d�|��D��i}d|kr�|d|d<t|�|�|�}	t|	�dkr�|�d|	i�t	�
d|||�|dk�r|�|�q$|dk�r|�|�q$t
dj|d���q$dS)z(Common handler for bond and bridge typescss|]\}}||fVqdSr4r1�r�r��vr1r1r2�	<genexpr>:sz>NetworkStateInterpreter._handle_bond_bridge.<locals>.<genexpr>css"|]\}}|tkr||fVqdSr4)�NETWORK_V2_KEY_FILTER)r�r7�valuer1r1r2r�?s�Z
parameterszgratuitious-arpNr)r�r�Z_interfacesrr�c3s|]\}}�||fVqdSr4r1r��Zv2key_to_v1r1r2r�Osr!rrfzv2(%s) -> v1(%s):
%sr-r,z Unknown command type: {cmd_type}r�)rnr.rPr��popr3r�r�r�r�r�r~r|r�r�)
r=r>r�Z	item_nameZitem_cfgZitem_paramsr�Z
grat_valueZv1_cmdrfr1r�r2r�6sH���


��z+NetworkStateInterpreter._handle_bond_bridgec

Cs�dd�}g}|�d�r:ddi}||�di�|�|�|�|�d�rnddi}d|_||�di�|�|�|�d	}d	}i}|�d
g�D]�}d|d�}d
|kr�d|kr�|d	kr�|�d�}|�d|i�n(d|kr�|d	kr�|�d�}|�d|i�d|k�rD|�sD|�d��d
�}	|	�r|	|d<|�d��d�}
|
�r:|
|d<|�|�|�|�q�g}|�dg�D]6}|�t|�d�|�d�|�d�|�d�d����q`t|��r�t|��r�||dd<|S)z7Common ipconfig extraction from v2 to v1 subnets array.cSsd|kr|d|d<dS)Nzroute-metric�metricr1)Z	overridesrhr1r1r2�_add_dhcp_overrideshszDNetworkStateInterpreter._v2_to_v1_ipcfg.<locals>._add_dhcp_overridesrr�rrTrNr�static)r�r��:rr�rr"rXrY�
dns_searchrb�toZviar�r!)r�r�r�r!r)rPr�rKr�r�r�)
r=r�r�rfrhrrr"r�rrYrbrdr1r1r2r�es`



�


���
z'NetworkStateInterpreter._v2_to_v1_ipcfg)T)T)T)N)%r:r;r<rxrmrRrprJrrK�setterr�r�r�r�r�r�r�rIr�r�r�r|r~r�r�r�r�r�r}rr�r�r�r�r�r�r1r1r1r2rr�sl��
��



#


<

4

@



_"
/rrcCszt�|�}tdd�|��D��}|�d�dkr@|�t|dd��dd�|�d	g�D�|d	<d
d�}dD]}|||�qf|S)
Ncss|]\}}|r||fVqdSr4r1r�r1r1r2r��sz$_normalize_subnet.<locals>.<genexpr>r�)r�Zstatic6)r�Z
ip_address��address_keyscSsg|]}t|��qSr1)r�)r��rr1r1r2r��sz%_normalize_subnet.<locals>.<listcomp>rbcSs*||kr&t||t�s&||��||<dSr4)r�r��split)Zsnetr�r1r1r2�listify�sz"_normalize_subnet.<locals>.listify)r�rX)rLrMrnr�rPr��_normalize_net_keys)rhZ
normal_subnetr�r�r1r1r2�_normalize_subnet�s 
��	
�
r�r1cCs�dd�|��D�}d}|D]}|�|�r|}q2q|sZdd�|�|f}t�|�t|��t|�|��}t|�s�t�d|�td|�d���t|�}t	|�}|�d	�}	d
|k�r|�
d
�\}
}}|
||<|r�t|�}
n*|r�t|�}
nt�d|�td|�d���nRd|k�rt
|d�}
n:|	�r0|�r0t|	�}
n$|	�rF|�rFt|	�}
n|�rPdnd
}
d|k�r�t|d�t|
�k�r�t�d|
|�|
|d<|�r�d	|k�r�|d	=n|�r�t|d�|d	<|S)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.
    cSs"i|]\}}|s|dkr||�qS)rr1r�r1r1r2�
<dictcomp>�s
z'_normalize_net_keys.<locals>.<dictcomp>Nz/No config network address keys [%s] found in %s�,z$Address %s is not a valid ip networkzAddress z is not a valid ip address�netmask�/ri�@�z;Overwriting existing 'prefix' with '%s' in network info: %s)r�rP�joinr�r�r�r�r
rr�	partitionrrror�r)rjr�ZnetZaddr_keyr7�messager�Zipv6Zipv4r�Z	addr_part�_Zmaybe_prefixrir1r1r2r��sb
�







 �
r�c
Cs�tdd�|��D��}d|kr0|d|d<|d=|�t|dd��|�d�}|r�zt|�|d<Wn2tk
r�}ztd�|��|�W5d	}~XYnX|S)
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.
    css"|]\}}|dkr||fVqdS))�NNr1r�r1r1r2r�sz#_normalize_route.<locals>.<genexpr>r�rj)rjr�r�r�z(Route config metric {} is not an integerN)	rnr�r�r�rPror��	TypeErrorr�)rdZnormal_router�r�r1r1r2r�s.
���
��r�cCs|sg}dd�|D�S)NcSsg|]}t|��qSr1)r�)r��sr1r1r2r�7sz&_normalize_subnets.<locals>.<listcomp>r1)rfr1r1r2r�4sr�T)�
net_configr�r0cCsfd}|�d�}|�d�}|dkr$|}|rP|dk	rPt|||d�}|j|d�|j}|sbtd|����|S)zfParses the config, returns NetworkState object

    :param net_config: curtin network config dict
    Nrrr�)rrr#r�zpNo valid network_state object created from network config. Did you specify the correct version? Network config:
)rPrrr�rr�)rr�r#r�rrZnsir1r1r2�parse_net_config_data:s$	

��r)r1)TN)/rLrEZlogging�typingrrrrZ	cloudinitrrrZ
cloudinit.netr	r
rrr
rrrrZcloudinit.net.rendererrZ	getLoggerr:r�rmr�r�r.r��__annotations__rnr3r8�	Exceptionr9rIrJrrr�r�r�r�r�rr1r1r1r2�<module>s�,
�����"VY
L"��