U
    Ld                     @   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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mZmZmZmZ d dlmZ e
eZdd	d
dddddddddddgZd-ddZdd Zdd ZG dd dZG dd  d eZ G d!d" d"eZ!G d#d$ d$ej"Z"d%d& Z#d.d'd(Z$d/d)d*Z%d0d+d,Z&dS )1    N)MappingOptional)log)subputil)networkmanager_confresolv_conf)IPV6_DYNAMIC_TYPESis_ipv6_addressnet_prefix_to_ipv4_maskrenderersubnet_is_ipv6)NetworkStateZ	almalinuxZcentosZ
cloudlinuxZ	eurolinuxZfedoraZmiraclelinuxZ	openeulerZOpenCloudOSZopenmandrivarhelZrockysuseZ	TencentOSZ	virtuozzo#c                 C   sL   ddg}t dt|D ]*}|| r8| d ||  ||< q| ||< qd|S )NzBCreated by cloud-init on instance boot automatically, do not edit. r    
)rangelenjoin)seplinesi r   9/usr/lib/python3/dist-packages/cloudinit/net/sysconfig.py_make_header)   s    
r   c                 C   s   d}| d dko| d |kS )N)z::z0.0.0.0prefixr   networkr   )routeZdefault_netsr   r   r   _is_default_route6   s    r!   c                 C   s6   t d| r.| dr$| dr$| S d|  S n| S d S )Nz\s"z"%s")research
startswithendswith)valuer   r   r   _quote_value;   s
    
r(   c                   @   sj   e Zd ZdZd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dd ZdS )	ConfigMapz!Sysconfig like dictionary object.yesZno)TFc                 C   s
   i | _ d S N_confselfr   r   r   __init__O   s    zConfigMap.__init__c                 C   s   || j |< d S r+   r,   )r/   keyr'   r   r   r   __setitem__R   s    zConfigMap.__setitem__c                 C   s
   | j | S r+   r,   r/   r1   r   r   r   __getitem__U   s    zConfigMap.__getitem__c                 C   s   | j |S r+   )r-   getr3   r   r   r   r5   X   s    zConfigMap.getc                 C   s
   || j kS r+   r,   r3   r   r   r   __contains__[   s    zConfigMap.__contains__c                 C   s   | j |d  d S r+   )r-   popr3   r   r   r   drop^   s    zConfigMap.dropc                 C   s
   t | jS r+   )r   r-   r.   r   r   r   __len__a   s    zConfigMap.__len__c                 C   s   dS )z6Skip the pair key, value if it matches a certain rule.Fr   r/   r1   valr   r   r   skip_key_valued   s    zConfigMap.skip_key_valuec                 C   s   t  }|t  | jr$|d t| j D ]X}| j| }| ||rNq2t|t	rb| j
| }t|tstt|}|d|t|f  q2| S )Nr   %s=%s
)ioStringIOwriter   r-   sortedkeysr<   
isinstancebool	_bool_mapstrr(   getvalue)r/   bufr1   r'   r   r   r   	to_stringh   s    




zConfigMap.to_stringc                 C   s   | j | d S r+   )r-   update)r/   Zupdatesr   r   r   rJ   x   s    zConfigMap.updateN)__name__
__module____qualname____doc__rE   r0   r2   r4   r5   r6   r8   r9   r<   rI   rJ   r   r   r   r   r)   F   s   r)   c                       sR   e Zd ZdZ fddZdd Zedd Zedd	 Zd
d Z	dddZ
  ZS )Routez!Represents a route configuration.c                    s<   t t|   d| _d| _d| _|| _|| _|| _|| _	d S )N   F)
superrO   r0   last_idxhas_set_default_ipv4has_set_default_ipv6_route_name_base_sysconf_dirroute_fn_tpl_ipv4route_fn_tpl_ipv6)r/   Z
route_namebase_sysconf_diripv4_tplipv6_tpl	__class__r   r   r0      s    zRoute.__init__c                 C   s>   t | j| j| j| j}| j |_| j|_| j|_| j	|_	|S r+   )
rO   rU   rV   rW   rX   r-   copyrR   rS   rT   )r/   rr   r   r   r^      s    z
Route.copyc                 C   s   | j | j| jd S N)basename)rW   rV   rU   r.   r   r   r   	path_ipv4   s    zRoute.path_ipv4c                 C   s   | j | j| jd S r`   )rX   rV   rU   r.   r   r   r   	path_ipv6   s    zRoute.path_ipv6c                 C   s   d|kS )N:r   )r/   addressr   r   r   is_ipv6_route   s    zRoute.is_ipv6_routeipv4c              	   C   s  |dkrt dt| t }|t  | jr<|d d}t| j D ]t}d|kr^qN|	dd}t| j| }t| jd|  }|dkrZ| 
|sZt| jd	|  }|d
 }|ddt| t|f  |ddt| t|f  |dd	t| t|f  d| }	|	| jkrt| jd|  }
|ddt| t|
f  qN|dkrN| 
|rNt| jd|  }d| | jkrdt| jd|   nd}
|d||||
| jf  qN| S )N)rh   ipv6zUnknown protocol '%s'r   ADDRESSr   GATEWAYrh   NETMASKrP   r=   METRICri   PREFIXzmetric z%s/%s via %s %s dev %s
)
ValueErrorrF   r>   r?   r@   r   r-   rA   rB   replacerg   r(   rU   rG   )r/   protorH   Zreindexr1   indexZaddress_valueZgateway_valueZnetmask_valueZ
metric_keyZmetric_valueZprefix_valuer   r   r   rI      sp    
zRoute.to_string)rh   )rK   rL   rM   rN   r0   r^   propertyrc   rd   rg   rI   __classcell__r   r   r\   r   rO   |   s   


rO   c                       s   e Zd ZdZddddddZd fd	d
	Zedd Zejdd Zedd Z	e	jdd Z	edd Z
dddZdd Z  ZS )NetInterfacezERepresents a sysconfig/networking-script (and its config + children).ZEthernetZBondZBridgeZ
InfiniBandVlan)ethernetbondbridge
infinibandvlanrx   c                    sr   t t|   g | _|| _| jd}t|||d|dd| _| jd| _|| _	|| _
|| jd< || _d S )Nroute_templatesrh   ri   )rZ   r[   iface_templatesDEVICE)rQ   rv   r0   children	templatesr5   rO   routesiface_fn_tplkind_iface_namer-   rV   )r/   
iface_namerY   r   r   Z	route_tplr\   r   r   r0      s    
zNetInterface.__init__c                 C   s   | j S r+   )r   r.   r   r   r   rb   	  s    zNetInterface.namec                 C   s   || _ || jd< d S )Nr   )r   r-   )r/   r   r   r   r   rb     s    c                 C   s   | j S r+   )_kindr.   r   r   r   r     s    zNetInterface.kindc                 C   s,   || j krt||| _| j | | jd< d S )NTYPE)iface_typesrp   r   r-   )r/   r   r   r   r   r     s    
c                 C   s   | j | j| jd S r`   )r   rV   rb   r.   r   r   r   path  s    zNetInterface.pathFc                 C   sH   t | j| j| j| jd}| j |_|r4t| j|_|rD| j	 |_	|S )N)r   )
rv   rb   rV   r   r   r-   r^   listr   r   )r/   Zcopy_childrenZcopy_routescr   r   r   r^   #  s       zNetInterface.copyc                 C   s   |dkr|dkrdS dS )Nr   rw   TFr   r:   r   r   r   r<   .  s    zNetInterface.skip_key_value)rx   )FF)rK   rL   rM   rN   r   r0   rt   rb   setterr   r   r^   r<   ru   r   r   r\   r   rv      s*   	 





rv   c                   @   s:  e Zd ZU dZddddddddd	Zd
ddddddddddddd	Zeddddddddddd d!d"d#d$gZi Ze	e
d%< dDd'd(Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Zed5d6 ZedEd7d8ZedFd9d:Zed;d< Zed=d> ZedGd?d@ZdHeee	 d&dAdBdCZd&S )IRendererz7Renders network information in a /etc/sysconfig format.TFnone)ONBOOTZUSERCTLZNM_CONTROLLED	BOOTPROTOstaticauto)r   	STARTMODE)r   r   IPV6_FORCE_ACCEPT_RAZSTPZAGEINGZPRIOZHWADDRMTU)	accept-ra
bridge_stpbridge_ageingbridge_bridgepriomac_addressmtu
BRIDGE_STPZBRIDGE_AGEINGTIMEZBRIDGE_PRIORITYLLADDR)r   r   r   r   r   )Z	bond_modezmode=%s)Zbond_xmit_hash_policyzxmit_hash_policy=%s)Zbond_miimonz	miimon=%s)Zbond_min_linkszmin_links=%s)Zbond_arp_intervalzarp_interval=%s)Zbond_arp_ip_targetzarp_ip_target=%s)Zbond_arp_validatezarp_validate=%s)Zbond_ad_selectzad_select=%s)Zbond_num_grat_arpznum_grat_arp=%s)Zbond_downdelayzdowndelay=%s)Zbond_updelayz
updelay=%s)Zbond_lacp_ratezlacp_rate=%s)Zbond_fail_over_maczfail_over_mac=%s)Zbond_primaryz
primary=%s)Zbond_primary_reselectzprimary_reselect=%sr   Nc                 C   sv   |si }| dd| _| dd| _| dd| _d}| d|| _| d	| d
| dd| _| dd| _d S )Nsysconf_dirzetc/sysconfignetrules_pathz(etc/udev/rules.d/70-persistent-net.rulesdns_pathzetc/resolv.confz,etc/NetworkManager/conf.d/99-cloud-init.confnetworkmanager_conf_pathcontrolr~   r}   )r   r~   r}   flavorr   )r5   r   r   r   r   r   r   )r/   Zconfignm_conf_pathr   r   r   r0   q  s$      zRenderer.__init__c                 C   s   t | j|i }|| dD ]H}||}|d k	r"|dkrN|d dkrNq"| j| |}|r"|||< q"d|kr|d r|d dkrd|d< d S )	N)r   r   r   r   type)physicalr{   Z	wakeonlanr   zwol gZETHTOOL_OPTS)r^   deepcopyiface_defaultsr5   rJ   cfg_key_maps)clsiface	iface_cfgr   Zflavor_defaultsold_key	old_valuenew_keyr   r   r   _render_iface_shared  s"    



zRenderer._render_iface_sharedc                 C   s|  |dkr,d|d< d|kr4d|d< | d nd|d< t|t|jdD ]\}}d}|d	}|d
ksn|dkr|dkr|d dkrd|d< nd
|d< d|d< nB|dkr|dkrd|d< d|d< d|d< d|d< nd|d< d|d< n|dkrF|dkr"|d dkrd|d< nd
|d< d|d< n d|d< d|d< d|d< d|d< n|dkr|dkr|d dkrrd|d< nd
|d< d|d< nd|d< d|d< nN|dkr|d }	d|d< |dkr|dkr|	d
krd|d< n
|dkrt|r|dkrd}d|d< d|kr~t||ko*|d || k}
|
rNtd|j	|| |d  t|rr|dkrdn|d ||< n|d ||< t|r|dkrd|d< d|d< nB|d kr|dkrt
d!| n||k|d"< ntd#||j	f |d$d krF|dkrd |d%< qFd|d"< qFd&}d&}t|t|jdD ]H\}}|d	}d'|kr`|dkr`|d' |d(< |d)kr|dkr,|r,|d dkr,d|d*< q,q,|tkrq,q,|dkr,t|rX|d+ }d,|d- |d. f }|d/kr|dkr||d0< n||d1< nT|d+kr*|dkr ||d2< n||d3< n,|dkrB||d4| < n|d3  d5| 7  < nB|d+ }|d/krnd6nt|}|d- |d7| < t|d. |d8| < d9|kr|dkrd|d:< t|d9 r|d9 |d;< n|d9 |d<< d=|kr|dkrd5|d= |d>< d?|kr,|dkr,t|d? d@krBt
dA|j	t|d?  t|d? d d@ d+D ]\}}||dBt| < qXq,d S )CNr   r   r   BRIDGEdhcpr   startr   r   Zdhcp6zipv6_dhcpv6-statefuldhcp4ZmanagedZDHCLIENT6_MODEr   TZDHCPV6CZIPV6INITFZIPV6_AUTOCONFzipv6_dhcpv6-statelessinfoz-SZDHCPV6C_OPTIONSZ
ipv6_slaac)r   r   )r   Zstatic6ZIPV6_MTUr   zZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.r   Zmanualz Unknown subnet type setting "%s"r   z1Unknown subnet type '%s' found for interface '%s'r   r   rj   metricrn   r   r   DHCLIENT_SET_DEFAULT_ROUTErP   z%s/%srf   r   r   ZIPADDR6ZIPV6ADDRZ	IPADDR6_1ZIPV6ADDR_SECONDARIESz
IPADDR6_%dr   r   ZIPADDRrm   gatewayDEFROUTEIPV6_DEFAULTGWrl   Z
dns_searchZDOMAINdns_nameservers   z6%s has %d entries in dns_nameservers. Only 3 are used.ZDNS)r8   	enumerater   r   r5   r   rD   LOGZwarningrb   debugrp   r	   rF   r   r
   r   )r   r   subnetshas_default_router   r   subnetZmtu_keysubnet_typeZbootproto_inZmtu_mismatchZ
ipv4_indexZ
ipv6_indexZ	ipv6_cidrZsuffkr   r   r   _render_subnets  s   










































zRenderer._render_subnetsc                 C   s@  |dkrd S t |t|jdD ]\}}|d}|dg D ]}|dpVt|d }	t|r|tkr|drx|js|dr|jrt	d|j
 d	|d
< |d dkrd	|d< d|kr|	r|d |d< d	|_n|d |d< d	|_d|kr|d |d< q>dD ]*\}
}|
|kr| |j }||
 ||< q| jd7  _q>qd S )Nr   r   r   r   ri   r   rh   z?Duplicate declaration of default route found for interface '%s'Tr   r   r   r   r   rl   r   rn   ))r   rl   )r   rn   )r   ro   )Znetmaskrm   )r   rk   rP   )r   r   r   r5   r
   r!   r	   rS   rT   rp   rb   rR   )r   r   	route_cfgr   r   _r   r   r    Zis_ipv6r   new_namer   r   r   r   _render_subnet_routesf  sR    
	zRenderer._render_subnet_routesc           	      C   s   g }| j D ]\\}}||ddg}|D ]>}||kr&|| }t|ttfrRd|}|||   q
q&q
|r|dkrd||d< nd||d< d S )Nr   -r   r   ZBONDING_MODULE_OPTSZBONDING_OPTS)bond_tpl_optsrq   rC   tupler   r   append)	r   r   r   r   Z	bond_optsZbond_keyZ	value_tplZ	bond_keysZ
bond_valuer   r   r   _render_bonding_opts  s    
zRenderer._render_bonding_optsc           
      C   s^   t j}||D ]H}|d }|dg }|| }|j}	| |||j| | ||	|| qd S )Nrb   r   )r   Zfilter_by_physicaliter_interfacesr5   r   r   r   r   )
r   network_stateiface_contentsr   Zphysical_filterr   r   iface_subnetsr   r   r   r   r   _render_physical_interfaces  s$       z$Renderer._render_physical_interfacesc                    sd  t d}t d}||D ]>}|d  |  }| ||| |g}||j |D ]}	d|	d< |dkrXd|	_qX|dr|dkr|d|d< n|d|d	< |d
g }
|j	}| 
||
|j| | |||
| t fdd||D }t|D ]`\}}|dkrd| }nd| }|||< || }|dkrLd|d< d|d< q |d< d|d< qqd S )Nry   bond-masterrb   TZBONDING_MASTERr   r   r   MACADDRr   c                    s    g | ]}|d   kr|d qS )r   rb   r   ).0Zslave_ifacer   r   r   
<listcomp>  s   z4Renderer._render_bond_interfaces.<locals>.<listcomp>zBONDING_SLAVE_%szBONDING_SLAVE%sr   r   Zhotplugr   ZMASTERZSLAVE)r   filter_by_typeZfilter_by_attrr   r   extendr   r   r5   r   r   r   r   rA   r   )r   r   r   r   Zbond_filterZslave_filterr   r   Zmaster_cfgsZ
master_cfgr   r   Zbond_slavesrs   Z
bond_slaveZslavestrZ	slave_cfgr   r   r   _render_bond_interfaces  s`    


   





z Renderer._render_bond_interfacesc              	   C   s   t d}||D ]}|d }|| }|dkr^|d}|rF||d< |d |d |d< nJd|d	< d|_|d
 }	t|	|d }
||
krtd||	d	|
 |	|d< |dg }|j
}| |||j| | |||| qd S )Nr|   rb   r   vlan_idZVLAN_ID.ZETHERDEVICETZVLANzvlan-raw-devicezIName '%s' for vlan '%s' is not officially supportedby RHEL. Supported: %sr   ZPHYSDEVr   )r   r   r   r5   rfindr   _supported_vlan_namesr   r   r   r   r   r   r   )r   r   r   r   Zvlan_filterr   r   r   r   rdevZ	supportedr   r   r   r   r   _render_vlan_interfaces  sF    

   z Renderer._render_vlan_interfacesc                 C   s   t t| jt| jgsd S td}|rFtj|rFtt	
|}| jD ]}|| qL| jD ]}|| qbtd}t|}||s|d | }|S )Nr   ;r   )anyr   r   Zdns_searchdomainsr   Z
ResolvConfosr   isfiler   Z	load_fileZadd_nameserverZadd_search_domainr   rF   r%   )r   existing_dns_pathcontentZ
nameserverZsearchdomainheaderZcontent_strr   r   r   _render_dns:  s$    



zRenderer._render_dnsc                 C   sP   t d}| jr|ddd t|dkr.d S dt dd| dg}|S )Nr   mainZdnsr   r   r   )r   ZNetworkManagerConfr   Zset_section_keypairr   r   r   r@   )r   r   r   outr   r   r   _render_networkmanager_confQ  s    
z$Renderer._render_networkmanager_confc                 C   s  dd | j |  D }td}||D ]P}|d }|| }|dkrPd|_| D ]\}	}
|	|krX||	 ||
< qX|dkrd|kr|drd|d< nd|d< |d	rd
}|dkrd}|d	||< |dkr|dg rdd|d |d< |dg D ]F}|| }|g}||j	 |D ] }|}|dkr:d}||d< q$q|dg }|j
}| |||j| | |||| q,d S )Nc                 S   s    i | ]\}}| d r||qS )rz   )r%   )r   Zold_kZnew_kr   r   r   
<dictcomp>b  s   
 z6Renderer._render_bridge_interfaces.<locals>.<dictcomp>rz   rb   r   r   ZonZoffr   r   Z	LLADDRESSZbridge_portsz%sr   ZBRIDGE_PORTSr*   r   r   )r   itemsr   r   r   r   r5   r   r   r   r   r   r   r   )r   r   r   r   Zbridge_key_mapZbridge_filterr   r   r   r   r   r1   Zbridged_iface_nameZbridged_cfgZbridged_cfgsZ
bridge_cfgZbridge_valuer   r   r   r   r   _render_bridge_interfaces`  sd    





   z"Renderer._render_bridge_interfacesc           
      C   sh   t d}||D ]N}|d }|| }d|_|dg }|j}	| |||j| | ||	|| qd S )Nr{   rb   r   )	r   r   r   r   r5   r   r   r   r   )
r   r   r   r   Z	ib_filterr   r   r   r   r   r   r   r   _render_ib_interfaces  s&    
   zRenderer._render_ib_interfacesc                 C   sN  |s
| j }i }| D ]X}|d dkr(q|d }t|||}|dkrX|d |d | ||| |||< q| ||| | ||| | ||| | ||| | 	||| i }	|
 D ]\}}|s|jr| |	|j< |jD ]}|r| |	|j< q|jrt|jj|jjgddgD ]$\}
}|
|	kr"|j||	|
< q"q|	S )	z3Given state, return /etc/sysconfig files + contentsr   Zloopbackrb   r   r   r   rh   ri   )r   r   rv   r8   r   r   r   r   r   r   r   r   rI   r   r   ziprc   rd   )r   rY   r   r   r   r   r   r   r   contentsZcpathrr   r   r   r   _render_sysconfig  sB    




zRenderer._render_sysconfig)r   r   returnc                 C   sT  |s
| j }d}t|| j}| j||| j|d D ]\}}t||| q4| j	rt|| j	}| j
||d}	|	rt||	| | jrt|| j}
| ||}|rt|
|| | jr| |}t|| j}tj|||dd t||d}|drPttj| t dg}|jr8|d	 |d
 t|d|d | d S )Ni  )r   )r   T)r   modeZpreserve_moder   r   zNETWORKING=yeszNETWORKING_IPV6=yeszIPV6_AUTOCONF=nor   )r   r   target_pathr   r   r   r   r   Z
write_filer   r   r   r   r   Z_render_persistent_netr5   r&   Z
ensure_dirr   r   dirnamer   Zuse_ipv6r   r   )r/   r   r   targetZ	file_moderY   r   datar   Zresolv_contentr   Znm_conf_contentZnetrules_contentr   Zsysconfig_pathZnetcfgr   r   r   render_network_state  sf          



  zRenderer.render_network_state)N)N)N)N)NN)rK   rL   rM   rN   r   r   r   r   r   dict__annotations__r0   classmethodr   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r   4  s   
		


 H
=


>
&
<
 *  r   c                    s    fdddD S )ziReturn list of supported names for vlan devices per RHEL doc
    11.5. Naming Scheme for VLAN Interfaces.c                    s   g | ]}|j  td qS )r   Zvid)formatint)r   vr  r   r   r     s   z)_supported_vlan_names.<locals>.<listcomp>)z{rdev}{vid:04}z{rdev}{vid}z{rdev}.{vid:04}z{rdev}.{vid}r   r  r   r  r   r     s    r   c                 C   s0   t  d tkrdS t| r dS t| r,dS dS )NZvariantFT)r   Zsystem_infoKNOWN_DISTROSavailable_sysconfigavailable_nm_ifcfg_rhr   r   r   r   	available  s    r
  c                 C   s   t  t| dS )Nz;usr/lib*/NetworkManager/*/libnm-settings-plugin-ifcfg-rh.so)globr   r   r	  r   r   r   r  %  s    r  c                 C   s`   ddg}ddg}|D ]}t j||| ds dS qddg}|D ]}tjt | |r< d	S q<dS )
NZifupZifdownz/sbinz	/usr/sbin)r$   r   Fz/etc/sysconfig/network-scripts/network-functionszetc/sysconfig/configT)r   Zwhichr   r   r   r   )r   Zexpectedr$   pZexpected_pathsr   r   r   r  0  s    r  )r   )N)N)N)'r^   r  r>   r   r#   typingr   r   Z	cloudinitr   Zloggingr   r   Zcloudinit.distros.parsersr   r   Zcloudinit.netr	   r
   r   r   r   Zcloudinit.net.network_stater   Z	getLoggerrK   r   r  r   r!   r(   r)   rO   rv   r   r   r
  r  r  r   r   r   r   <module>   sT   

6nJ     ^


