o
    w7e                     @   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g d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%d!ddZ&dS )"    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)NetworkState)	almalinuxcentos
cloudlinux	eurolinuxfedoramiraclelinux	openeulerOpenCloudOSopenmandrivarhelrockysuse	TencentOS	virtuozzo#c                 C   sL   ddg}t dt|D ]}|| r| 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 |v S )N)z::z0.0.0.0prefixr   networkr'   )routedefault_netsr'   r'   r(   _is_default_route6   s   r.   c                 C   s0   t d| r| dr| dr| S d|  S | S )Nz\s"z"%s")research
startswithendswith)valuer'   r'   r(   _quote_value;   s
   r5   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.yesno)TFc                 C   s
   i | _ d S N_confselfr'   r'   r(   __init__O      
zConfigMap.__init__c                 C   s   || j |< d S r9   r:   )r=   keyr4   r'   r'   r(   __setitem__R   s   zConfigMap.__setitem__c                 C   s
   | j | S r9   r:   r=   r@   r'   r'   r(   __getitem__U   r?   zConfigMap.__getitem__c                 C   s   | j |S r9   )r;   getrB   r'   r'   r(   rD   X   s   zConfigMap.getc                 C   s
   || j v S r9   r:   rB   r'   r'   r(   __contains__[   r?   zConfigMap.__contains__c                 C   s   | j |d  d S r9   )r;   poprB   r'   r'   r(   drop^   s   zConfigMap.dropc                 C   s
   t | jS r9   )r"   r;   r<   r'   r'   r(   __len__a   r?   zConfigMap.__len__c                 C   s   dS )z6Skip the pair key, value if it matches a certain rule.Fr'   r=   r@   valr'   r'   r(   skip_key_valued   s   zConfigMap.skip_key_valuec                 C   s   t  }|t  | jr|d t| j D ],}| j| }| ||r'qt|t	r1| j
| }t|ts:t|}|d|t|f  q| S )Nr    %s=%s
)ioStringIOwriter)   r;   sortedkeysrK   
isinstancebool	_bool_mapstrr5   getvalue)r=   bufr@   r4   r'   r'   r(   	to_stringh   s   




zConfigMap.to_stringc                 C   s   | j | d S r9   )r;   update)r=   updatesr'   r'   r(   rY   x   s   zConfigMap.updateN)__name__
__module____qualname____doc__rT   r>   rA   rC   rD   rE   rG   rH   rK   rX   rY   r'   r'   r'   r(   r6   F   s    r6   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)
superr_   r>   last_idxhas_set_default_ipv4has_set_default_ipv6_route_name_base_sysconf_dirroute_fn_tpl_ipv4route_fn_tpl_ipv6)r=   
route_namebase_sysconf_diripv4_tplipv6_tpl	__class__r'   r(   r>      s   
zRoute.__init__c                 C   s>   t | j| j| j| j}| j |_| j|_| j|_| j	|_	|S r9   )
r_   re   rf   rg   rh   r;   copyrb   rc   rd   )r=   rr'   r'   r(   ro      s   z
Route.copyc                 C      | j | j| jd S N)basename)rg   rf   re   r<   r'   r'   r(   	path_ipv4      zRoute.path_ipv4c                 C   rq   rr   )rh   rf   re   r<   r'   r'   r(   	path_ipv6   rv   zRoute.path_ipv6c                 C   s   d|v S )N:r'   )r=   addressr'   r'   r(   is_ipv6_route   s   zRoute.is_ipv6_routeipv4c              	   C   s  |dvrt dt| t }|t  | jr|d d}t| j D ]}d|vr.q'|	dd}t| j| }t| jd|  }|dkr| 
|st| jd	|  }|d
 }|ddt| t|f  |ddt| t|f  |dd	t| t|f  d| }	|	| jv rt| jd|  }
|ddt| t|
f  q'|dkr| 
|rt| jd|  }d| | jv rdt| jd|   nd}
|d||||
| jf  q'| S )N)r{   ipv6zUnknown protocol '%s'r    ADDRESSr   GATEWAYr{   NETMASKr`   rL   METRICr|   PREFIXzmetric z%s/%s via %s %s dev %s
)
ValueErrorrU   rM   rN   rO   r)   r;   rP   rQ   replacerz   r5   re   rV   )r=   protorW   reindexr@   indexaddress_valuegateway_valuenetmask_value
metric_keymetric_valueprefix_valuer'   r'   r(   rX      st   

zRoute.to_string)r{   )r[   r\   r]   r^   r>   ro   propertyru   rw   rz   rX   __classcell__r'   r'   rm   r(   r_   |   s    


r_   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).EthernetBondBridge
InfiniBandVlan)ethernetbondbridge
infinibandvlanr   c                    sr   t t|   g | _|| _| jd}t|||d|dd| _| jd| _|| _	|| _
|| jd< || _d S )Nroute_templatesr{   r|   )rk   rl   iface_templatesDEVICE)ra   r   r>   children	templatesrD   r_   routesiface_fn_tplkind_iface_namer;   rf   )r=   
iface_namerj   r   r   	route_tplrm   r'   r(   r>      s   

zNetInterface.__init__c                 C      | j S r9   )r   r<   r'   r'   r(   rt   	     zNetInterface.namec                 C   s   || _ || jd< d S )Nr   )r   r;   )r=   r   r'   r'   r(   rt     s   c                 C   r   r9   )_kindr<   r'   r'   r(   r     r   zNetInterface.kindc                 C   s,   || j vr	t||| _| j | | jd< d S )NTYPE)iface_typesr   r   r;   )r=   r   r'   r'   r(   r     s   
c                 C   rq   rr   )r   rf   rt   r<   r'   r'   r(   path  rv   zNetInterface.pathFc                 C   sH   t | j| j| j| jd}| j |_|rt| j|_|r"| j	 |_	|S )N)r   )
r   rt   rf   r   r   r;   ro   listr   r   )r=   copy_childrencopy_routescr'   r'   r(   ro   #  s   zNetInterface.copyc                 C   s   |dkr
|dkr
dS dS )Nr   r   TFr'   rI   r'   r'   r(   rK   .  s   zNetInterface.skip_key_value)r   )FF)r[   r\   r]   r^   r   r>   r   rt   setterr   r   ro   rK   r   r'   r'   rm   r(   r      s,    	





r   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g dZi Ze	e
d< d7ddZedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed7d)d*Zed7d+d,Zed-d. Zed/d0 Ze	d7d1d2Z		d8d3edee	 d4dfd5d6ZdS )9Rendererz7Renders network information in a /etc/sysconfig format.TFnone)ONBOOTUSERCTLNM_CONTROLLED	BOOTPROTOstaticauto)r   	STARTMODE)r   r   IPV6_FORCE_ACCEPT_RASTPAGEINGPRIOHWADDRMTU)	accept-ra
bridge_stpbridge_ageingbridge_bridgepriomac_addressmtu
BRIDGE_STPBRIDGE_AGEINGTIMEBRIDGE_PRIORITYLLADDR)r   r   r   r   r   ))	bond_modezmode=%s)bond_xmit_hash_policyzxmit_hash_policy=%s)bond_miimonz	miimon=%s)bond_min_linkszmin_links=%s)bond_arp_intervalzarp_interval=%s)bond_arp_ip_targetzarp_ip_target=%s)bond_arp_validatezarp_validate=%s)bond_ad_selectzad_select=%s)bond_num_grat_arpznum_grat_arp=%s)bond_downdelayzdowndelay=%s)bond_updelayz
updelay=%s)bond_lacp_ratezlacp_rate=%s)bond_fail_over_maczfail_over_mac=%s)bond_primaryz
primary=%s)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   )rD   r   r   r   r   r   r   )r=   confignm_conf_pathr'   r'   r(   r>   q  s    zRenderer.__init__c                 C   s   t | j|i }|| dD ]$}||}|d ur5|dkr'|d dvr'q| j| |}|r5|||< qd|v rJ|d rL|d dkrNd|d< d S d S d S d S )	N)r   r   r   r   type)physicalr   	wakeonlanr   zwol gETHTOOL_OPTS)ro   deepcopyiface_defaultsrD   rY   cfg_key_maps)clsiface	iface_cfgr   flavor_defaultsold_key	old_valuenew_keyr'   r'   r(   _render_iface_shared  s$   

zRenderer._render_iface_sharedc                 C   sX  |dkrd|d< d|v rd|d< | d nd|d< t|t|jdD ]V\}}d}|d	}|d
ks7|dkrr|dkrP|d dkrFd|d< nd
|d< d|d< n|dkri|dkrid|d< d|d< d|d< d|d< nd|d< d|d< n|dkr|dkr|d dkrd|d< nd
|d< d|d< nd|d< d|d< d|d< d|d< n|dkr|dkr|d dkrd|d< nd
|d< d|d< nd|d< d|d< n|dv r|d }	d|d< |dkr|dkr|	d
krd|d< n|dv rCt|r|dkrd}d|d< d|v r0t||v o|d || k}
|
rtd|j	|| |d  t|r*|dkr#n|d ||< n|d ||< t|rB|dkrBd|d< d|d< n!|d kr[|dkrTt
d!| n||v |d"< n	td#||j	f |d$d krz|dkrvd |d%< q#d|d"< q#d&}d&}t|t|jdD ] \}}|d	}d'|v r|dkr|d' |d(< |d)v r|dkr|r|d dkrd|d*< q|tv rÐq|dv rt|r|d+ }d,|d- |d. f }|d/kr|dkr||d0< nQ||d1< nL|d+kr|dkr||d2< n=||d3< n8|dkr||d4| < n,|d3  d5| 7  < n!|d+ }|d/kr%d6nt|}|d- |d7| < t|d. |d8| < d9|v r]|dkr]d|d:< t|d9 rW|d9 |d;< n|d9 |d<< d=|v rp|dkrpd5|d= |d>< d?|v r|dkrt|d? d@krt
dA|j	t|d?  t|d? d d@ d+D ]\}}||dBt| < qqd S )CNr   r   r   BRIDGEdhcpr   startr   r   dhcp6zipv6_dhcpv6-statefuldhcp4managedDHCLIENT6_MODEr   TDHCPV6CIPV6INITFIPV6_AUTOCONFzipv6_dhcpv6-statelessinfoz-SDHCPV6C_OPTIONS
ipv6_slaac)r   r   )r   static6IPV6_MTUr   zZNetwork config: ignoring %s device-level mtu:%s because ipv4 subnet-level mtu:%s provided.r   manualz Unknown subnet type setting "%s"r   z1Unknown subnet type '%s' found for interface '%s'r   r   r}   metricr   r   r   DHCLIENT_SET_DEFAULT_ROUTEr`   z%s/%sry   r*   r   IPADDR6IPV6ADDR	IPADDR6_1IPV6ADDR_SECONDARIESz
IPADDR6_%dr   r   IPADDRr   gatewayDEFROUTEIPV6_DEFAULTGWr   
dns_searchDOMAINdns_nameservers   z6%s has %d entries in dns_nameservers. Only 3 are used.DNS)rG   	enumerater"   r   rD   r   rS   LOGwarningrt   debugr   r	   rU   r   r
   r#   )r   r   subnetshas_default_router   r&   subnetmtu_keysubnet_typebootproto_inmtu_mismatch
ipv4_index
ipv6_index	ipv6_cidr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p*t|d }	t|r||tvr||dr;|jsC|drJ|jrJt	d|j
 d	|d
< |d dv rXd	|d< d|v rq|	rh|d |d< d	|_n	|d |d< d	|_d|v r{|d |d< qdD ]\}
}|
|v r| |j }||
 ||< q~| jd7  _qqd S )Nr   r   r   r   r|   r	  r{   z?Duplicate declaration of default route found for interface '%s'Tr
  r   r  r  r  r   r  r   ))r	  r   )r  r   )r*   r   )netmaskr   )r+   r~   r`   )r  r"   r   rD   r
   r.   r	   rc   rd   r   rt   rb   )r   r   	route_cfgr  r   _r  r  r,   is_ipv6r   new_namer   r'   r'   r(   _render_subnet_routesf  sX   
	zRenderer._render_subnet_routesc           	      C   s   g }| j D ].\}}||ddg}|D ]}||v r2|| }t|ttfr)d|}|||   nqq|rL|dkrCd||d< d S d||d< d S d S )Nr$  -r   r   BONDING_MODULE_OPTSBONDING_OPTS)bond_tpl_optsr   rR   tupler   r#   append)	r   r   r   r   	bond_optsbond_key	value_tpl	bond_keys
bond_valuer'   r'   r(   _render_bonding_opts  s"   
zRenderer._render_bonding_optsc           
      C   s^   t j}||D ]$}|d }|dg }|| }|j}	| |||j| | ||	|| qd S )Nrt   r  )r   filter_by_physicaliter_interfacesrD   r   r!  r  r'  )
r   network_stateiface_contentsr   physical_filterr   r   iface_subnetsr   r#  r'   r'   r(   _render_physical_interfaces  s    z$Renderer._render_physical_interfacesc                    s^  t d}t d}||D ]}|d  |  }| ||| |g}||j |D ]}	d|	d< |dkr8d|	_q+|drQ|dkrJ|d|d< n|d|d	< |d
g }
|j	}| 
||
|j| | |||
| t fdd||D }t|D ].\}}|dkrd| }nd| }|||< || }|dkrd|d< d|d< q} |d< d|d< q}qd S )Nr   bond-masterrt   TBONDING_MASTERr   r   r   MACADDRr  c                    s    g | ]}|d   kr|d qS )r;  rt   r'   ).0slave_ifacer   r'   r(   
<listcomp>  s
    z4Renderer._render_bond_interfaces.<locals>.<listcomp>zBONDING_SLAVE_%szBONDING_SLAVE%sr   r   hotplugr   MASTERSLAVE)r   filter_by_typefilter_by_attrr5  r3  extendr   r   rD   r   r!  r  r'  rP   r  )r   r6  r7  r   bond_filterslave_filterr   r   master_cfgs
master_cfgr9  r#  bond_slavesr   
bond_slaveslavestr	slave_cfgr'   r@  r(   _render_bond_interfaces  s`   







z Renderer._render_bond_interfacesc              	   C   s   t d}||D ]d}|d }|| }|dkr/|d}|r#||d< |d |d |d< n%d|d	< d|_|d
 }	t|	|d }
||
vrPtd||	d	|
 |	|d< |dg }|j
}| |||j| | |||| q
d S )Nr   rt   r   vlan_idVLAN_ID.ETHERDEVICETVLANzvlan-raw-devicezIName '%s' for vlan '%s' is not officially supportedby RHEL. Supported: %sr   PHYSDEVr  )r   rE  r5  rD   rfindr   _supported_vlan_namesr  r   r#   r   r!  r  r'  )r   r6  r7  r   vlan_filterr   r   r   rQ  rdev	supportedr9  r#  r'   r'   r(   _render_vlan_interfaces  sB   

z Renderer._render_vlan_interfacesc                 C   s   t t| jt| jgsd S td}|r#tj|r#tt	
|}| jD ]}|| q&| jD ]}|| q1td}t|}||sL|d | }|S )Nr   ;r    )anyr"   r  dns_searchdomainsr   
ResolvConfosr   isfiler   	load_fileadd_nameserveradd_search_domainr)   rU   r2   )r6  existing_dns_pathcontent
nameserversearchdomainheader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   maindnsr   r   r    )r   NetworkManagerConfr  set_section_keypairr"   r#   r)   rO   )r6  r   rg  outr'   r'   r(   _render_networkmanager_confQ  s   
z$Renderer._render_networkmanager_confc                 C   s|  dd | j |  D }td}||D ]}|d }|| }|dkr'd|_| D ]\}	}
|	|v r9||	 ||
< q+|dkrPd|v rP|drLd|d< nd|d< |d	rdd
}|dkr]d}|d	||< |dkrz|dg rzdd|d |d< |dg D ] }|| }|g}||j	 |D ]}|}|dkrd}||d< qq|dg }|j
}| |||j| | |||| qd S )Nc                 S   s    i | ]\}}| d r||qS )r   )r2   )r>  old_knew_kr'   r'   r(   
<dictcomp>b  s    z6Renderer._render_bridge_interfaces.<locals>.<dictcomp>r   rt   r   r   onoffr   r=  	LLADDRESSbridge_portsz%sr   BRIDGE_PORTSr7   r   r  )r   itemsr   rE  r5  r   rD   r#   rG  r   r   r!  r  r'  )r   r6  r7  r   bridge_key_mapbridge_filterr   r   r   r   r   r@   bridged_iface_namebridged_cfgbridged_cfgs
bridge_cfgbridge_valuer9  r#  r'   r'   r(   _render_bridge_interfaces`  sd   





z"Renderer._render_bridge_interfacesc           
      C   sh   t d}||D ]'}|d }|| }d|_|dg }|j}	| |||j| | ||	|| q
d S )Nr   rt   r  )	r   rE  r5  r   rD   r   r!  r  r'  )
r   r6  r7  r   	ib_filterr   r   r   r9  r#  r'   r'   r(   _render_ib_interfaces  s"   
zRenderer._render_ib_interfacesc                 C   sH  |s| j }i }| D ],}|d dkrq|d }t|||}|dkr,|d |d | ||| |||< q| ||| | ||| | ||| | ||| | 	||| i }	|
 D ]@\}}|sj|jr| |	|j< |jD ]}|r| |	|j< qt|jrt|jj|jjgddgD ]\}
}|
|	vr|j||	|
< qqa|	S )	z3Given state, return /etc/sysconfig files + contentsr   loopbackrt   r   r   r   r{   r|   )r   r5  r   rG   r   r:  rP  r\  r  r  r{  r   rX   r   r   zipru   rw   )r   rj   r6  r   r   r7  r   r   r   contentscpathr   r'   r'   r(   _render_sysconfig  sF   




zRenderer._render_sysconfigr6  returnc                 C   sT  |s| j }d}t|| j}| j||| j|d D ]\}}t||| q| j	r@t|| j	}| j
||d}	|	r@t||	| | jrYt|| j}
| ||}|rYt|
|| | jrq| |}t|| j}tj|||dd t||d}|drttj| t dg}|jr|d	 |d
 t|d|d | d S d S )Ni  )r   )rf  T)rg  modepreserve_moder   r+   zNETWORKING=yeszNETWORKING_IPV6=yeszIPV6_AUTOCONF=nor    )r   r   target_pathr   r  r   r{  r   
write_filer   rl  r   rr  r   _render_persistent_netrD   r3   
ensure_dirra  r   dirnamer)   use_ipv6r-  r#   )r=   r6  r   target	file_moderj   r   datar   resolv_contentr   nm_conf_contentnetrules_contentr   sysconfig_pathnetcfgr'   r'   r(   render_network_state  s\   






zRenderer.render_network_stater9   )NN)r[   r\   r]   r^   r   r   r,  r+  r   dict__annotations__r>   classmethodr   r!  r'  r3  r:  rP  r\  staticmethodrl  rr  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 )rZ  vid)formatint)r>  vr  r'   r(   rA    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(   rX    s   rX  c                 C   s0   t  d tvr
dS t| rdS t| rdS dS )NvariantFT)r   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 )
Nifupifdownz/sbinz	/usr/sbin)r1   r  Fz/etc/sysconfig/network-scripts/network-functionszetc/sysconfig/configT)r   whichra  r   rb  r  )r  expectedr1   pexpected_pathsr'   r'   r(   r  0  s   r  )r   r9   )'ro   r  rM   ra  r0   typingr   r   	cloudinitr   loggingr   r   cloudinit.distros.parsersr   r   cloudinit.netr	   r
   r   r   r   cloudinit.net.network_stater   	getLoggerr[   r  r  r)   r.   r5   r6   r_   r   r   rX  r  r  r  r'   r'   r'   r(   <module>   s:   

6nJ     ^


