
    fR                        U d Z ddlZddlZddlZddl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mZ ddlmZ  ej*                  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dddd	g dddd did did!dddd"idd#diid	ddd$d%dgddd&d'd(d)gd)d*d+d,d did-d.d/d0d)i id did	ddd1did2d did	ddd1d-id2d didd	d"d-d.d/d2d did did!d did	ddd1d-id2dd#diid3Zd4D ]
  Zed5   ee<    d6D ]
  Zed7   ee<    d8d9d: ed;      e ed<       ed=      gedgd>Zee d?<    ee      Z  e!g d@      Z"dA Z#dB Z$dNdCZ%dOdDZ&dE Z'	 	 	 	 	 	 	 	 dPdFZ(dG Z)dHe*dIedJedKe+dLdf
dMZ,y)QzNTP: enable and configure ntp    N)dedent)subp
temp_utils	templater
type_utilsutil)Cloud)Config)
MetaSchemaget_meta_doc)PER_INSTANCEz/etc/ntp.conf   )	almalinuxalpinecentos
cloudlinuxcosdebian	eurolinuxfedorafreebsdmarinermiraclelinuxopenbsd	openeulerOpenCloudOSopenmandrivaopensuseopensuse-microosopensuse-tumbleweedopensuse-leapphoton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,   r4   r5   openntpdr6   z/etc/chrony/chrony.conf)r.   r0   )r.   r/   r0   )r,   r4   r0   )r4   r,   )r0   r.   r.   )r.   r0   r1   z/usr/local/etc/chrony.conf)r.   r/   r0   r1   z/usr/local/sbin/ntpdz/usr/local/etc/ntp.confr7   zntpd.conf.openbsd)r-   r.   r/   r0   r1   )r4   r,   r7   z"/usr/lib/systemd/systemd-timesyncdz/etc/systemd/timesyncd.conf)r-   r.   )r,   r6   r-   )r,   r4   r6   )r   r   r   r   r   r   r   r   r   r"   r#   r'   r)   )r   r    r!   r   )r%   r&   r'   cc_ntpNTPzenable and configure ntpaD          Handle ntp configuration. If ntp is not installed on the system and
        ntp configuration is specified, ntp will be installed. If there is a
        default ntp config file in the image or one is present in the
        distro's ntp package, it will be copied to a file with ``.dist``
        appended to the filename before any changes are made. A list of ntp
        pools and ntp servers can be provided under the ``ntp`` config key.
        If no ntp ``servers`` or ``pools`` are provided, 4 pools will be used
        in the format ``{0-3}.{distro}.pool.ntp.org``.z        # Override ntp with chrony configuration on Ubuntu
        ntp:
          enabled: true
          ntp_client: chrony  # Uses cloud-init default chrony configuration
        aY          # Provide a custom ntp client configuration
        ntp:
          enabled: true
          ntp_client: myntpclient
          config:
             confpath: /etc/myntpclient/myntpclient.conf
             check_exe: myntpclientd
             packages:
               - myntpclient
             service_name: myntpclient
             template: |
                 ## template:jinja
                 # My NTP Client config
                 {% if pools -%}# pools{% endif %}
                 {% for pool in pools -%}
                 pool {{pool}} iburst
                 {% endfor %}
                 {%- if servers %}# servers
                 {% endif %}
                 {% for server in servers -%}
                 server {{server}} iburst
                 {% endfor %}
                 {% if peers -%}# peers{% endif %}
                 {% for peer in peers -%}
                 peer {{peer}}
                 {% endfor %}
                 {% if allow -%}# allow{% endif %}
                 {% for cidr in allow -%}
                 allow {{cidr}}
                 {% endfor %}
          pools: [0.int.pool.ntp.org, 1.int.pool.ntp.org, ntp.myorg.org]
          servers:
            - ntp.server.local
            - ntp.ubuntu.com
            - 192.168.23.2
          allow:
            - 192.168.23.0/32
          peers:
            - km001
            - km002)idnametitledescriptiondistrosexamples	frequencyactivate_by_schema_keysmeta)r-   r.   r/   r0   c                     t         }t        j                  t              }| |v rt        j                  |||    g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)DISTRO_CLIENT_CONFIGcopyNTP_CLIENT_CONFIGr   mergemanydict)distrodcfgcfgs      9/usr/lib/python3/dist-packages/cloudinit/config/cc_ntp.pydistro_ntp_client_configsrN   <  s?      D
))%
&C~  #tF|!4dCJ    c                 D   t        |j                        }| r-| dk7  r(t        j                  d|        |j	                  | i       S |j                  dd      }i }|dk(  r|j                  D ]Q  }|j	                  |      }t        j                  |j	                  d            s9t        j                  d|       |} n |s6|j                  d   }t        j                  d|       |j	                  |      }|S t        j                  d|       |j	                  |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)	rN   r;   LOGdebugget
get_optionpreferred_ntp_clientsr   which)rR   rJ   
distro_cfgdistro_ntp_client	clientcfgclientrL   s          rM   select_ntp_clientr]   J  s#    +6;;7J jF*		BJ	
 ~~j"-- )),?IF"22 	F..(Czz#''+./		A6  		 11!4FIIN #v.I  			?	
 NN#4b9	rO   c                 J    t        j                  |      ry|dg} | |       y)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.
    Nr4   )r   rX   )install_funcr/   r-   s      rM   install_ntp_clientr`   |  s(     zz)7rO   c                 v    t         j                  j                  |       rt        j                  | | dz          yy)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r.   s    rM   rename_ntp_confrg     s,     
ww~~hHh01  rO   c           	          g }| }| dk(  rd}n| dk(  s| dk(  rd}t        t              D ]E  }|j                  dj                  t	        |      g|gz   dgz   D cg c]  }|s|	 c}             G |S c c}w )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    .zpool.ntp.org)rangeNR_POOL_SERVERSappendjoinstr)rJ   namespool_distroxns        rM   generate_server_namesrt     s     EK !	8	v4 ?# 
HH VH}47GGMq1M	

 L	 Ns   A2A2c	                    |sg }|sg }|sg }|sg }t        |      dk(  rt        |      dk(  r| dk(  ryt        |      dk(  r;| dk(  r6|dk(  r1t        |       }t        j                  ddj	                  |             nLt        |      dk(  r>t        |      dk(  r0t        |       }t        j                  ddj	                  |             |st        d	      |s|st        d
      ||||d}	|r3t        j                  dd      }
|
d   }t        j                  ||       t        j                  |||	       |rt        j                  |       yy)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   r   Nr   r3   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)lenrt   rS   rT   rn   
ValueErrorr   mkstempr   
write_filer   render_to_filedel_file)distro_namer0   rw   rx   ry   rz   rc   template_fnr2   paramstfiles              rM   write_ntp_config_templater     sJ   @ 
7|qSZ1_1EG8#F" (4		9388G;LM	W	s5zQ%k2		8#((5/	
 ;<<x?@@ 	F ""*:7KAhX6[$7k" rO   c                    g }t         j                  t        | j                                     }|r<dj	                  t        |            }|j                  dj                  |             n<t        | j                  d      | j                  d      g      s|j                  d       t        | j                               D ]  \  }}d|z   }|dk(  r?t        |t        |t              g      r,|j                  d	j                  ||
             O|dk(  r4t        |t              re|j                  dj                  ||
             |dv r7|t        |t              r|j                  dj                  ||
             t        |t              r|j                  dj                  ||
              |r*t        dj                  dj	                  |                  y)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})keysr2   r1   zJEither ntp:config:template or ntp:config:template_name values are requiredzntp:config:r.   z6Expected a config file path {keypath}. Found ({value}))keypathvaluer/   zHExpected a list of required package names for {keypath}. Found ({value}))r2   r1   Nz5Expected a string type for {keypath}. Found ({value})z$Invalid ntp configuration:\n{errors}
)errors)REQUIRED_NTP_CONFIG_KEYS
differencesetr   rn   sortedrm   formatanyrU   itemsall
isinstancero   listr   )
ntp_configr   missingr   keyr   r   s          rM   supplemental_schema_validationr     s    F&11#joo6G2HIGyy)6==4=H	
 	
	#Z^^O%DE 		
 Z--/0 
U#%*z%567''-vgUv'K JeT*''-vgUv'K 11}eS)''-vgUv'K E3'MMGNN#5 O /: 3::yy( ; 
 	
 rO   r;   rL   cloudargsreturnc                 	   d|vrt         j                  d|        y|d   }|i }t        |t              s.t	        dj                  t        j                  |                  |j                  dd      }t        j                  |      rt         j                  d|        yt        |j                  d	      |j                        }t        j                  ||j                  d
i       gd      }t        |       t        |j                  d             d}|j                  d      sg|j                  d      j!                  d|j                  j"                        }|j%                  |      }|sd|j                  d      z  }	t	        |	      t         j                  d|j                  d             t         j                  d|j                  dg              t         j                  d|j                  dg              t         j                  d|j                  dg              t         j                  d|j                  dg              t'        |j                  j"                  |j                  d      |j                  dg       |j                  dg       |j                  dg       |j                  dg       |j                  d      ||j                  d      	       t)        |j                  j*                  |d   |d          t        j,                         rz|j                  d      d k7  r:	 |j                  j/                  d!d        	 |j                  j/                  d#d        	 |j                  j/                  d%|j                  d             	 |j                  j/                  d'|j                  d             y# t0        j2                  $ r t         j5                  d"       Y w xY w# t0        j2                  $ r t         j5                  d$       Y w xY w# t0        j2                  $ r}
t         j7                  d&|
        d}
~
ww xY w# t0        j2                  $ r}
t         j7                  d(|
        d}
~
ww xY w))zEnable and configure ntp.r4   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 cfgrR   configrD   r.   rf   r2   r1   z{distro}z#No template found, not rendering %szservice_name: %sr0   zservers: %srw   z	pools: %srx   z	allow: %sry   z	peers: %srz   )r0   rw   rx   ry   rz   rc   r   r2   r/   r-   )r/   r-   r3   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)rS   rT   r   dictRuntimeErrorr   r   obj_namerU   r   is_falser]   rJ   rI   r   rg   replacer;   get_template_filenamer   r`   install_packagesis_BSDmanage_servicer   ProcessExecutionErrorwarning	exception)r;   rL   r   r   ntp_cfgr   ntp_client_configr   r1   msges              rM   handler   B  s   C		F	
 	%jG g&$$*F1D1DW1MF$N
 	
 kk)T*G}}W		=tD *L!5<< **	GKK"56 ##45.22:>?K  ,)--o>FF))
 11-@5#''89  s##II "3"7"7"GHIImW[[B78IIk7;;w34IIk7;;w34IIk7;;w34&**>:Ir*kk'2&kk'2&kk'2&"":."&&z2
 %%":.#K0
 {{}  0F:@++FF;C++Iv>	LL''+//?##'++N;	
 -- @>?@ -- CABC )) 	MM<a@	 %% >BsT   2O O2 ,+P  +Q (O/.O/2(PP Q3Q

QR%Q<<R)Nr3   )N)NNNNNNNN)-__doc__rG   loggingrb   textwrapr   	cloudinitr   r   r   r   r   cloudinit.cloudr	   cloudinit.configr
   cloudinit.config.schemar   r   cloudinit.settingsr   	getLogger__name__rS   r@   NTP_CONFrl   r>   rH   rF   rJ   rB   __annotations__	frozensetr   rN   r]   r`   rg   rt   r   r   ro   r   r    rO   rM   <module>r      s   $   	  C C ! # < +g!	B &J / G, K!, $- 6C+)C) ^ 2%

 ("

 F
 I
	 	%1
 	1
 ("0
 5!
%3	
 01#&0
, I
 >5
	 	B
 I
 ("

 9
 I
 ("

 =
 I
 !'OD=5
	 F
 I
	 I
 ("

 =
 	1
kz x K DF#7
#C D ' @F#7#? @ '	:
 	
 	(*	
4j  %wMGj GP t
 %9 
/d"2> 


	N#b:
z_ _6 _% _t _ _rO   