509318396
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
\¼me�  ã               @   sš  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
 d dl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jeƒZdZdddd	giZd
ddddddddddddddg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/d0dd1œd2œZeeeeef f edd3œd4d5„Z d6d7„ Z!G d8d9„ d9e"ƒZ#d:d;„ Z$G d<d=„ d=ƒZ%G d>d?„ d?ƒZ&d@dA„ Z'f fdBdC„Z(dDdE„ Z)dFdG„ Z*dLee+e%dIœdJdK„Z,dS )Mé    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Údhcp4zdhcp4-overridesÚdhcp6zdhcp6-overridesÚgateway4Úgateway6Ú
interfacesÚmatchÚmtuÚnameserversÚrendererzset-nameÚ	wakeonlanz	accept-raz	ad-selectzarp-intervalzarp-ip-targetzarp-validatez
down-delayzfail-over-mac-policyz	lacp-ratezmii-monitor-intervalz	min-linksÚmodezgratuitous-arpZ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-timeZpriorityzforward-delayz
hello-timezmax-agez	path-costzport-priorityÚstp)Zbridge_ageingZbridge_bridgeprioZ	bridge_fdZbridge_gcintZbridge_helloZbridge_maxageZbridge_maxwaitZbridge_pathcostZbridge_portprioÚ
bridge_stpZbridge_waitport)ÚbondÚbridge)ÚdiktÚreturnc             C   s$   d| ksd| kr t jdddd� dS )z8Warn about deprecations of v2 properties for all devicesr   r   z$The use of `gateway4` and `gateway6`z22.4zhFor more info check out: https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html)Z
deprecatedZdeprecated_versionZextra_messageN)r   Z	deprecate)r&   © r(   ú#/usr/lib/python3.6/network_state.pyÚwarn_deprecated_all_devicesV   s
    r*   c             C   s$   t | ƒ}x|D ]}|j|ƒ qW |S )N)ÚsetÚdiscard)ZexpectedÚactualZmissingÚkeyr(   r(   r)   Ú	diff_keysa   s    
r/   c               @   s   e Zd ZdS )ÚInvalidCommandN)Ú__name__Ú
__module__Ú__qualname__r(   r(   r(   r)   r0   h   s   r0   c                s   ‡ fdd„}|S )Nc                s   t jˆ ƒ‡ ‡fdd„ƒ}|S )Nc                s4   ˆr"t ˆ|ƒ}|r"td|ˆf ƒ‚ˆ | |f|ž|ŽS )Nz&Command missing %s of required keys %s)r/   r0   )ÚselfÚcommandÚargsÚkwargsÚmissing_keys)ÚfuncÚrequired_keysr(   r)   Ú	decoratorn   s    
z7ensure_command_keys.<locals>.wrapper.<locals>.decorator)Ú	functoolsÚwraps)r9   r;   )r:   )r9   r)   Úwrapperm   s    z$ensure_command_keys.<locals>.wrapperr(   )r:   r>   r(   )r:   r)   Úensure_command_keysl   s    r?   c               @   sš   e Zd Zefeedœdd„Zeedœdd„ƒZedd„ ƒZ	ed	d
„ ƒZ
edd„ ƒZedd„ ƒZddd„Zddd„Zdd„ Zdd„ Zeed dœdd„ƒZdS )ÚNetworkState)r   r   c             C   s*   t j|ƒ| _|| _|jddƒ| _d | _d S )NÚuse_ipv6F)ÚcopyÚdeepcopyÚ_network_stateÚ_versionÚgetrA   Ú_has_default_route)r4   r   r   r(   r(   r)   Ú__init__   s    zNetworkState.__init__)r'   c             C   s
   | j d S )Nr   )rD   )r4   r(   r(   r)   r   ‡   s    zNetworkState.configc             C   s   | j S )N)rE   )r4   r(   r(   r)   r   ‹   s    zNetworkState.versionc             C   s(   y| j d d S  tk
r"   g S X d S )NÚdnsr   )rD   ÚKeyError)r4   r(   r(   r)   Údns_nameservers�   s    zNetworkState.dns_nameserversc             C   s(   y| j d d S  tk
r"   g S X d S )NrI   Úsearch)rD   rJ   )r4   r(   r(   r)   Údns_searchdomains–   s    zNetworkState.dns_searchdomainsc             C   s   | j d kr| jƒ | _ | j S )N)rG   Ú_maybe_has_default_route)r4   r(   r(   r)   Úhas_default_route�   s    

zNetworkState.has_default_routeNc             c   sB   | j jdi ƒ}x.|jƒ D ]"}|d kr,|V  q||ƒr|V  qW d S )Nr   )rD   rF   Úvalues)r4   Úfilter_funcZifacesÚifacer(   r(   r)   Úiter_interfaces£   s    zNetworkState.iter_interfacesc             c   s:   x4| j jdg ƒD ]"}|d k	r,||ƒr2|V  q|V  qW d S )NÚroutes)rD   rF   )r4   rQ   Úrouter(   r(   r)   Úiter_routes¬   s
    zNetworkState.iter_routesc             C   sp   x| j ƒ D ]}| j|ƒr
dS q
W xJ| jƒ D ]>}x8|jdg ƒD ](}x"|jdg ƒD ]}| j|ƒrNdS qNW q<W q*W dS )NTÚsubnetsrT   F)rV   Ú_is_default_routerS   rF   )r4   rU   rR   Úsubnetr(   r(   r)   rN   ´   s    

z%NetworkState._maybe_has_default_routec             C   s    d}|j dƒdko|j dƒ|kS )Nú::ú0.0.0.0Úprefixr   Únetwork)rZ   r[   )rF   )r4   rU   Zdefault_netsr(   r(   r)   rX   ¿   s    zNetworkState._is_default_route)r   r'   c             C   s(   i }d|kr|d |d< | d|if|Ž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`.
        r   r   r(   )Úclsr   r7   r(   r(   r)   Úto_passthroughÅ   s    	zNetworkState.to_passthrough)N)N)r1   r2   r3   ÚNETWORK_STATE_VERSIONÚdictÚintrH   Úpropertyr   r   rK   rM   rO   rS   rV   rN   rX   Úclassmethodr_   r(   r(   r(   r)   r@   ~   s   
	
r@   c               @   sž  e Zd Zi g g g dœdddœZeddfddœdd„Zeed	œd
d„ƒZedd„ ƒZ	e	j
dd„ ƒZ	dd„ Zdd„ Zdd„ Zdd„ ZdJdd„ZdKdd„ZdLdd„Zedgƒdd „ ƒZedgƒd!d"„ ƒZedd#d$gƒd%d&„ ƒZedd'd(gƒd)d*„ ƒZedd+gƒd,d-„ ƒZedgƒd.d/„ ƒZd0d1„ Zed2gƒd3d4„ ƒZed2gƒd5d6„ ƒZed7gƒd8d9„ ƒZd:d;„ Zd<d=„ Zd>d?„ Zd@dA„ Z dBdC„ Z!dd	œdDdE„Z"dMdFdG„Z#dHdI„ Z$dS )NÚNetworkStateInterpreter)r   rL   FN)r   rT   rI   rA   r   zOptional[Renderer])r   c             C   sv   || _ || _tj| jƒ| _|| jd< d| _i | _|| _| j	| j
| j| j| j| j| j| j| j| j| j| j| jdœ| _d S )Nr   F)r$   Zbondsr%   ZbridgesZ	ethernetsZ
infinibandZloopbackÚ
nameserverÚphysicalrU   ÚvlanZvlansZwifis)rE   Ú_configrB   rC   Úinitial_network_staterD   Ú_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)r4   r   r   r   r(   r(   r)   rH   à   s(    
z NetworkStateInterpreter.__init__)r'   c             C   sH   ddl m} | jdkr8t| j|ƒr8tjdƒ tj| j	ƒS t| j
| jd�S )Nr   )r   é   zPassthrough netplan v2 config)r   )Úcloudinit.net.netplanr   rE   Ú
isinstancerm   ÚLOGÚdebugr@   r_   ri   rD   )r4   ÚNetplanRendererr(   r(   r)   r   ý   s
    
z%NetworkStateInterpreter.network_statec             C   s   | j jdƒS )NrA   )rD   rF   )r4   r(   r(   r)   rA     s    z NetworkStateInterpreter.use_ipv6c             C   s   | j jd|iƒ d S )NrA   )rD   Úupdate)r4   Úvalr(   r(   r)   rA   
  s    c             C   s   | j | j| jdœ}tj|ƒS )N)r   r   r   )rE   ri   rD   r   Údumps)r4   Ústater(   r(   r)   Údump  s    
zNetworkStateInterpreter.dumpc             C   sz   d|krt jdƒ tdƒ‚t|d  }t||ƒ}|rNd| }t j|ƒ t|ƒ‚x&dd„ |D ƒD ]}t| ||| ƒ q^W d S )Nr   z$Invalid state, missing version fieldzInvalid state, missing keys: %sc             S   s   g | ]}|dkr|‘qS )r   )r   r(   )Ú.0Úkr(   r(   r)   ú
<listcomp>#  s    z0NetworkStateInterpreter.load.<locals>.<listcomp>)r   ÚerrorÚ
ValueErrorÚNETWORK_STATE_REQUIRED_KEYSr/   Úsetattr)r4   r…   r:   r8   Úmsgr.   r(   r(   r)   Úload  s    


zNetworkStateInterpreter.loadc             C   s   t j| jƒS )N)r   r„   rD   )r4   r(   r(   r)   Údump_network_state&  s    z*NetworkStateInterpreter.dump_network_statec             C   s   | j | jdœS )N)r   r   )rE   ri   )r4   r(   r(   r)   Úas_dict)  s    zNetworkStateInterpreter.as_dictTc             C   s>   | j dkr| j|d� d| _n| j dkr:| j|d� d| _d S )Nr   )Úskip_brokenTr|   )rE   Úparse_config_v1rk   Úparse_config_v2)r4   r’   r(   r(   r)   Úparse_config,  s    

z$NetworkStateInterpreter.parse_configc             C   s   xž| j D ]”}|d }y| j| }W n0 tk
rR } ztd| ƒ|‚W Y d d }~X nX y||ƒ W q tk
rš   |sx‚ ntjd|dd� tj| jƒ ƒ Y qX qW xz| j	j
ƒ D ]l\}}d }y| jd | }W n2 tk
rü } ztdj|ƒƒ|‚W Y d d }~X nX |r¬|\}	}
|	|
dœ|d	< q¬W d S )
NÚtypez"No handler found for  command '%s'zSkipping invalid command: %sT)Úexc_infor   zINameserver specified for interface {0}, but interface {0} does not exist!)r   rL   rI   )ri   r{   rJ   ÚRuntimeErrorr0   r   Úwarningr€   r�   rl   ÚitemsrD   r‹   Úformat)r4   r’   r5   Úcommand_typeÚhandlerÚeÚ	interfacerI   rR   r   rL   r(   r(   r)   r“   4  s:    z'NetworkStateInterpreter.parse_config_v1c             C   sÔ   ddl m} t| j|ƒrd S x²| jjƒ D ]¤\}}|d	kr:q(y| j| }W n0 tk
rx } ztd| ƒ|‚W Y d d }~X nX y||ƒ | j	|ƒ W q( t
k
rÊ   |s¨‚ ntjd|dd� tj| jƒ ƒ Y q(X q(W d S )
Nr   )r   r   r   z!No handler found for command '%s'zSkipping invalid command: %sT)r—   )r   r   )r}   r   r~   rm   ri   rš   r{   rJ   r˜   Ú
_v2_commonr0   r   r™   r€   r�   )r4   r’   r�   rœ   r5   r�   rž   r(   r(   r)   r”   W  s*    z'NetworkStateInterpreter.parse_config_v2Únamec             C   s
   | j |ƒS )N)rv   )r4   r5   r(   r(   r)   rt   s  s    z'NetworkStateInterpreter.handle_loopbackc       
      C   s.  | j jdi ƒ}|j|d i ƒ}x*|jdi ƒjƒ D ]\}}|j||iƒ q0W t|jdƒƒ}| js’x2|D ]*}|jdƒjdƒs†t|jdƒƒrdd| _P qdW |jd	d
ƒ}|d
k	r°tj	|ƒ}|jdd
ƒ}	|	d
k	rÎtj	|	ƒ}	|j|jdƒ|jdƒ|jdƒdd|jdƒd
d
|||	dœƒ | j d j|jdƒ|iƒ | j
ƒ  d
S )zþ
        command = {
            'type': 'physical',
            'mac_address': 'c0:d6:9f:2c:e8:80',
            'name': 'eth0',
            'subnets': [
                {'type': 'dhcp4'}
             ],
            'accept-ra': 'true'
        }
        r   r¡   ÚparamsrW   r–   Ú6ÚaddressTz	accept-raNr    Úmac_addressÚinetZmanualr   )r¡   r–   r¥   r¦   r!   r   r¤   ÚgatewayrW   z	accept-rar    )rD   rF   rš   r‚   Ú_normalize_subnetsrA   Úendswithr   r   Zis_truer�   )
r4   r5   r   rR   Úparamrƒ   rW   rY   Z	accept_rar    r(   r(   r)   rv   w  s>    



z'NetworkStateInterpreter.handle_physicalÚvlan_idÚ	vlan_linkc             C   s\   | j jdi ƒ}| j|ƒ |j|jdƒi ƒ}|jdƒ|d< |jdƒ|d< |j|d |iƒ dS )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)rD   rF   rv   r‚   )r4   r5   r   rR   r(   r(   r)   rx   ®  s    

z#NetworkStateInterpreter.handle_vlanÚbond_interfacesr¢   c       	      C   s  | j |ƒ | jjdƒ}|j|jdƒi ƒ}x(|jdƒjƒ D ]\}}|j||iƒ q8W |jddiƒ | jd j|d |iƒ x’|jdƒD ]„}||kr¤|ddœ}| j |ƒ | jjdi ƒ}|j|ƒ}|jdƒ|d	< x(|jdƒjƒ D ]\}}|j||iƒ qÚW | jd j||iƒ q„W 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
        r   r¡   r¢   zbond-slavesZnoner­   r$   )r¡   r–   zbond-masterN)rv   rD   rF   rš   r‚   )	r4   r5   r   rR   rª   rƒ   ÚifnameÚcmdZbond_ifr(   r(   r)   rn   ¿  s$    


z#NetworkStateInterpreter.handle_bondÚbridge_interfacesc       	      C   s  | j jdi ƒ}x.|jdƒD ] }||kr(qd|i}| j|ƒ qW | j jdi ƒ}| j|ƒ |j|jdƒi ƒ}|d |d< x*|jdi ƒjƒ D ]\}}|j||iƒ q†W |jdƒ}|dk	o¼t|tƒ � rú|dkrÎd}n|dkrÜd}ntdj|d�ƒ‚|jd|iƒ |j|d |iƒ dS )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¡   Zbridge_portsr¢   r#   NÚonÚ1r   TÚoffÚ0r   Fz2Cannot convert bridge_stp value ({stp}) to boolean)r"   )r±   r²   r   )r³   r´   r   )	rD   rF   rv   rš   r‚   r~   Úboolr‹   r›   )	r4   r5   r   r®   r¯   rR   rª   rƒ   r#   r(   r(   r)   rp   ô  s.    


z%NetworkStateInterpreter.handle_bridgec             C   s   | j |ƒ d S )N)rv   )r4   r5   r(   r(   r)   rs   5  s    z)NetworkStateInterpreter.handle_infinibandc             C   s€   g }g }d|kr@|d }t |tƒs(|g}x|D ]}|j|ƒ q.W d|krx|d }t |tƒs`|g}x|D ]}|j|ƒ qfW ||fS )Nr¤   rL   )r~   ÚlistÚappend)r4   r5   r   rL   ZaddrsÚaddrÚpathsÚpathr(   r(   r)   Ú
_parse_dns9  s    



z"NetworkStateInterpreter._parse_dnsr¤   c             C   sV   | j jdƒ}| j|ƒ\}}d|kr6||f| j|d < n|d j|ƒ |d j|ƒ d S )NrI   rŸ   r   rL   )rD   rF   r»   rl   Úextend)r4   r5   rI   r   rL   r(   r(   r)   ru   J  s    z)NetworkStateInterpreter.handle_nameserverc             C   s0   | j jdƒ}| j|ƒ\}}||dœ|| d< d S )Nr   )r   rL   rI   )rD   rF   r»   )r4   r5   rR   Z_ifacer   rL   r(   r(   r)   Ú_handle_individual_nameserverW  s    z5NetworkStateInterpreter._handle_individual_nameserverÚdestinationc             C   s   | j d jt|ƒƒ d S )NrT   )rD   r·   Ú_normalize_route)r4   r5   r(   r(   r)   rw   ]  s    z$NetworkStateInterpreter.handle_routec             C   s   | j |dd� dS )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_bridge)r4   r5   r(   r(   r)   ro   b  s    z$NetworkStateInterpreter.handle_bondsc             C   s   | j |dd� dS )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À   N)rÁ   )r4   r5   r(   r(   r)   rq   �  s    z&NetworkStateInterpreter.handle_bridgesc             C   s$  t ƒ }�x|jƒ D �]\}}ddi}|jdi ƒ}|jddƒ}|sRtjd|t|ƒƒ ||d< |}|jdƒ}	|	rr|	}n |r’|r’|jƒ }
t|
ƒ}|r’|}||d	< |jd
dƒ}|r¶d
|i|d< x dD ]}||kr¼|| ||< q¼W t|ƒ | j	|ƒ}t
|ƒdk�r|jd|iƒ tjd|ƒ | j|ƒ qW dS )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–   rg   r   Ú
macaddressNzHNetworkState Version2: missing "macaddress" info in config entry: %s: %sr¥   zset-namer¡   Údriverr¢   r   r    ú	accept-rar   rW   z!v2(ethernets) -> v1(physical):
%s)r   r   r    rÄ   )r	   rš   rF   r   r€   ÚstrÚlowerr   r*   Ú_v2_to_v1_ipcfgÚlenr‚   rv   )r4   r5   Zifaces_by_macZethÚcfgZphy_cmdr   r¥   r¡   Zset_nameZlcase_mac_addressZmacrÃ   r.   rW   r(   r(   r)   rr   š  sB    -



z(NetworkStateInterpreter.handle_ethernetsc             C   sŠ   x„|j ƒ D ]x\}}d||jdƒ|jdƒdœ}d|kr@|d |d< t|ƒ | j|ƒ}t|ƒdkrl|jd|iƒ tjd|ƒ | j|ƒ q
W d	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'}],
        }
        rh   ÚidÚlink)r–   r¡   r«   r¬   r   r   rW   zv2(vlans) -> v1(vlan):
%sN)	rš   rF   r*   rÇ   rÈ   r‚   r   r€   rx   )r4   r5   rh   rÉ   Zvlan_cmdrW   r(   r(   r)   ry   ø  s    
z$NetworkStateInterpreter.handle_vlansc             C   s   t jdƒ d S )NzOWifi configuration is only available to distros with netplan rendering support.)r   r™   )r4   r5   r(   r(   r)   rz     s    z$NetworkStateInterpreter.handle_wifisc       
      C   sä   t jd|ƒ xÒ|jƒ D ]Æ\}}d|kr8|jdƒ}|r8|}d|kr|jdƒjdg ƒ}|jdƒjdg ƒ}ddi}t|ƒdkr†|jd|iƒ t|ƒdkr |jd	|iƒ | j|ƒ |jd
i ƒjdƒ}|rÐt|ƒ}	|	rÐ|	}| j||ƒ qW d S )Nzv2_common: handling config:
%szset-namer   rL   r   r–   rf   r   r¤   r   rÂ   )	r   r€   rš   rF   rÈ   r‚   ru   r   r½   )
r4   rÉ   rR   Zdev_cfgZset_name_ifacerL   rI   Zname_cmdr¥   Zreal_if_namer(   r(   r)   r       s,    

z"NetworkStateInterpreter._v2_commonc       
         s4  t dd„ tj|ƒjƒ D ƒƒ‰ �x|jƒ D �]\}}t dd„ |jƒ D ƒƒ}|jdi ƒ}|jddƒ}|rl||d< d|d	||d
 |jdƒdt ‡ fdd„|jƒ D ƒƒi}d|kr´|d |d< t|ƒ | j|ƒ}	t|	ƒdkrà|jd|	iƒ t	j
d|||ƒ |dk�r| j|ƒ q(|dk�r| j|ƒ q(tdj|d�ƒ‚q(W dS )z(Common handler for bond and bridge typesc             s   s   | ]\}}||fV  qd S )Nr(   )r‡   rˆ   Úvr(   r(   r)   ú	<genexpr>@  s    z>NetworkStateInterpreter._handle_bond_bridge.<locals>.<genexpr>c             s   s"   | ]\}}|t kr||fV  qd S )N)ÚNETWORK_V2_KEY_FILTER)r‡   r.   Úvaluer(   r(   r)   rÍ   E  s   Z
parameterszgratuitious-arpNzgratuitous-arpr–   r¡   Z_interfacesr   r¢   c             3   s   | ]\}}ˆ | |fV  qd S )Nr(   )r‡   rˆ   rÌ   )Úv2key_to_v1r(   r)   rÍ   T  s    r   r   rW   zv2(%s) -> v1(%s):
%sr%   r$   z Unknown command type: {cmd_type})rÀ   )ra   ÚNET_CONFIG_TO_V2rF   rš   Úpopr*   rÇ   rÈ   r‚   r   r€   rp   rn   r‹   r›   )
r4   r5   rÀ   Z	item_nameZitem_cfgZitem_paramsr¢   Z
grat_valueZv1_cmdrW   r(   )rÐ   r)   rÁ   ;  s8    


z+NetworkStateInterpreter._handle_bond_bridgec             C   s¼  dd„ }g }|j dƒr:ddi}||j di ƒ|ƒ |j|ƒ |j dƒrnddi}d| _||j di ƒ|ƒ |j|ƒ d	}d	}i }xØ|j d
g ƒD ]È}d|dœ}d|krÈd|krð|d	krð|j dƒ}|jd|iƒ n(d|krð|d	krð|j dƒ}|jd|iƒ d|koü| �rF|j dƒj d
ƒ}	|	�r|	|d< |j dƒj dƒ}
|
�r<|
|d< |j|ƒ |j|ƒ qˆW g }x>|j dg ƒD ].}|jt|j dƒ|j dƒ|j dƒdœƒƒ �qfW t|ƒ�r¸t|ƒ�r¸||d d< |S )z7Common ipconfig extraction from v2 to v1 subnets array.c             S   s   d| kr| d |d< d S )Nzroute-metricÚmetricr(   )Z	overridesrY   r(   r(   r)   Ú_add_dhcp_overridesm  s    zDNetworkStateInterpreter._v2_to_v1_ipcfg.<locals>._add_dhcp_overridesr   r–   zdhcp4-overridesr   Tzdhcp6-overridesNr   Ústatic)r–   r¤   ú:r   r§   r   r   rK   rL   Ú
dns_searchrT   ZtoZviarÓ   )r¾   r§   rÓ   r   )rF   r·   rA   r‚   r¿   rÈ   )r4   rÉ   rÔ   rW   rY   r   r   r   r¤   r   rL   rT   rU   r(   r(   r)   rÇ   j  sV    






z'NetworkStateInterpreter._v2_to_v1_ipcfg)T)T)T)N)%r1   r2   r3   rj   r`   rH   rc   r@   r   rA   Úsetterr†   r�   r�   r‘   r•   r“   r”   r?   rt   rv   rx   rn   rp   rs   r»   ru   r½   rw   ro   rq   rr   ry   rz   r    rÁ   rÇ   r(   r(   r(   r)   re   Ô   sL   

#
75A^"
/re   c             C   s~   t j| ƒ} tdd„ | jƒ D ƒƒ}| jdƒdkr@|jt|dd�ƒ d	d
„ | jdg ƒD ƒ|d< dd„ }xdD ]}|||ƒ qhW |S )Nc             s   s   | ]\}}|r||fV  qd S )Nr(   )r‡   rˆ   rÌ   r(   r(   r)   rÍ   °  s    z$_normalize_subnet.<locals>.<genexpr>r–   rÕ   Ústatic6r¤   Ú
ip_address)Úaddress_keysc             S   s   g | ]}t |ƒ‘qS r(   )r¿   )r‡   Úrr(   r(   r)   r‰   ½  s    z%_normalize_subnet.<locals>.<listcomp>rT   c             S   s,   || kr(t | | tƒ r(| | jƒ | |< d S )N)r~   r¶   Úsplit)Zsnetr¡   r(   r(   r)   ÚlistifyÀ  s    z"_normalize_subnet.<locals>.listifyr×   rK   )rÕ   rÙ   )r¤   rÚ   )r×   rK   )rB   rC   ra   rš   rF   r‚   Ú_normalize_net_keys)rY   Znormal_subnetrÞ   rˆ   r(   r(   r)   Ú_normalize_subnet­  s    
 

rà   c             C   s¾  dd„ | j ƒ D ƒ}d}x|D ]}|j|ƒr|}P qW |s\ddj|ƒ| f }tj|ƒ t|ƒ‚t|j|ƒƒ}t|ƒsŽtjd|ƒ td|› d�ƒ‚t|ƒ}t	|ƒ}|jd	ƒ}	d
|k�r|j
d
ƒ\}
}}|
||< |rØt|ƒ}n*|ræt|ƒ}ntjd|ƒ td|› d�ƒ‚nRd|k�rt|d ƒ}n:|	�r2|�r2t|	ƒ}n$|	�rH|�rHt|	ƒ}n|�rRdnd}d|k�r„t|d ƒt|ƒk�r„tj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.
    c             S   s"   i | ]\}}|s|d kr||“qS )r   r(   )r‡   rˆ   rÌ   r(   r(   r)   ú
<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 networkzAddress z is not a valid ip addressÚnetmaskú/r\   é@   é   z;Overwriting existing 'prefix' with '%s' in network info: %s)rš   rF   Újoinr   rŠ   r‹   rÅ   r   r   r   Ú	partitionr   r
   rb   r™   r   )r]   rÛ   ZnetZaddr_keyr.   Úmessager¸   Zipv6Zipv4rã   Z	addr_partÚ_Zmaybe_prefixr\   r(   r(   r)   rß   Ê  s^    









 
rß   c             C   s˜   t dd„ | jƒ D ƒƒ}d|kr0|d |d< |d= |jt|d	d�ƒ |jdƒ}|r”yt|ƒ|d< W n2 tk
r’ } ztdj|ƒƒ|‚W Y dd}~X nX |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.
    c             s   s"   | ]\}}|dkr||fV  qdS )Ú N)rë   Nr(   )r‡   rˆ   rÌ   r(   r(   r)   rÍ   !  s    z#_normalize_route.<locals>.<genexpr>r¾   r]   )rÛ   rÓ   z(Route config metric {} is not an integerN)r]   r¾   )	ra   rš   r‚   rß   rF   rb   r‹   Ú	TypeErrorr›   )rU   Znormal_routerÓ   rž   r(   r(   r)   r¿     s"    


r¿   c             C   s   | sg } dd„ | D ƒS )Nc             S   s   g | ]}t |ƒ‘qS r(   )rà   )r‡   Úsr(   r(   r)   r‰   ;  s    z&_normalize_subnets.<locals>.<listcomp>r(   )rW   r(   r(   r)   r¨   8  s    r¨   T)Ú
net_configr’   r'   c             C   sf   d}| j dƒ}| j dƒ}|dkr$| }|rP|dk	rPt|||d�}|j|d� |j}|sbt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:
)rF   re   r•   r   r˜   )rî   r’   r   r…   r   r   Znsir(   r(   r)   Úparse_net_config_data>  s    	

rï   )TN)-rB   r<   ZloggingZtypingr   r   r   r   Z	cloudinitr   r   Zcloudinit.netr   r	   r
   r   r   r   r   r   r   Zcloudinit.net.rendererr   Z	getLoggerr1   r   r`   rŒ   rÎ   rÑ   rÅ   ra   r*   r/   Ú	Exceptionr0   r?   r@   re   rà   rß   r¿   r¨   rµ   rï   r(   r(   r(   r)   Ú<module>   sŒ    ,
 V     ^L" 