
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
\meU                 @   s   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZmZmZ d dlmZ ejeZdddd	d
dgZ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*gZd+d, Zd-d. Zd>d0d1Zd2d3 Zd4d5 Zd6d7 ZG d8d9 d9ejZd?d:d;Zd@d<d=ZdS )A    N)Optional)subputil)ParserErrorrenderersubnet_is_ipv6)NetworkStatezpre-upupzpost-updownzpre-downz	post-downZbridge_ageingZbridge_bridgeprioZ	bridge_fdZbridge_gcinitZbridge_helloZbridge_maxageZbridge_maxwaitZ
bridge_stpaddressnetmask	broadcastnetworkmetricgatewayZpointtopointZmediamtuZhostnameZ
leasehoursZ	leasetimeZvendorZclientZbootfileserverZhwaddrZproviderframeZnetnumZendpointZlocalZttlc          
   C   s   g }ddddddddd	d
g
}x|j  D ]t\}}|dkr8q&|dkrTd|d |d f }|r&||kr&t|trtdj|}d|kr|jdd}|jdj|| q&W t|S )Nr   r   r   r   r   Zpointopointr   Zscope
dns_searchdns_nameserversz%s/%sprefix _-z    {0} {1})items
isinstancelistjoinreplaceappendformatsorted)ifacesubnetcontentZ	valid_mapkeyvalue r'   /usr/lib/python3.6/eni.py_iface_add_subnet@   s.    

r)   c       
   	   C   s"  |dkrg S g }dddddddd	d
g	}dddg}ddi}| d
 dkrN|j d x| j D ]\}}t|trz| | rvdnd}| sX||krqX|dkr|r||krXtjd| d || qX||krx&|D ]}	|j dj|j|||	 qW qXt|t rdj	|}|j dj|j||| qXW t
|S )Nr   controlZ	device_idZdriverindexinetmodenamesubnetstypebridge_pathcostbridge_portprioZbridge_waitportmac_address	hwaddressbondbridge
infinibandvlanZonZoffr   zZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.z    {0} {1}r   )r5   r6   r7   r8   )r   r   r   boolLOGZwarningr    getr   r   r!   )
r"   r+   ipv4_subnet_mtur$   Z
ignore_mapZmultiline_keysrenamesr%   r&   vr'   r'   r(   _iface_add_attrs^   sN    



r?   Fc             C   s   | d }| d }|dkrd}n|dkr0d| }nd| }| j  }|j||d djf |d	jf |g}|r| jd
r|jdjf | |S )Nr.   r*   autohotplugzallow-z
# control-)fullnamecverbz{cverb} {fullname}ziface {fullname} {inet} {mode}r3   z    hwaddress {mac_address})rA   )copyupdater    r;   r   )r"   r+   render_hwaddressrB   r*   rC   Zsubstlinesr'   r'   r(   _iface_start_entry   s    

rH   c                sr  d}x8|j  D ]*}|j }|jdr*q|jd}|d }|dkr|d }|jdsdtjj||}xtj|D ]r tj }	 fdd	|	D }	xP|	D ]H}
t	|
d
}|j
 j }W dQ R X tjj|
}t| |tjj|| qW qpW q|dkrp|d }|jdstjj||}xXtj|D ]J t	 d
}|j
 j }W dQ R X tjj }t| |tjj|| q W q|dkrx8|dd D ](}|| krd|i| |< d| | d< qW q|dkr&|dd \}}}|| krd|i| |< nd| | krtd||f || | d< || | d< |}q|dkr^|d dkrH|d }n|d }|| | d< q|tkrz|d | | |< q|tkr|| | krg | | |< | | | jdj|dd  q|jdrzd| | kri | | d< |dkr0g | | d d< xv|dd D ]}| | d d j| qW nH|dkr<g | | d d< x,|dd D ]}| | d d j| qXW q|jdrd| | kri | | d< |tkr|jddd}|d | | d |< q<|d krg | | d d!< x,|dd D ]}| | d d! j| qW n|d"krb|d j d#krL|d | | d d#< n|d | | d d#< n|d$krd%| | d kri | | d d%< |d | | d d% |d < nH|d&kr<d'| | d kri | | d d'< |d | | d d' |d < q|jd(rd)| | kri | | d)< |jd(dd}|d | | d) |< qW x,| j D ] }d| | krJd*| | d< qJW dS )+a}  Parses the file contents, placing result into ifaces.

    '_source_path' is added to every dictionary entry to define which file
    the configration information came from.

    :param ifaces: interface dictionary
    :param contents: contents of interfaces file
    :param src_dir: directory interfaces file was located
    :param src_path: file path the `contents` was read
    N#r   r   zsource-directory   /c                s@   g | ]8}t jjt jj |rtjd |dk	rt jj |qS )z^[a-zA-Z0-9_-]+$N)ospathisfiler   rematch).0rM   )expanded_pathr'   r(   
<listcomp>   s   z*_parse_deb_config_data.<locals>.<listcomp>rsourcer@   Z_source_pathTr"      familyz:Interface %s can only be defined once. Re-defined in '%s'.methodr4   Zether   zdns-dnsz
dns-searchsearchzdns-nameserversnameserversZbridge_r6    Zbridge_portsZportsZ	bridge_hwZmacr1   Zpathcostr2   Zportpriozbond-r5   F)
splitlinesstrip
startswithsplitrL   rM   r   globlistdiropenreadabspath_parse_deb_config_datadirnamer   NET_CONFIG_OPTIONSNET_CONFIG_COMMANDSr   NET_CONFIG_BRIDGE_OPTIONSr   lowerkeys)ifacescontentssrc_dirsrc_pathZcurriflinera   ZoptionZparsed_src_dirZdir_contentsentryfpZsrc_dataZ	abs_entryZnew_src_pathZabs_pathr"   rW   rX   valZdomainr   Zbridge_optionZbond_optionr'   )rR   r(   rg      s    














"







rg   c             C   s   i }t || d d d t|S )N)rp   rq   )rg   _ifaces_to_net_config_data)Zeni_datarn   r'   r'   r(   convert_eni_data7  s    rw   c                sF  i  x"| j  D ]\}}|jdd }| krj|dkr>d}nd}||g d |< d|krj|d  | d< ||d	 d
}|jdrd|d< nd|d< |jd	dkr|d |d< x dD ]}||kr|| ||< qW d|krx8dD ]0}||d kr|d | r|d | |d| < qW  | d j| qW d fddt D dS )zReturn network config that represents the ifaces data provided.
    ifaces = _parse_deb_config_data(...)
    config = ifaces_to_net_config_data(ifaces)
    state = parse_net_config_data(config).:r   loloopbackphysical)r0   r.   r/   r4   r3   rX   )Z_orig_eni_namer0   r@   r*   Zmanualstaticr   r   r   r   rZ   r\   r[   Zdns_r/   rJ   c                s   g | ]} | qS r'   r'   )rQ   d)devsr'   r(   rS   d  s    z._ifaces_to_net_config_data.<locals>.<listcomp>)versionconfig)r   r   r   )r\   r[   )r   	partitionr;   r   r!   )rn   r.   dataZdevnameZdtyper#   Zcopy_keynr'   )r~   r(   rv   >  s2    




rv   c               @   sP   e Zd ZdZdddZdddZdd	d
ZdddZdee	e
 ddddZdS )Rendererz@Renders network information in a /etc/network/interfaces format.Nc             C   s6   |si }|j dd| _|j dd | _|j dd| _d S )Neni_pathzetc/network/interfaces
eni_headernetrules_pathz(etc/udev/rules.d/70-persistent-net.rules)r;   r   r   r   )selfr   r'   r'   r(   __init__j  s    zRenderer.__init__r]   c             C   sP  g }|d }|d }d}ddd}d}|d d	krD|d
 d	krDd}n|d dkr`|d dkr`d}d}	xdD ]}
|r||
dkr|qj|
dkr|	d|||
 ||
 f 7 }	qj|
|krj|
dkrd||
 kr|	d7 }	n |j ddkr|	d7 }	n|	d7 }	d|kr$|	d||
 |d f 7 }	qj|	d||
 ||
 f 7 }	qjW |j||	 |  |j||	 |  |S )a  When rendering routes for an iface, in some cases applying a route
        may result in the route command returning non-zero which produces
        some confusing output for users manually using ifup/ifdown[1].  To
        that end, we will optionally include an '|| true' postfix to each
        route line allowing users to work with ifup/ifdown without using
        --force option.

        We may at somepoint not want to emit this additional postfix, and
        add a 'strict' flag to this function.  When called with strict=True,
        then we will not append the postfix.

        1. http://askubuntu.com/questions/168033/
                 how-to-set-static-routes-in-ubuntu-server
        zpost-up route addzpre-down route delz || trueZgwr   )r   r   r]   r   z0.0.0.0r   z defaultz::r   r   z -A inet6 defaultr   z%s %s %srx   z	 -A inet6    z -hostz -netz %s/%sz %s %s)r   r   r   )r;   r   )r   routeindentr$   r	   r
   Zor_truemappingZ
default_gwZ
route_linekr'   r'   r(   _render_routes  s<    




zRenderer._render_routeFc                s6  g } j di } jdd } jdd }|r4d d< |rؐxt|D ]\}}d }	| d< |d  d< |j d	d
 d	< d}
t|r|
d7 }
n
|j d}	|
 d< |d dks|d dks|d dkrd d< |d k	r|rdnd d< nn|d dkrd
 d< d d< nN|d dkr&d
 d< d d< n.t|rTd d< |d k	rT|rLdnd d< d fdd|D krtd d	< tt ||dt | t ||	 }x*|j dg D ]}|j| j	|dd qW |j
| qFW nZg }d  ksd! kr|j
d"jf   |j
d#jf   |jt d$d d% |j
| |S )&Nr/   z	accept-raZ	wakeonlangzethernet-wolr+   r0   r-   r*   r@   r,   6r   Zdhcp4Zdhcp6zipv6_dhcpv6-statefulZdhcp10	accept_razipv6_dhcpv6-statelessZ
ipv6_slaacr|   Tc                s   g | ]}d  d  |kqS )zauto %sr.   r'   )rQ   rr   )r"   r'   r(   rS     s    z*Renderer._render_iface.<locals>.<listcomp>alias)rF   Zroutesz    )r   zbond-masterzbond-slaveszauto {name}ziface {name} {inet} {mode}r   )r+   r<   )r;   pop	enumerater   r   rH   r)   r?   extendr   r   r    )r   r"   rF   sectionsr/   r   Zethernet_wolr+   r#   r<   Zsubnet_inetrG   r   r'   )r"   r(   _render_iface  sb    





&
zRenderer._render_ifacec       	         s&  ddddddgd}x(|j  D ]}|jddkr tj|}q W |j}|r`d	j||d
 d d< |j}|rd	j||d
 d d< ddddddd g }|j| j| xDt	|j   fdddD ](}|jddkrq|j| j||d qW x |j
 D ]}|j| j| qW djdd |D d S )z1Given state, emit etc/network/interfaces content.ry   r{   r,   rz   r@   )r0   r*   )r.   r0   r,   r/   r.   r   r/   r   r   r   rJ   rY      rV      )rz   r{   r7   r5   r6   r8   c                s    | d  | d fS )Nr0   r.   r'   )r   )orderr'   r(   <lambda>  s    z-Renderer._render_interfaces.<locals>.<lambda>)r%   )rF   z

c             S   s   g | ]}d j |qS )
)r   )rQ   sr'   r'   r(   rS   &  s    z/Renderer._render_interfaces.<locals>.<listcomp>r   )Ziter_interfacesr;   rD   deepcopyr   r   Zdns_searchdomainsr   r   r!   Ziter_routesr   r   )	r   network_staterF   ry   r"   r\   Zsearchdomainsr   r   r'   )r   r(   _render_interfaces  s>    zRenderer._render_interfaces)r   	templatesreturnc             C   s   t j|| j}tjtjj| | jr,| jnd}tj	||| j
|  | jrt j|| j}tjtjj| tj	|| j|dd d S )Nr]   T)r$   Zpreserve_mode)r   target_pathr   r   Z
ensure_dirrL   rM   rh   r   Z
write_filer   r   Z_render_persistent_net)r   r   r   targetZfpeniheaderZnetrulesr'   r'   r(   render_network_state(  s    zRenderer.render_network_state)N)r]   )F)F)NN)__name__
__module____qualname____doc__r   r   r   r   r   r   dictr   r'   r'   r'   r(   r   g  s   
	
4
M
7 
r   c             C   sF   d}t ||d dd}|sd}|jds0|d7 }|j| |d}|| S )Nzetc/network/interfaces)r   r   r   )r   r]   r   )rF   )r   endswithr   )r   r   rF   r   r   ro   r'   r'   r(   network_state_to_eni=  s    

r   c             C   sT   dddg}ddg}x |D ]}t j||| dsdS qW t j| d}tjj|sPdS d	S )
NZifqueryZifupZifdownz/sbinz	/usr/sbin)r[   r   Fzetc/network/interfacesT)r   Zwhichr   rL   rM   rN   )r   Zexpectedr[   pZenir'   r'   r(   	availableQ  s    

r   )F)NF)N)rD   rb   ZloggingrL   rO   Ztypingr   Z	cloudinitr   r   Zcloudinit.netr   r   r   Zcloudinit.net.network_stater   Z	getLoggerr   r:   rj   rk   ri   r)   r?   rH   rg   rw   rv   r   r   r   r'   r'   r'   r(   <module>   sr   
<
 ) W
