o
    thHL                     @   sN  U d 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m	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ ddlmZ eeZeZd	Zd
Zg dZdddgdddddedgdddddedgddddddg ddddddg dddddZi ddddd	g ddd d!dd"d#d$id%d&did"d#d$d'd(d&did&did)d*dddd+id,dd-diid.d	ddd/d0dgddd1d2d3d4gd4d5d6d7d8d&did"d#d$d'd9d4i id:d&did	ddd;did<d=d&did	ddd;d"id<d>d&didd	d+d"d#d$d<d?dd;d"iid@d&did&did)dAd&did	ddd;d"id<dBdd-diiZeeef edC< dDD ]	Z ed= ee < q8dED ]	Z ed@ ee < qDdFD ]	Z edA ee < qPdGeedgdHZ!eedI< e"g dJZ#dKdL Z$dMefdNdOZ%d`dPdQZ&dadRdSZ'dTdU Z(								dbdVdWZ)dXdY Z*dZed[ed\ed]e+dMdf
d^d_Z,dS )czNTP: enable and configure ntp    N)DictMapping)subp
temp_utils	templater
type_utilsutil)Cloud)Config)
MetaSchema)PER_INSTANCEz/etc/ntp.conf   )	almalinuxalpineaosc
azurelinuxcentos
cloudlinuxcosdebian	eurolinuxfedorafreebsdmarinermiraclelinuxopenbsd	openeulerOpenCloudOSopenmandrivaopensuseopensuse-microosopensuse-tumbleweedopensuse-leapphotonraspberry-pi-osrhelrockysle_hpc	sle-microsles	TencentOSubuntu	virtuozzochronydz/etc/chrony.confchronyzchrony.conf.{distro})	check_execonfpathpackagesservice_nametemplate_nametemplatentpdntpzntp.conf.{distro}ntpdatez/etc/ntpd.confzntpd.conf.{distro}z/lib/systemd/systemd-timesyncdz-/etc/systemd/timesyncd.conf.d/cloud-init.confsystemd-timesyncdztimesyncd.conf)r.   r6   r7   openntpdr8   r   z/etc/chrony/chrony.conf)r0   r2   )r0   r1   r2   )r.   r6   r   z"/usr/lib/systemd/systemd-timesyncdz/etc/systemd/timesyncd.conf)r/   r0   r   r2   )r.   r8   r   )r6   r.   r   )r2   r0   r   r0   r   )r0   r2   r3   z/usr/local/etc/chrony.conf)r0   r1   r2   r3   z/usr/local/sbin/ntpdz/usr/local/etc/ntp.confr9   zntpd.conf.openbsd)r/   r0   r1   r2   r3   )r6   r.   r9   r   r   r   r/   )r.   r6   r8   r   r#   r$   r%   r)   r+   DISTRO_CLIENT_CONFIG)r    r!   r"   )r   r   r&   )r'   r(   cc_ntp)iddistros	frequencyactivate_by_schema_keysmeta)r/   r0   r1   r2   c                 C   s0   t }tt}| |v rtj|||  gdd}|S )zConstruct a distro-specific ntp client config dictionary by merging
       distro specific changes into base config.

    @param distro: String providing the distro class name.
    @returns: Dict of distro configurations for ntp clients.
    Treverse)r:   copyNTP_CLIENT_CONFIGr   mergemanydict)distrodcfgcfg rI   9/usr/lib/python3/dist-packages/cloudinit/config/cc_ntp.pydistro_ntp_client_configs  s
   
rK   returnc                 C   s   t |j}| r| dkrtd|  || i S |dd}i }|dkrU|jD ]}||}t|dr?td| |} nq&|sS|jd }td| ||i }|S td| ||i }|S )	a  Determine which ntp client is to be used, consulting the distro
       for its preference.

    @param ntp_client: String name of the ntp client to use.
    @param distro: Distro class instance.
    @returns: Dict of the selected ntp client or {} if none selected.
    autoz4Selected NTP client "%s" via user-data configuration
ntp_clientr/   z+Selected NTP client "%s", already installedr   z<Selected distro preferred NTP client "%s", not yet installedz1Selected NTP client "%s" via distro system config)	rK   nameLOGdebugget
get_optionpreferred_ntp_clientsr   which)rN   rF   
distro_cfgdistro_ntp_client	clientcfgclientrH   rI   rI   rJ   select_ntp_client!  s@   




rZ   c                 C   s(   t |rdS |du rdg}| | dS )ah  Install ntp client package if not already installed.

    @param install_func: function.  This parameter is invoked with the contents
    of the packages parameter.
    @param packages: list.  This parameter defaults to ['ntp'].
    @param check_exe: string.  The name of a binary that indicates the package
    the specified package is already installed.
    Nr6   )r   rU   )install_funcr1   r/   rI   rI   rJ   install_ntp_clientS  s
   
	r\   c                 C   s$   t j| rt| | d  dS dS )zRename any existing ntp client config file

    @param confpath: string. Specify a path to an existing ntp client
    configuration file.
    z.distN)ospathexistsr   renamer0   rI   rI   rJ   rename_ntp_confd  s   rb   c                 C   sh   g }| }| dkrd}n
| dks| dkrd}t tD ]}|ddd t|g|g d	g D  q|S )
zGenerate a list of server names to populate an ntp client configuration
    file.

    @param distro: string.  Specify the distro name
    @returns: list: A list of strings representing ntp servers for this distro.
    r)   r   r   r    .c                 S   s   g | ]}|r|qS rI   rI   ).0nrI   rI   rJ   
<listcomp>  s    z)generate_server_names.<locals>.<listcomp>zpool.ntp.org)rangeNR_POOL_SERVERSappendjoinstr)rF   namespool_distroxrI   rI   rJ   generate_server_namesn  s   rp   c	                 C   s   |sg }|sg }|sg }|sg }|s|s| dkrdS |s2| dkr2|dkr2t | }tdd| n|sC|sCt | }tdd| |sItd|sQ|sQtd	||||d
}	|rltjddd}
|
d }tj||d t	
|||	 |r|t| dS dS )a  Render a ntp client configuration for the specified client.

    @param distro_name: string.  The distro class name.
    @param service_name: string. The name of the NTP client service.
    @param servers: A list of strings specifying ntp servers. Defaults to empty
    list.
    @param pools: A list of strings specifying ntp pools. Defaults to empty
    list.
    @param allow: A list of strings specifying a network/CIDR. Defaults to
    empty list.
    @param peers: A list nodes that should peer with each other. Defaults to
    empty list.
    @param path: A string to specify where to write the rendered template.
    @param template_fn: A string to specify the template source file.
    @param template: A string specifying the contents of the template. This
    content will be written to a temporary file before being used to render
    the configuration file.

    @raises: ValueError when path is None.
    @raises: ValueError when template_fn is None and template is None.
    r   Nr   r5   z%Adding distro default ntp servers: %s,z*Adding distro default ntp pool servers: %sz Invalid value for path parameterz$Not template_fn or template provided)serverspoolsallowpeersztemplate_name-z.tmpl)prefixsuffix   )content)rp   rP   rQ   rk   
ValueErrorr   mkstempr   
write_filer   render_to_filedel_file)distro_namer2   rr   rs   rt   ru   r^   template_fnr4   paramstfilerI   rI   rJ   write_ntp_config_template  sF    
r   c                 C   sB  g }t t|  }|rdt|}|dj|d nt| 	d| 	dgs/|d t| 
 D ]\\}}d| }|dkrUt|t|tgsT|d	j||d
 q5|dkrit|tsh|dj||d
 q5|dv r|du rrq5t|ts|dj||d
 q5t|ts|dj||d
 q5|rtdjd|ddS )aO  Validate user-provided ntp:config option values.

    This function supplements flexible jsonschema validation with specific
    value checks to aid in triage of invalid user-provided configuration.

    @param ntp_config: Dictionary of configuration value under 'ntp'.

    @raises: ValueError describing invalid values provided.
    z, z(Missing required ntp:config keys: {keys})keysr4   r3   zJEither ntp:config:template or ntp:config:template_name values are requiredzntp:config:r0   z6Expected a config file path {keypath}. Found ({value}))keypathvaluer1   zHExpected a list of required package names for {keypath}. Found ({value}))r4   r3   Nz5Expected a string type for {keypath}. Found ({value})z$Invalid ntp configuration:\n{errors}
)errors)REQUIRED_NTP_CONFIG_KEYS
differencesetr   rk   sortedrj   formatanyrR   itemsall
isinstancerl   listrz   )
ntp_configr   missingr   keyr   r   rI   rI   rJ   supplemental_schema_validation  sn   




r   rO   rH   cloudargsc                 C   s  d|vrt d|  dS |d }|du ri }t|ts&tdjt|d|dd}t	
|r9t d|  dS t|d	|j}t	j||d
i gdd}t| t|dd d}|ds~|d d|jj}||}|s~d|d }	t|	t d|d t d|dg  t d|dg  t d|dg  t d|dg  t|jj|d|dg |dg |dg |dg |d||dd	 t|jj|d |d d t	 rF|dd kr%z	|jd!d  W n tjy
   t d" Y nw z	|jd#d  W n tjy$   t d$ Y nw z|jd%|d  W n tjyE }
 zt d&|
  d}
~
ww z|jd'|d  W dS  tjyg }
 zt d(|
  d}
~
ww ))zEnable and configure ntp.r6   z8Skipping module named %s, not present or disabled by cfgNzL'ntp' key existed in config, but not a dictionary type, is a {_type} instead)_typeenabledTz)Skipping module named %s, disabled by cfgrN   configrA   r0   ra   r4   r3   z{distro}z#No template found, not rendering %szservice_name: %sr2   zservers: %srr   z	pools: %srs   z	allow: %srt   z	peers: %sru   )r2   rr   rs   rt   ru   r^   r   r4   r1   r/   )r1   r/   r5   stopz Failed to stop base ntpd servicedisablez#Failed to disable base ntpd serviceenablez Failed to enable ntp service: %sreloadz&Failed to reload/start ntp service: %s)rP   rQ   r   dictRuntimeErrorr   r   obj_namerR   r   is_falserZ   rF   rE   r   rb   replacerO   get_template_filenamer   r\   install_packagesis_BSDmanage_servicer   ProcessExecutionErrorwarning	exception)rO   rH   r   r   ntp_cfgr   ntp_client_configr   r3   msgerI   rI   rJ   handle  s   










r   )Nr5   )N)NNNNNNNN)-__doc__rC   loggingr]   typingr   r   	cloudinitr   r   r   r   r   cloudinit.cloudr	   cloudinit.configr
   cloudinit.config.schemar   cloudinit.settingsr   	getLogger__name__rP   r>   NTP_CONFri   r=   rD   r:   rl   __annotations__rF   r@   	frozensetr   rK   rZ   r\   rb   rp   r   r   r   r   rI   rI   rI   rJ   <module>   s  
$				,#).BKNZfpu} 
  	
2


M"=