U
    Ad2                     @   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edddZdS )    )OrderedDict)Optional)log)subputil)renderer)NetworkStatec                   @   s4   e Zd Zd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_confc                 C   s6   |st d d S |  }t d| t|| d S )NzTarget file not givenzFinal content: %s)LOGwarningr/   debugr   
write_file)r   Z	target_fnr+   r   r   r   	dump_dataS   s    
zCfgParser.dump_dataN)__name__
__module____qualname__r   r#   r%   r/   r4   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/)getr9   r:   )r   configr   r   r   r   e   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   ifacer=   r   Z
match_dictr"   r,   r   r   r   generate_match_sectiono   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@   r=   r   r   r   r   generate_link_section   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/rE   N)r   r*   r%   )	r   r$   confr=   r   Zroute_cfg_maprF   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   rC   DNSDomains)rQ   rD   dns_nameservers
dns_searchrF   rG   rD   r   arT   rU    ZDHCP)rM   rN   z	accept-rar&   ZIPv6AcceptRA)	r;   rI   r*   r   r#   r%   join
isinstancebool)r   r@   r=   rL   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dhcp6domainrN   rJ   routezInvalid dhcp4domain value - %sr^   r   r   
UseDomains)r   casefoldr   Ztranslate_bool
ValueErrorr0   r1   r#   )r   dr=   itemZretZsectionr   r   r   dhcp_domain   s    

zRenderer.dhcp_domain)r=   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   rS   rR   )searchnameserversZ	addressesdnsrP   )rg   rh      rW   )r;   versionZdns_searchdomainsrT   r*   r#   rX   )	r   r@   r=   rf   r   Zdns_cfg_mapri   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	UseRoutesrL   
-overridesrN   ZipvZDHCPv)updater*   r#   )	r   r=   devicerL   rk   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)r0   r2   r   r3   Zchownbyname)r   linkrH   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)r:   r   Ztarget_pathr   Z
ensure_dir_render_contentr*   rt   )r   ru   rv   targetZnetwork_dirret_dictr"   r,   r   r   r   render_network_state$  s    

zRenderer.render_network_state)rf   rw   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   crP   rj   r?   Z	ethernetszset-name)rn   6rL   Zdomainrm   ro   z has both dhcpzdomain and dhcpz*-overrides.use-domains configured. Use one)Ziter_interfacesr	   rA   rB   r]   rl   Ziter_routesrI   rk   r<   r*   r;   re   	Exceptionrr   rp   r/   )r   rf   r{   r@   r=   rs   rL   r$   r_   r?   Zdev_nameZdev_cfgrq   rk   Z	exceptionr   r   r   ry   4  sD    

zRenderer._render_content)N)NN)r5   r6   r7   __doc__r   r	   rA   rB   rI   r]   re   r   rl   rr   rt   r   r   r|   ry   r   r   r   r   r8   ]   s$   

	6  r8   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)rg   rz   FT)r   Zwhich)rz   Zexpectedrg   pr   r   r   	availableo  s    r   )rf   c                 C   s   t i }|| S rx   )r8   ry   )rf   r   r   r   r   network_state_to_networkdx  s    r   )N)collectionsr   typingr   Z	cloudinitr   Zloggingr   r   Zcloudinit.netr   Zcloudinit.net.network_stater   Z	getLoggerr5   r0   r	   r8   r   r   r   r   r   r   <module>
   s   
H  
	