Your IP : 216.73.217.13


Current Path : /usr/lib/python3/dist-packages/cloudinit/net/__pycache__/
Upload File :
Current File : //usr/lib/python3/dist-packages/cloudinit/net/__pycache__/network_state.cpython-38.pyc

U

�Ad6��@s�UddlZddlZddlZddlmZmZmZmZddlm	Z	m
Z
ddlmZm
Z
mZmZmZmZmZmZmZer~ddlmZe�e�ZdZdddd	giZd
ddd
dddddddddddgZdddddddd d!d"d#d$d%d&d'd(�d)d*d+dd,d-dd.d/d0dd1�d2�Zeeeeeffed3<e dd4�d5d6�Z!d7d8�Z"d9d:�Z#Gd;d<�d<e$�Z%d=d>�Z&Gd?d@�d@e'�Z(GdAdB�dB�Z)GdCdD�dDe(dE�Z*dFdG�Z+dSdIdJ�Z,dKdL�Z-dMdN�Z.dTe e/e)dP�dQdR�Z0dS)U�N)�
TYPE_CHECKING�Any�Dict�Optional)�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-raz	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�returncCsd|ksd|krt�d�dS)z8Warn about deprecations of v2 properties for all devicesrrz�DEPRECATED: The use of `gateway4` and `gateway6` is deprecated. For more info check out: https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.htmlN��LOG�warning)r-�r2�=/usr/lib/python3/dist-packages/cloudinit/net/network_state.py�warn_deprecated_all_devicesVs�r4cCst�|�}t�}|�|�|S�N)rZ	read_conf�NetworkStateInterpreter�load)Z
state_file�state�nsir2r2r3�from_state_file`s

r:cCs t|�}|D]}|�|�q|Sr5)�set�discard)ZexpectedZactualZmissing�keyr2r2r3�	diff_keysgsr>c@seZdZdS)�InvalidCommandN)�__name__�
__module__�__qualname__r2r2r2r3r?nsr?cs�fdd�}|S)Ncst�����fdd��}|S)Ncs4�r"t�|�}|r"td|�f���||f|�|�S)Nz&Command missing %s of required keys %s)r>r?)�self�command�args�kwargs�missing_keys)�func�
required_keysr2r3�	decoratorts
��z7ensure_command_keys.<locals>.wrapper.<locals>.decorator)�	functools�wraps)rHrJ�rI)rHr3�wrapperss
z$ensure_command_keys.<locals>.wrapperr2)rIrNr2rMr3�ensure_command_keysrsrOcs eZdZdZ�fdd�Z�ZS)�CommandHandlerMetaaMetaclass that dynamically creates a 'command_handlers' attribute.

    This will scan the to-be-created class for methods that start with
    'handle_' and on finding those will populate a class attribute mapping
    so that those methods can be quickly located and called.
    csbi}|��D]6\}}t|�r|�d�r|td�d�}|r|||<q||d<tt|��||||�S)NZhandle_�command_handlers)�items�callable�
startswith�len�superrP�__new__)�cls�name�parentsZdctrQZ	attr_name�attrZhandles_what��	__class__r2r3rW�s
zCommandHandlerMeta.__new__)r@rArB�__doc__rW�
__classcell__r2r2r\r3rP�srPc@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�getra�_has_default_route)rCrrr2r2r3�__init__�szNetworkState.__init__�r.cCs
|jdS)Nr)rd�rCr2r2r3r�szNetworkState.configcCs|jSr5)rerjr2r2r3r�szNetworkState.versioncCs.z|jddWStk
r(gYSXdS)N�dnsr!�rd�KeyErrorrjr2r2r3�dns_nameservers�szNetworkState.dns_nameserverscCs.z|jddWStk
r(gYSXdS)Nrk�searchrlrjr2r2r3�dns_searchdomains�szNetworkState.dns_searchdomainscCs|jdkr|��|_|jSr5)rg�_maybe_has_default_routerjr2r2r3�has_default_route�s

zNetworkState.has_default_routeNccs>|j�di�}|��D]"}|dkr*|Vq||�r|VqdS)Nr)rdrf�values)rC�filter_funcZifaces�ifacer2r2r3�iter_interfaces�szNetworkState.iter_interfacesccs6|j�dg�D]"}|dk	r*||�r0|Vq|VqdS�N�routes�rdrf)rCrt�router2r2r3�iter_routes�s
zNetworkState.iter_routescCsh|��D]}|�|�rdSq|��D]<}|�dg�D]*}|�dg�D]}|�|�rFdSqFq6q&dS)NT�subnetsrxF)r{�_is_default_routervrf)rCrzru�subnetr2r2r3rq�s

z%NetworkState._maybe_has_default_routecCs d}|�d�dko|�d�|kS)N)z::z0.0.0.0�prefixr�network)rf)rCrzZdefault_netsr2r2r3r}�s�zNetworkState._is_default_route)rr.cCs(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`.
        rrr2)rXrrFr2r2r3�to_passthrough�s	zNetworkState.to_passthrough)N)N)r@rArB�NETWORK_STATE_VERSION�dict�intrh�propertyrrrnrprrrvr{rqr}�classmethodr�r2r2r2r3r`�s*��




	
r`c@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)Nr6�r!roFN)rrxrkrarzOptional[Renderer])r"cCs:||_||_t�|j�|_||jd<d|_i|_||_dS)NrF)	re�_configrbrc�initial_network_staterd�_parsed�_interface_dns_map�	_renderer)rCrrr"r2r2r3rh�s
z NetworkStateInterpreter.__init__ricCsHddlm}|jdkr8t|j|�r8t�d�t�|j	�St|j
|jd�S)Nrr�zPassthrough netplan v2 config�r)�cloudinit.net.netplanrre�
isinstancer�r0�debugr`r�r�rd)rC�NetplanRendererr2r2r3rs

z%NetworkStateInterpreter.network_statecCs|j�d�S�Nraryrjr2r2r3rasz NetworkStateInterpreter.use_ipv6cCs|j�d|i�dSr�)rd�update)rC�valr2r2r3rascCs|j|j|jd�}t�|�S)N)rrr)rer�rdr�dumps)rCr8r2r2r3�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�r2)�.0�kr2r2r3�
<listcomp>.sz0NetworkStateInterpreter.load.<locals>.<listcomp>)r0�error�
ValueError�NETWORK_STATE_REQUIRED_KEYSr>�setattr)rCr8rIrG�msgr=r2r2r3r7!s


zNetworkStateInterpreter.loadcCst�|j�Sr5)rr�rdrjr2r2r3�dump_network_state1sz*NetworkStateInterpreter.dump_network_statecCs|j|jd�S)N)rr)rer�rjr2r2r3�as_dict4szNetworkStateInterpreter.as_dictTcCs>|jdkr|j|d�d|_n|jdkr:|j|d�d|_dS)Nr��skip_brokenTr�)re�parse_config_v1r��parse_config_v2)rCr�r2r2r3�parse_config7s

z$NetworkStateInterpreter.parse_configcCs|jD]�}|d}z|j|}Wn0tk
rP}ztd|�|�W5d}~XYnXz|||�Wqtk
r�|sx�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!)rrork)r�rQrm�RuntimeErrorr?r0r1r�r�r�rRrdr��format)rCr�rD�command_type�handler�e�	interfacerkrur!ror2r2r3r�?sL
�������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�r�rRrQrmr��
_v2_commonr?r0r1r�r�)rCr�r�r�rDr�r�r2r2r3r�bs4��
�z'NetworkStateInterpreter.parse_config_v2rYcCs
|�|�Sr5��handle_physical�rCrDr2r2r3�handle_loopback~sz'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�d
d|�d�d
d
|||	d��|jd�|�d�|i�|�
�d
S)z�
        command = {
            'type': 'physical',
            'mac_address': 'c0:d6:9f:2c:e8:80',
            'name': 'eth0',
            'subnets': [
                {'type': 'dhcp4'}
             ],
            'accept-ra': 'true'
        }
        rrY�paramsr|r��6�addressTr%Nr$�mac_address�inetZmanualr )rYr�r�r�r&r r��gatewayr|r%r$)rdrfrRr��_normalize_subnetsra�endswithrrZis_truer�)
rCrDrru�paramr�r|r~Z	accept_rar$r2r2r3r��sD�

��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
        rrYr�zvlan-raw-devicer�N)rdrfr�r�)rCrDrrur2r2r3�handle_vlan�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
        rrYr�zbond-slavesZnoner�r*)rYr�zbond-masterN)r�rdrfrRr�)	rCrDrrur�r��ifname�cmdZbond_ifr2r2r3�handle_bond�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|�tkr�|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�rYZbridge_portsr�r)N)Zon�1rT)Zoff�0rFz2Cannot convert bridge_stp value ({stp}) to boolean)r()	rdrfr�rRr�r��boolr�r�)	rCrDrr�r�rur�r�r)r2r2r3�
handle_bridge�s6�

��z%NetworkStateInterpreter.handle_bridgecCs|�|�dSr5r�r�r2r2r3�handle_infiniband@sz)NetworkStateInterpreter.handle_infinibandcCszg}g}d|kr>|d}t|�tks*|g}|D]}|�|�q.d|krr|d}t|t�s^|g}|D]}|�|�qb||fS)Nr�ro)r��list�appendr�)rCrDr!roZaddrs�addr�paths�pathr2r2r3�
_parse_dnsDs
z"NetworkStateInterpreter._parse_dnsr�cCsV|j�d�}|�|�\}}d|kr6||f|j|d<n|d�|�|d�|�dS)Nrkr�r!ro)rdrfr�r��extend)rCrDrkr!ror2r2r3�handle_nameserverUs�z)NetworkStateInterpreter.handle_nameservercCs0|j�d�}|�|�\}}||d�||d<dS)Nrr�rk)rdrfr�)rCrDruZ_ifacer!ror2r2r3�_handle_individual_nameserverbsz5NetworkStateInterpreter._handle_individual_nameserver�destinationcCs|jd�t|��dSrw)rdr��_normalize_router�r2r2r3�handle_routehsz$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�r2r2r3�handle_bondsmsz$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�r2r2r3�handle_bridges�sz&NetworkStateInterpreter.handle_bridgescCst�}|��D�]\}}ddi}|�di�}|�dd�}|sNt�d|t|��||d<|}|�d�}	|	rn|	}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_netsvc
            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�Zphysicalr�
macaddressNzHNetworkState Version2: missing "macaddress" info in config entry: %s: %sr�r#rY�driverr�)r rr$r%rr|z!v2(ethernets) -> v1(physical):
%s)
r	rRrfr0r��str�lowerrr4�_v2_to_v1_ipcfgrUr�r�)rCrDZ
ifaces_by_macZeth�cfgZphy_cmdrr�rYZset_nameZlcase_mac_addressZmacr�r=r|r2r2r3�handle_ethernets�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'}],
        }
        �vlan�id�link)r�rYr�r�r rr|zv2(vlans) -> v1(vlan):
%sN)	rRrfr4r�rUr�r0r�r�)rCrDr�r�Zvlan_cmdr|r2r2r3�handle_vlanss�
z$NetworkStateInterpreter.handle_vlanscCst�d�dS)NzOWifi configuration is only available to distros with netplan rendering support.r/r�r2r2r3�handle_wifis&s�z$NetworkStateInterpreter.handle_wifisc
Cs�t�d|�|��D]�\}}d|kr6|�d�}|r6|}d|kr|�d��dg�}|�d��dg�}ddi}t|�dkr�|�d|i�t|�dkr�|�d	|i�|�|�|�d
i��d�}|r�t|�}	|	r�|	}|�||�qdS)Nzv2_common: handling config:
%sr#r!rorr�Z
nameserverrr�rr�)	r0r�rRrfrUr�r�rr�)
rCr�ruZdev_cfgZset_name_ifacerorkZname_cmdr�Zreal_if_namer2r2r3r�,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|]\}}||fVqdSr5r2�r�r��vr2r2r3�	<genexpr>Ksz>NetworkStateInterpreter._handle_bond_bridge.<locals>.<genexpr>css"|]\}}|tkr||fVqdSr5)�NETWORK_V2_KEY_FILTER)r�r=�valuer2r2r3r�Ps�Z
parameterszgratuitious-arpNr'r�rYZ_interfacesrr�c3s|]\}}�||fVqdSr5r2r��Zv2key_to_v1r2r3r�`sr rr|zv2(%s) -> v1(%s):
%sr+r*z Unknown command type: {cmd_type}r�)r�r,rfrR�popr4r�rUr�r0r�r�r�r�r�)
rCrDr�Z	item_nameZitem_cfgZitem_paramsr�Z
grat_valueZv1_cmdr|r2r�r3r�GsH���


��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]&}|�t|�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�metricr2)Z	overridesr~r2r2r3�_add_dhcp_overridesyszDNetworkStateInterpreter._v2_to_v1_ipcfg.<locals>._add_dhcp_overridesrr�rrTrNr�static)r�r��:rr�rr!rnro�
dns_searchrx�toZvia)r�r�r)rfr�rar�r�rU)
rCr�r�r|r~rrr!r�rrorxrzr2r2r3r�vs\



�


���z'NetworkStateInterpreter._v2_to_v1_ipcfg)T)T)T)N)%r@rArBr�r�rhr�r`rra�setterr�r7r�r�r�r�r�rOr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r2r2r2r3r6�sl��
��



#


6

4

@



^"
/r6)�	metaclasscCszt�|�}tdd�|��D��}|�d�dkr@|�t|dd��dd�|�d	g�D�|d	<d
d�}dD]}|||�qf|S)
Ncss|]\}}|r||fVqdSr5r2r�r2r2r3r��sz$_normalize_subnet.<locals>.<genexpr>r�)r�Zstatic6)r�Z
ip_address��address_keyscSsg|]}t|��qSr2)r�)r��rr2r2r3r��sz%_normalize_subnet.<locals>.<listcomp>rxcSs*||kr&t||t�s&||��||<dSr5)r�r��split)ZsnetrYr2r2r3�listify�sz"_normalize_subnet.<locals>.listify)r�rn)rbrcr�rRrfr��_normalize_net_keys)r~Z
normal_subnetr�r�r2r2r3�_normalize_subnet�s 
��	
�
r�r2cCs�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)rr2r�r2r2r3�
<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�/r�@�z;Overwriting existing 'prefix' with '%s' in network info: %s)rRrf�joinr0r�r�r�rrr
�	partitionrr
r�r1r)r�r�ZnetZaddr_keyr=�messager�Zipv6Zipv4rZ	addr_part�_Zmaybe_prefixrr2r2r3r��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))�NNr2r�r2r2r3r�+sz#_normalize_route.<locals>.<genexpr>r�r�)r�r�r�r�z(Route config metric {} is not an integerN)	r�rRr�r�rfr�r��	TypeErrorr�)rzZnormal_router�r�r2r2r3r�!s.
���
��r�cCs|sg}dd�|D�S)NcSsg|]}t|��qSr2)r�)r��sr2r2r3r�Fsz&_normalize_subnets.<locals>.<listcomp>r2)r|r2r2r3r�Csr�T)�
net_configr�r.cCsfd}|�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:
)rfr6r�rr�)r
r�r"r8rrr9r2r2r3�parse_net_config_dataIs$	

��r)r2)TN)1rbrKZlogging�typingrrrrZ	cloudinitrrZ
cloudinit.netrr	r
rrr
rrrZcloudinit.net.rendererrZ	getLoggerr@r0r�r�r�r,r��__annotations__r�r4r:r>�	Exceptionr?rOr�rPr`r6r�r�r�r�r�rr2r2r2r3�<module>s�,
�����"
VP
L"��