o
    f2                     @   s   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
 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 )    N)OrderedDict)Optional)subputil)renderershould_add_gateway_onlink_flag)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 }qF|d7 }q6q	|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_conf8   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   Y   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_sectionc   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_sectiont   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 r|d }	d|v rl|	dt|d  7 }	ddddd}
| D ]S\}}|dkr|d|
| |	 qw|dkr|dd| |
| | t||	rtd||	 |dd| dd
 |d }qw|dks|dkr|||
| d	| qwq||d| t
| d d!tr||d"|d   |S )#Nnor   r   subnetstypedhcp4dhcpipv4ipv6yesdhcp6routesr   addressrK   rL   r   rE   DNSDomains)r\   rH   dns_nameservers
dns_searchrH   r   azGGateway %s is not contained within subnet %s, adding GatewayOnLink flagGatewayOnLinkr_   r`    DHCPz	accept-rar&   IPv6AcceptRA)r6   rO   r   r*   r#   r%   r   LOGdebugjoin
isinstancebool)r   r?   r8   rT   r   r$   r-   tiaddrsubnet_cfg_mapr"   r,   r   r   r   parse_subnets   sj   


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 - %srp   r   r   
UseDomains)r   casefoldr   translate_bool
ValueErrorrf   warningr#   )r   dr8   itemretsectionr   r   r   dhcp_domain   s$   
zRenderer.dhcp_domainnsc                 C   s   d}| d}|s|jdkr|j|jd}n	|s|jdkrd S | dr0||dd|d  | d	rC||d
d|d	  d S d S )Nr   dnsr[   )searchnameservers   r   r^   rc   r   r]   )r6   versiondns_searchdomainsr_   r#   rh   )r   r?   r8   r}   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)UseDNSrs   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)rf   rg   r   
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   ro   r   iter_routesrO   r   r7   r*   r6   r|   RuntimeErrorr   r   r/   )r   r}   r   r?   r8   r   rT   r$   rr   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   ro   r|   r   r   r   r   r   r   r   r   r   r   r   r   r3   Q   s*    

	?
r3   c                 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   	availableg  s   r   r   )loggingcollectionsr   typingr   	cloudinitr   r   cloudinit.netr   r   cloudinit.net.network_stater   	getLoggerr0   rf   r	   r3   r   r   r   r   r   <module>   s   
?  