sonic-buildimage/files/image_config/ntp/ntp.conf.j2
Yevhen Fastiuk f78cb9c55c
[202311][cherry-pick][NTP] Add NTP extended configuration (#17487)
* Add NTP YANG model

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Extend NTP config generation mechanism

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Add NTP YANG nodel tests

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Add test for NTP Jinja templates

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Add ntpdate package

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Fix 'bad' when auth disabled

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* [NTP] Changed owner for ntp keys config file to root and remove read access for other.

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Fix NTP warnings after restarting the service

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Add ability to encrypt/decrypt NTP keys

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Update Configuration reference

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Fix NTP configuration template

* Align the description for setting interface
* Fix the usage of scoped variable

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Fix YANG model description and tests

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Align NTP test according to fixed condition

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Allow eth0 to be as source ifc without defining it

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

* Update sample config with NTP config

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>

---------

Signed-off-by: Yevhen Fastiuk <yfastiuk@nvidia.com>
2023-12-21 09:45:29 -08:00

164 lines
5.9 KiB
Django/Jinja

###############################################################################
# This file was AUTOMATICALLY GENERATED. DO NOT MODIFY.
# Controlled by ntp-config.service
###############################################################################
# To avoid ntpd from panic and exit if the drift between new time and
# current system time is large.
tinker panic 0
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
{# Getting NTP global configuration -#}
{% set global = (NTP | d({})).get('global', {}) -%}
{# Adding NTP servers. We need to know if we have some pools, to set proper
config -#}
{% set ns = namespace(is_pools=false) %}
{% for server in NTP_SERVER if NTP_SERVER[server].admin_state != 'disabled' and
NTP_SERVER[server].resolve_as and
NTP_SERVER[server].association_type -%}
{% set config = NTP_SERVER[server] -%}
{# Server options -#}
{% set soptions = '' -%}
{# Server access control options -#}
{% set aoptions = '' -%}
{# Authentication key -#}
{% if global.authentication == 'enabled' -%}
{% if config.key -%}
{% set soptions = soptions ~ ' key ' ~ config.key -%}
{% endif -%}
{% endif -%}
{# Aggressive polling -#}
{% if config.iburst -%}
{% set soptions = soptions ~ ' iburst' -%}
{% endif -%}
{# Protocol version -#}
{% if config.version -%}
{% set soptions = soptions ~ ' version ' ~ config.version -%}
{% endif -%}
{# Check if there are any pool configured. BTW it doesn't matter what was
configured as "resolve_as" for pools. If they were configured with FQDN they
must remain like that -#}
{% set config_as = config.resolve_as -%}
{% if config.association_type == 'pool' -%}
{% set ns.is_pools = true -%}
{% set config_as = server -%}
{% else -%}
{% set aoptions = aoptions ~ ' nopeer' -%}
{% endif -%}
{{ config.association_type }} {{ config_as }}{{ soptions }}
{% if global.server_role == 'disabled' %}
restrict {{ config_as }} kod limited nomodify notrap noquery{{ aoptions }}
{% endif %}
{% endfor -%}
{% set trusted_keys_arr = [] -%}
{% for key in NTP_KEY -%}
{% set keydata = NTP_KEY[key] -%}
{% if keydata.trusted == 'yes' -%}
{% set trusted_keys_arr = trusted_keys_arr.append(key) -%}
{% endif -%}
{% endfor %}
{% if global.authentication == 'enabled' %}
keys /etc/ntp.keys
{% if trusted_keys_arr != [] %}
trustedkey {{ trusted_keys_arr|join(' ') }}
{% endif %}
{% endif %}
{# listen on source interface if configured, else only listen on MGMT_INTERFACE,
LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 if we don't
have both of them (default is to listen on all ip addresses) -#}
interface ignore wildcard
{# Set interface to listen on:
* Set global variable for configured source interface name.
* Set global boolean to indicate if the ip of the configured source
interface is configured.
* If the source interface is configured but no ip on that
interface, then listen on another interface based on existing logic. -#}
{%- macro check_ip_on_interface(interface_name, table_name) %}
{%- set ns = namespace(valid_intf = 'false') %}
{%- if table_name %}
{%- for (name, source_prefix) in table_name|pfx_filter %}
{%- if source_prefix and name == interface_name %}
{%- set ns.valid_intf = 'true' %}
{%- endif %}
{%- endfor %}
{%- endif %}
{{ ns.valid_intf }}
{%- endmacro %}
{% set ns = namespace(source_intf = "") %}
{% set ns = namespace(source_intf_ip = 'false') %}
{% if global.src_intf %}
{% set ns.source_intf = global.src_intf %}
{% if ns.source_intf != "" %}
{% if ns.source_intf == "eth0" %}
{% set ns.source_intf_ip = 'true' %}
{% elif ns.source_intf.startswith('Vlan') %}
{% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, VLAN_INTERFACE) %}
{% elif ns.source_intf.startswith('Ethernet') %}
{% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, INTERFACE) %}
{% elif ns.source_intf.startswith('PortChannel') %}
{% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, PORTCHANNEL_INTERFACE) %}
{% elif ns.source_intf.startswith('Loopback') %}
{% set ns.source_intf_ip = check_ip_on_interface(ns.source_intf, LOOPBACK_INTERFACE) %}
{% endif %}
{% endif %}
{% endif %}
{% if ns.source_intf_ip == 'true' %}
interface listen {{ns.source_intf}}
{% elif (NTP) and NTP['global']['vrf'] == 'mgmt' %}
interface listen eth0
{% elif MGMT_INTERFACE %}
{% for (mgmt_intf, mgmt_prefix) in MGMT_INTERFACE|pfx_filter %}
interface listen {{ mgmt_prefix | ip }}
{% endfor %}
{% elif LOOPBACK_INTERFACE %}
{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %}
{% if prefix | ipv4 and name == 'Loopback0' %}
interface listen {{ prefix | ip }}
{% endif %}
{% endfor %}
{% else %}
interface listen eth0
{% endif %}
interface listen 127.0.0.1
{# Access control options -#}
{% set options = '' -%}
{# Allow additional servers mobilization from the pool. Otherwise we don't need
that -#}
{% if ns.is_pools == false -%}
{% set options = options ~ ' nopeer' -%}
{% endif -%}
{# Disable NTP server functionality. Should stay on when dhcp is enabled -#}
{# {% if global.server_role == 'disabled' and global.dhcp == 'disabled' -%}
{% set options = options ~ ' ignore' -%}
{% endif -%} #}
# Access control configuration
# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod limited notrap nomodify noquery{{ options }}
restrict -6 default kod limited notrap nomodify noquery{{ options }}
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1