o
    w7e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 ](}||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rC|| j | vrg | 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 ]e\}}|sq	|dkr.t |D ]}|d| d 7 }||d 7 }|d7 }qq	|dkrUt |D ]}|d| d 7 }t || D ]}||d 7 }|d7 }qFq6q	|d| d 7 }t |D ]}||d 7 }qa|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defddZdefdd	Zdefd
dZdefddZ	defddZ
dedefddZdefddZdd Z		ddedee ddfddZdedef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 ]\}}||v r%|| r%|||||  q|d S )Nr
   NameDriver
MACAddress)namedrivermac_addressr<   )r*   r#   )r   ifacer8   r   
match_dictr"   r,   r   r   r   generate_match_sectionf   s   zRenderer.generate_match_sectionc                 C   s:   d}|sd S d|v r|d r| |d|d  d S d S d S )Nr   mtu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|v rdt |d  }| D ]\}}||vr#q|d	kr+||7 }||||| | qd
S )zy
        Parse a route and use rid as a key in order to isolate the route from
        others in the route dict.
        r   GatewayDestinationMetric)gatewaynetworkmetricr&   prefix/rI   N)r   r*   r%   )	r   r$   confr8   r   route_cfg_maprK   r"   r,   r   r   r   parse_routes   s   zRenderer.parse_routesc              	   C   s  d}d}d}| dg D ]}|d }|dks|dkr(|dkr!d}n|d	kr'd
}n|dkr9|dkr3d	}n|dkr9d
}d|v rV|d rV|d D ]}| d| || |d }qEd|v rddddd}	| D ]J\}
}|
dkrd|v r{|dt|d  7 }|d|	|
 | qe|
dkr|dd| |	|
 | |d }qe|
dks|
dkr|||	|
 d| qeq||d| |dv rt| dd tr||d!|d  |S )"Nnor   r   subnetstypedhcp4dhcpipv4ipv6yesdhcp6routesr   addressr   rE   DNSDomains)r\   rH   dns_nameservers
dns_searchrK   rL   rH   r   ar_   r`    DHCP)rV   rW   z	accept-rar&   IPv6AcceptRA)	r6   rO   r*   r   r#   r%   join
isinstancebool)r   r?   r8   rT   r   r$   r-   tisubnet_cfg_mapr"   r,   r   r   r   parse_subnets   sZ   


zRenderer.parse_subnetsc              	   C   s   dD ]B}||vr	qt ||  }zt|}|rdnd}W n ty3   |dkr1td| d}Y nw |dkr;d}nd}||d	| qd S )
N)dhcp4domaindhcp6domainrW   rP   routezInvalid dhcp4domain value - %srl   r   r   
UseDomains)r   casefoldr   translate_bool
ValueErrorLOGwarningr#   )r   dr8   itemretsectionr   r   r   dhcp_domain   s$   
zRenderer.dhcp_domainnsc           	   	   C   s   d}dddd}| d}|s|jdkr|j|jd}n	|s%|jdkr%d S | D ]\}}||v rA|| rA|||d	||  q)d S )
Nr   r^   r]   )searchnameservers	addressesdnsr[   )r{   r|      rb   )r6   versiondns_searchdomainsr_   r*   r#   re   )	r   r?   r8   rz   r   dns_cfg_mapr~   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|v rH|dd| fv rJ|d| d }| D ]\}}||v rG|d| |||  q3d S d S d S )Nzuse-dnsuse-domainszuse-hostnamezuse-ntp)UseDNSro   UseHostnameUseNTP4zsend-hostnamehostnamezroute-metriczuse-mtuz
use-routes)SendHostnameHostnameRouteMetricUseMTU	UseRoutesrT   
-overridesrW   ipvDHCPv)updater*   r#   )	r   r8   devicerT   r   dhcp_config_mapsdhcp_overridesr"   r,   r   r   r   parse_dhcp_overrides   s2   
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)rs   debugr   
write_filechownbyname)r   linkrM   nwk_dirnet_fn_ownernet_fnr   r   r   create_network_file  s
   zRenderer.create_network_filenetwork_state	templatesreturnc                 C   sP   | j }|rt|| }t| | |}| D ]\}}| ||| qd S N)r5   r   target_pathr   
ensure_dir_render_contentr*   r   )r   r   r   targetnetwork_dirret_dictr"   r,   r   r   r   render_network_state  s   

zRenderer.render_network_statec                 C   s^  i }|  D ]}t }| ||}| || | ||}| ||| d}| D ]}| d| || |d }q*|jdkr|d }	|j	d 
 D ]\}
}d|v r^|d|	kr^|
}	 nqK|	|j	d v r|j	d |	 }| || dD ]-}d	| d
|v rd|d	| di v r|	 d| d| d}t|| |||| qu||| i q|S )Nr   cr[   r   r<   	ethernetszset-name)r   6rT   domainr   r   z has both dhcpzdomain and dhcpz*-overrides.use-domains configured. Use one)iter_interfacesr	   rA   rD   rk   r   iter_routesrO   r   r7   r*   r6   ry   RuntimeErrorr   r   r/   )r   rz   r   r?   r8   r   rT   r$   rn   r<   dev_namedev_cfgr   r   	exceptionr   r   r   r   +  sF   


zRenderer._render_contentr   )NN)r0   r1   r2   __doc__r   r	   rA   rD   rO   rk   ry   r   r   r   r   r   r   r   r   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 )Nip	systemctlz	/usr/sbinz/bin)r{   r   FT)r   which)r   expectedr{   pr   r   r   	availablef  s   r   r   )collectionsr   typingr   	cloudinitr   loggingr   r   cloudinit.netr   cloudinit.net.network_stater   	getLoggerr0   rs   r	   r3   r   r   r   r   r   <module>   s   	
?  