U
    w7e`7                     @   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	 d dlm
Z
mZ d dlmZmZmZ d dlmZ dZdZd	Zd
Ze	eZG dd dZG dd dejZdddZdddZdddZdS )    N)Optional)log)subputil)is_ipv6_addressrenderersubnet_is_ipv6)NetworkStatez/etc/NetworkManagerz/usr/lib/NetworkManagerz'/etc/NetworkManager/NetworkManager.confz# This is generated by cloud-init. Do not edit.
#
[.config]
  enable=nm-version-min:1.40
[connection.30-cloud-init-ip6-addr-gen-mode]
  # Select EUI64 to be used if the profile does not specify it.
  ipv6.addr-gen-mode=0

c                   @   s|   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zedd Zdd Zdd ZdS )NMConnectionz/Represents a NetworkManager connection profile.c                 C   sR   t d}t | _t| j_d| tt ||dd| jd< ddi| jd< d	S )
z
        Initializes the connection with some very basic properties,
        notably the UUID so that the connection can be referred to.
        z$a3924cb8-09e0-43e9-890b-77972a800108zcloud-init Z120)iduuidzautoconnect-priority
connectionz%org.freedesktop.NetworkManager.originz
cloud-inituserN)r   ZUUIDconfigparserConfigParserconfigstrZoptionxformZuuid5)selfcon_idZ
CI_NM_UUID r   ?/usr/lib/python3/dist-packages/cloudinit/net/network_manager.py__init__'   s    

 zNMConnection.__init__c                 C   s6   | j |si | j |< | j ||s2|| j | |< dS )z_
        Sets a property unless it's already set, ensuring the section
        exists.
        N)r   Zhas_section
has_option)r   sectionZoptionvaluer   r   r   _set_default?   s    
zNMConnection._set_defaultc              	   C   s   ddddddddd}|  |dd z|| }W n& tk
rV   d}d| j| d< Y nX | j| d dkrnd	S | j| d dkr|dkrd	S || j| d< |  |dd
 d	S )z}
        Ensures there's appropriate [ipv4]/[ipv6] for given family
        appropriate for given configuration type
        Zmanualautodhcp)ZstaticZstatic6Zdhcp6Z
ipv6_slaaczipv6_dhcpv6-statelesszipv6_dhcpv6-statefulZdhcp4r   methoddisabledtruezmay-failNfalse)r   KeyErrorr   )r   familyZsubnet_typeZ
method_mapr   r   r   r   _set_ip_methodJ   s*    zNMConnection._set_ip_methodc                 C   s@   t dD ]0}| | }| j||s
|| j| |<  q<q
dS )z
        Adds a numbered property, such as address<n> or route<n>, ensuring
        the appropriate value gets used for <n>.
           N)	itertoolscountr   r   )r   r   Z
key_prefixr   indexkeyr   r   r   _add_numberedo   s
    zNMConnection._add_numberedc                 C   s*   |d d t |d  }| |d| dS )z5
        Adds an ipv[46]address<n> property.
        address/prefixNr   r*   )r   r#   subnetr   r   r   r   _add_address{   s    zNMConnection._add_addressc                 C   sB   |d d t |d  }d|kr0|d |d  }| |d| dS )z3
        Adds a ipv[46].route<n> property.
        Znetworkr,   r-   gateway,routeNr.   )r   r#   r3   r   r   r   r   
_add_route   s    zNMConnection._add_routec                 C   sP   t |rdnd}| |dd | |dd | j| d | d | j| d< dS )	zF
        Extends the ipv[46].dns property with a name server.
        ipv6ipv4r   r   dns ;N)r   r   r   )r   r7   r#   r   r   r   _add_nameserver   s    	zNMConnection._add_nameserverc                 C   s8   |  |dd | j| d d| d | j| d< dS )zM
        Extends the ipv[46].dns-search property with a name server.
        z
dns-searchr8   r9   N)r   r   join)r   r#   
dns_searchr   r   r   _add_dns_search   s    zNMConnection._add_dns_searchc                 C   s   | j d d S )z-
        Returns the connection UUID
        r   r   )r   r   r   r   r   con_uuid   s    zNMConnection.con_uuidc                 C   s   | j ddS )zN
        Can this be serialized into a meaningful connection profile?
        r   type)r   r   r>   r   r   r   valid   s    zNMConnection.validc                 C   s   |  dd S )z)
        Sanitize a MAC address.
        -:)replaceupper)Zaddrr   r   r   mac_addr   s    zNMConnection.mac_addrc              
   C   s  ddddddd}||d  }|dkr*dS d	|kr8d}nd}|| j d
 d< |dk	r||| j d
 d< |||d  | j d
 d< i | j |< dddddddddd	dddddii i d}|d }d}|d D ]}	t|	rd nd!}
| |
|	d  d"|	kr| |
|	 d#|	kr|	d# | j |
 d#< |	d$ D ]}| |
| q&d%|	kr^|	d% D ]}| | qLd&|	krx| |
|	d&  |
d!krd|	kr|	d }q|dkr|}||kst	d'|d( || || 
 D ]n\}}||krq|| dkrqt|| tr || rd)nd*| j | |< nt|| | j | |< q|dkr|d+ d,krdtd-| j d d.< |dk	rt|| j d d< |d/ dk	r| |d/ | j d d0< |dkrd1|kr||d1 | j d d2< |dkr<|d3 D ]0}||}|d
dd |d
d|   q|d/ dk	r<| |d/ | j d d0< |dkr|dk	rd4| j d d5< t|| j d d< |d/ dk	r| |d/ | j d d0< |dks| j |d0s|d( | j d
 d6< dS )7z
        Integrate information from network state interface information
        into the connection. Most of the work is done here.
        ethernetvlanbondbridge
infinibandN)ZphysicalrH   rI   rJ   rK   Zloopbackr@   zbond-masterr   z
slave-typez-masterZmasterz	bond-modeZbond_miimonzbond-xmit-hash-policyzbond-num-grat-arpzbond-downdelayzbond-updelayzbond-fail-over-maczbond-primary-reselectzbond-primary)	modeZmiimonZxmit_hash_policyZnum_grat_arpZ	downdelayZupdelayZfail_over_macZprimary_reselectZprimaryZ
bridge_stpZbridge_bridgeprio)ZstpZpriorityr   Zvlan_id)rI   rJ   rH   rG   rK   ZmtuZsubnetsr5   r6   r+   r1   ZroutesZdns_nameserversr<   zZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.namer    r!   Z	wakeonlanT@   zwake-on-lanZmac_addresszmac-addresszvlan-raw-deviceparentZbridge_portsZdatagramztransport-modezinterface-name)r   con_refr   r$   r0   r4   r:   r=   LOGZwarningitems
isinstanceboolr   rF   get_connr   r?   r   )r   ifacer   Z	_type_mapZif_typeZ
slave_typeZ	_prop_mapZ
device_mtuZipv4_mtur/   r#   r3   Z
nameserverZnm_propr)   Zportr   r   r   render_interface   s    	

 






	




 zNMConnection.render_interfacec                 C   s(   t  }| jj|dd d}||  S )z
        Stringify.
        F)Zspace_around_delimitersz2# Generated by cloud-init. Changes will be lost.

)ioStringIOr   writegetvalue)r   Zbufheaderr   r   r   dumpI  s    zNMConnection.dumpN)__name__
__module____qualname____doc__r   r   r$   r*   r0   r4   r:   r=   r?   rA   staticmethodrF   rW   r]   r   r   r   r   r
   $   s    %


 r
   c                   @   sB   e Zd ZdZdddZdd Zdd Zdeee	 dd	d
dZ
dS )Rendererz?Renders network information in a NetworkManager keyfile format.Nc                 C   s
   i | _ d S Nconnections)r   r   r   r   r   r   W  s    zRenderer.__init__c                 C   s
   | j | S rd   re   r   r   r   r   r   rU   Z  s    zRenderer.get_connc                 C   s    || j kr| j |  S |S d S rd   )rf   r?   rg   r   r   r   rP   ]  s    
zRenderer.con_ref)network_state	templatesreturnc                 C   s   |  D ]}t|d | j|d < q|  D ]}| j|d  }|||  q,| j D ].\}}| shqVt||}t||	 d qVtt
|td d S )NrM   i  )Ziter_interfacesr
   rf   rW   rR   rA   conn_filenamer   Z
write_filer]   cloud_init_nm_conf_filenameNM_IPV6_ADDR_GEN_CONF)r   rh   ri   targetrV   Zconnr   rM   r   r   r   render_network_stated  s    	
  zRenderer.render_network_state)N)NN)r^   r_   r`   ra   r   rU   rP   r	   r   dictro   r   r   r   r   rc   T  s   

  rc   c                 C   s&   t |t}d|  d}| d| S )Nzcloud-init-z.nmconnectionz/system-connections/r   target_path
NM_RUN_DIR)r   rn   target_con_dirZcon_filer   r   r   rk     s    rk   c                 C   s   t | t}d}| d| S )Nz$30-cloud-init-ip6-addr-gen-mode.confz/conf.d/rq   )rn   rt   Z	conf_filer   r   r   rl     s    rl   c                 C   sz   ddl m} tjtj| td}tjd| d}d}| rjztddd	g W n tj	k
rh   d
}Y nX |oxt
|ox|S )Nr   )uses_systemd)pathZnmcli)rn   TZ	systemctlz
is-enabledzNetworkManager.serviceF)Zcloudinit.distrosru   osrv   isfiler   rr   NM_CFG_FILEZwhichZProcessExecutionErrorrT   )rn   ru   Zconfig_presentZnmcli_presentZservice_activer   r   r   	available  s    
rz   )N)N)N)r   rX   r&   rw   r   typingr   Z	cloudinitr   Zloggingr   r   Zcloudinit.netr   r   r   Zcloudinit.net.network_stater	   rs   Z
NM_LIB_DIRry   rm   Z	getLoggerr^   rQ   r
   rc   rk   rl   rz   r   r   r   r   <module>	   s*   	
  2/

