U
    Ld1                     @   s   d dl mZ d dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZ eeZG dd dZG d	d
 d
e
jZdddZdS )    )OrderedDict)Optional)log)subputil)renderer)NetworkStatec                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
	CfgParserc              	   C   s   t g g g g g g i d| _d S )N)MatchLinkNetworkDHCPv4DHCPv6AddressRoute)r   	conf_dict)self r   8/usr/lib/python3/dist-packages/cloudinit/net/networkd.py__init__   s    zCfgParser.__init__c                 C   s`   | j  D ]P}||kr
| j | |d t|  tt| j | | j |< | j |   q
d S )N=r   keysappendstrlistdictfromkeyssort)r   seckeyvalkr   r   r   update_section#   s
    zCfgParser.update_sectionc                 C   s   | j  D ]|}||kr
|| j | kr2g | j | |< | j | | |d t|  tt| j | | | j | |< | j | |   q
dS )z
        For each route section we use rid as a key, this allows us to isolate
        this route from others on subsequent calls.
        r   Nr   )r   r   ridr    r!   r"   r   r   r   update_route_section+   s     zCfgParser.update_route_sectionc                 C   s   d}t | j D ]\}}|s q|dkr\t |D ](}|d| d 7 }||d 7 }|d7 }q0q|dkrt |D ]:}|d| d 7 }t || D ]}||d 7 }|d7 }qqlq|d| d 7 }t |D ]}||d 7 }q|d7 }q|S )N r   [z]

r   )sortedr   items)r   contentsr"   venr   r   r   get_final_conf;   s(    
zCfgParser.get_final_confN)__name__
__module____qualname__r   r#   r%   r/   r   r   r   r   r	      s   r	   c                   @   s   e Zd ZdZdddZedddZeddd	Zedd
dZedddZ	edddZ
eedddZedddZdd Zdeee ddddZeedddZdS )Rendererz
    Renders network information in /etc/systemd/network

    This Renderer is currently experimental and doesn't support all the
    use cases supported by the other renderers yet.
    Nc                 C   s(   |si }| dd| _| dd| _d S )Nresolve_conf_fnz/etc/systemd/resolved.confnetwork_conf_dirz/etc/systemd/network/)getr4   r5   )r   configr   r   r   r   \   s      zRenderer.__init__)cfgc                 C   sT   d}dddd}|sd S |  D ]*\}}||kr || r |||||  q |d S )Nr
   NameZDriverZ
MACAddress)nameZdriverZmac_addressr:   )r*   r#   )r   ifacer8   r   Z
match_dictr"   r,   r   r   r   generate_match_sectionf   s    zRenderer.generate_match_sectionc                 C   s2   d}|sd S d|kr.|d r.| |d|d  d S )Nr   ZmtuZMTUBytes)r#   )r   r;   r8   r   r   r   r   generate_link_sectionw   s
    zRenderer.generate_link_sectionc           	      C   sp   d}dddd}d}d|kr,dt |d  }| D ]6\}}||krFq4|d	krV||7 }||||| | q4d
S )zy
        Parse a route and use rid as a key in order to isolate the route from
        others in the route dict.
        r   GatewayZDestinationZMetric)gatewaynetworkZmetricr&   prefix/r@   N)r   r*   r%   )	r   r$   confr8   r   Zroute_cfg_maprA   r"   r,   r   r   r   parse_routes   s    zRenderer.parse_routesc              	   C   s  d}d}d}| dg D ]N}|d }|dks6|dkrR|dkrDd}qt|d	krtd
}n"|dkrt|dkrhd	}n|dkrtd
}d|kr|d r|d D ] }| d| || |d }qd|krddddd}	| D ]\}
}|
dkrd|kr|dt|d  7 }|d|	|
 | q|
dkr<|dd| |	|
 | |d }q|
dksN|
dkr|||	|
 d| qq||d| |dkrt| dd tr||d!|d  |S )"Nnor   r   ZsubnetstypeZdhcp4dhcpZipv4ipv6yesZdhcp6Zroutesr   addressr   r>   DNSDomains)rL   r?   dns_nameservers
dns_searchrA   rB   r?   r   arO   rP    ZDHCP)rH   rI   z	accept-rar&   ZIPv6AcceptRA)	r6   rD   r*   r   r#   r%   join
isinstancebool)r   r;   r8   rG   r   r$   r-   tiZsubnet_cfg_mapr"   r,   r   r   r   parse_subnets   s^    


   

 zRenderer.parse_subnetsc              	   C   s   dD ]}||krqt ||  }zt|}|r6dnd}W n, tk
rh   |dkrdtd| d}Y nX |dkrxd}nd}||d	| qd S )
N)dhcp4domainZdhcp6domainrI   rE   routezInvalid dhcp4domain value - %srY   r   r   
UseDomains)r   casefoldr   Ztranslate_bool
ValueErrorLOGZwarningr#   )r   dr8   itemZretZsectionr   r   r   dhcp_domain   s    

zRenderer.dhcp_domain)r8   nsc           	   	   C   s   d}dddd}| d}|s8|jdkr8|j|jd}n|sJ|jdkrJd S | D ]0\}}||krR|| rR|||d	||  qRd S )
Nr   rN   rM   )searchnameserversZ	addressesdnsrK   )rc   rd      rR   )r6   versionZdns_searchdomainsrO   r*   r#   rS   )	r   r;   r8   rb   r   Zdns_cfg_mapre   r"   r,   r   r   r   	parse_dns   s    
zRenderer.parse_dnsc           	      C   s   ddddd}|dkr,| ddd	d
dd d| d|kr|dd| fkr|d| d }| D ](\}}||krf|d| |||  qfd S )Nzuse-dnsuse-domainszuse-hostnamezuse-ntp)ZUseDNSr[   ZUseHostnameZUseNTP4zsend-hostnameZhostnamezroute-metriczuse-mtuz
use-routes)ZSendHostnameZHostnameZRouteMetricZUseMTUZ	UseRoutesrG   
-overridesrI   ZipvZDHCPv)updater*   r#   )	r   r8   devicerG   rg   Zdhcp_config_mapsZdhcp_overridesr"   r,   r   r   r   parse_dhcp_overrides   s,    
zRenderer.parse_dhcp_overridesc                 C   s>   d}t d| |d | d }t|| t||| d S )Nzsystemd-networkz Setting Networking Config for %sz10-cloud-init-z.network)r^   debugr   Z
write_fileZchownbyname)r   linkrC   Znwk_dirZnet_fn_ownerZnet_fnr   r   r   create_network_file  s
    zRenderer.create_network_file)network_state	templatesreturnc                 C   sP   | j }|rt|| }t| | |}| D ]\}}| ||| q4d S )N)r5   r   Ztarget_pathr   Z
ensure_dir_render_contentr*   rq   )r   rr   rs   targetZnetwork_dirret_dictr"   r,   r   r   r   render_network_state  s    

zRenderer.render_network_state)rb   rt   c                 C   sh  i }|  D ]T}t }| ||}| || | ||}| ||| d}| D ] }| d| || |d }qV|jdkrP|d }	|j	d 
 D ]&\}
}d|kr|d|	kr|
}	 qq|	|j	d krP|j	d |	 }| || dD ]^}d	| d
|kr>d|d	| di kr>|	 d| d| d}t|| |||| q||| i q|S )Nr   crK   rf   r:   Z	ethernetszset-name)rj   6rG   Zdomainri   rk   z has both dhcpzdomain and dhcpz*-overrides.use-domains configured. Use one)Ziter_interfacesr	   r<   r=   rX   rh   Ziter_routesrD   rg   r7   r*   r6   ra   RuntimeErrorrn   rl   r/   )r   rb   rw   r;   r8   rp   rG   r$   rZ   r:   Zdev_nameZdev_cfgrm   rg   Z	exceptionr   r   r   ru   +  sD    

zRenderer._render_content)N)NN)r0   r1   r2   __doc__r   r	   r<   r=   rD   rX   ra   r   rh   rn   rq   r   r   rx   ru   r   r   r   r   r3   T   s$   

	6  r3   Nc                 C   s4   ddg}ddg}|D ]}t j||| ds dS qdS )NZipZ	systemctlz	/usr/sbinz/bin)rc   rv   FT)r   Zwhich)rv   Zexpectedrc   pr   r   r   	availablef  s    r~   )N)collectionsr   typingr   Z	cloudinitr   Zloggingr   r   Zcloudinit.netr   Zcloudinit.net.network_stater   Z	getLoggerr0   r^   r	   r3   r~   r   r   r   r   <module>
   s   
?  