f78cb9c55c
* 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>
164 lines
5.9 KiB
Django/Jinja
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
|