diff --git a/changelogs/fragments/T6894-ntp-integration-tests.yml b/changelogs/fragments/T6894-ntp-integration-tests.yml new file mode 100644 index 00000000..f5ad209b --- /dev/null +++ b/changelogs/fragments/T6894-ntp-integration-tests.yml @@ -0,0 +1,5 @@ +--- +minor_changes: + - Added ntp options for 1.5+ (interleave, ptp) + - Synchronized argspec and docs with core module + - Fix integration tests for 1.3+ diff --git a/docs/vyos.vyos.vyos_ntp_global_module.rst b/docs/vyos.vyos.vyos_ntp_global_module.rst index 582aa17f..2975149d 100644 --- a/docs/vyos.vyos.vyos_ntp_global_module.rst +++ b/docs/vyos.vyos.vyos_ntp_global_module.rst @@ -1,967 +1,973 @@ .. _vyos.vyos.vyos_ntp_global_module: ************************* vyos.vyos.vyos_ntp_global ************************* **NTP global resource module** Version added: 1.0.0 .. contents:: :local: :depth: 1 Synopsis -------- - This module manages ntp configuration on devices running Vyos Parameters ---------- .. raw:: html
Parameter Choices/Defaults Comments
config
dictionary
List of configurations for ntp module
allow_clients
list / elements=string
Network Time Protocol (NTP) server options
listen_addresses
list / elements=string
local IP addresses for service to listen on
servers
list / elements=dictionary
Network Time Protocol (NTP) server
options
list / elements=string
    Choices: -
  • noselect
  • dynamic
  • +
  • noselect
  • pool
  • preempt
  • prefer
  • +
  • nts
  • +
  • ptp
  • +
  • interleave
server options for NTP
-
`dynamic` changed to `pool` after v1.3
+
`pool` replaces `dynamic` in Vyos 1.3
+
`preempt` is only available in Vyos 1.3 and earlier
+
`nts` was added in Vyos 1.4
+
`ptp` and `interleave` were added in Vyos 1.5
server
string
-
server name for NTP
+
server name or address for NTP
running_config
string
This option is used only with state parsed.
The value of this option should be the output received from the VYOS device by executing the command show configuration commands | grep ntp.
The states replaced and overridden have identical behaviour for this module.
The state parsed reads the configuration from show configuration commands | grep ntp option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
state
string
    Choices:
  • deleted
  • merged ←
  • overridden
  • replaced
  • gathered
  • rendered
  • parsed
The state the configuration should be left in.

Notes ----- .. note:: - - Tested against vyos 1.3 + - Tested against vyos 1.3.8 - This module works with connection ``network_cli``. - VyOS v.1.4+ uses chronyd, and path changes from `system` to `service` Examples -------- .. code-block:: yaml # # ------------------- # # 1. Using merged # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # Task # # ------------- - name: Replace the existing ntp config with the new config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.6.6.0/24 listen_addresses: - 10.1.3.1 servers: - server: 203.0.113.0 options: - prefer # Task output: # ------------- # "after": { # "allow_clients": [ # "10.6.6.0/24" # ], # "listen_addresses": [ # "10.1.3.1" # ], # "servers": [ # { # "server": "ser", # "options": [ # "prefer" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # }, # "changed": true, # "commands": [ # "set service ntp allow-clients address 10.6.6.0/24", # "set service ntp listen-address 10.1.3.1", # "set service ntp server 203.0.113.0 prefer" # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.6.6.0/24' # set service ntp listen-address '10.1.3.1' # set service ntp server 203.0.113.0 prefer, # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 2. Using replaced # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.4.9.0/24' # set service ntp allow-clients address '10.4.7.0/24' # set service ntp allow-clients address '10.1.2.0/24' # set service ntp allow-clients address '10.2.3.0/24' # set service ntp listen-address '10.1.9.16' # set service ntp listen-address '10.5.3.2' # set service ntp listen-address '10.7.9.21' # set service ntp listen-address '10.8.9.4' # set service ntp listen-address '10.4.5.1' # set service ntp server 10.3.6.5 noselect # set service ntp server 10.3.6.5 dynamic # set service ntp server 10.3.6.5 preempt # set service ntp server 10.3.6.5 prefer # set service ntp server server4 noselect # set service ntp server server4 dynamic # set service ntp server server5 # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # Task # # ------------- - name: Replace the existing ntp config with the new config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.6.6.0/24 listen_addresses: - 10.1.3.1 servers: - server: 203.0.113.0 options: - prefer state: replaced # # Task output: # # ------------- # "after": { # "allow_clients": [ # "10.6.6.0/24" # ], # "listen_addresses": [ # "10.1.3.1" # ], # "servers": [ # { # "server": "ser", # "options": [ # "prefer" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # "allow_clients": [ # "10.4.7.0/24", # "10.2.3.0/24", # "10.1.2.0/24", # "10.4.9.0/24" # ], # "listen_addresses": [ # "10.7.9.21", # "10.4.5.1", # "10.5.3.2", # "10.8.9.4", # "10.1.9.16" # ], # "servers": [ # { # "server": "10.3.6.5", # "options": [ # "noselect", # "dynamic", # "preempt", # "prefer" # ] # }, # { # "server": "server4", # "options": [ # "noselect", # "dynamic" # ] # }, # { # "server": "server5" # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "changed": true, # "commands": [ # "delete service ntp allow-clients address 10.4.7.0/24", # "delete service ntp allow-clients address 10.2.3.0/24", # "delete service ntp allow-clients address 10.1.2.0/24", # "delete service ntp allow-clients address 10.4.9.0/24", # "delete service ntp listen-address 10.7.9.21", # "delete service ntp listen-address 10.4.5.1", # "delete service ntp listen-address 10.5.3.2", # "delete service ntp listen-address 10.8.9.4", # "delete service ntp listen-address 10.1.9.16", # "delete service ntp server 10.3.6.5", # "delete service ntp server server4", # "delete service ntp server server5", # "set service ntp allow-clients address 10.6.6.0/24", # "set service ntp listen-address 10.1.3.1", # "set service ntp server 203.0.113.0 prefer" # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.6.6.0/24' # set service ntp listen-address '10.1.3.1' # set service ntp server 203.0.113.0 prefer, # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 3. Using overridden # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.6.6.0/24' # set service ntp listen-address '10.1.3.1' # set service ntp server 203.0.113.0 prefer, # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # Task # ------------- - name: Override ntp config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.3.3.0/24 listen_addresses: - 10.7.8.1 servers: - server: server1 options: - dynamic - prefer - server: server2 options: - noselect - preempt - server: serv state: overridden # # Task output: # # ------------- # "after": { # "allow_clients": [ # "10.3.3.0/24" # ], # "listen_addresses": [ # "10.7.8.1" # ], # "servers": [ # { # "server": "serv" # }, # { # "server": "server1", # "options": [ # "dynamic", # "prefer" # ] # }, # { # "server": "server2", # "options": [ # "noselect", # "preempt" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # "allow_clients": [ # "10.6.6.0/24" # ], # "listen_addresses": [ # "10.1.3.1" # ], # "servers": [ # { # "server": "ser", # "options": [ # "prefer" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "changed": true, # "commands": [ # "delete service ntp allow-clients address 10.6.6.0/24", # "delete service ntp listen-address 10.1.3.1", # "delete service ntp server ser", # "set service ntp allow-clients address 10.3.3.0/24", # "set service ntp listen-address 10.7.8.1", # "set service ntp server server1 dynamic", # "set service ntp server server1 prefer", # "set service ntp server server2 noselect", # "set service ntp server server2 preempt", # "set service ntp server serv" # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # 4. Using gathered # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # Task # ------------- - name: Gather ntp config vyos.vyos.vyos_ntp_global: state: gathered # # Task output: # # ------------- # "gathered": { # "allow_clients": [ # "10.3.3.0/24" # ], # "listen_addresses": [ # "10.7.8.1" # ], # "servers": [ # { # "server": "serv" # }, # { # "server": "server1", # "options": [ # "dynamic", # "prefer" # ] # }, # { # "server": "server2", # "options": [ # "noselect", # "preempt" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # } # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 5. Using deleted # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # Task # # ------------- - name: Delete ntp config vyos.vyos.vyos_ntp_global: state: deleted # # Task output: # # ------------- # "after": { # "servers": [ # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # "allow_clients": [ # "10.3.3.0/24" # ], # "listen_addresses": [ # "10.7.8.1" # ], # "servers": [ # { # "server": "serv" # }, # { # "server": "server1", # "options": [ # "dynamic", # "prefer" # ] # }, # { # "server": "server2", # "options": [ # "noselect", # "preempt" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "changed": true, # "commands": [ # "delete service ntp allow-clients", # "delete service ntp listen-address", # "delete service ntp server serv", # "delete service ntp server server1", # "delete service ntp server server2" # # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 6. Using rendered # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # Task # ------------- - name: Render ntp config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.7.7.0/24 - 10.8.8.0/24 listen_addresses: - 10.7.9.1 servers: - server: server7 - server: server45 options: - noselect - prefer - pool - server: time1.vyos.net - server: time2.vyos.net - server: time3.vyos.net state: rendered # # Task output: # # ------------- # "rendered": [ # "set service ntp allow-clients address 10.7.7.0/24", # "set service ntp allow-clients address 10.8.8.0/24", # "set service ntp listen-address 10.7.9.1", # "set service ntp server server7", # "set service ntp server server45 noselect", # "set service ntp server server45 prefer", # "set service ntp server server45 pool", # "set service ntp server time1.vyos.net", # "set service ntp server time2.vyos.net", # "set service ntp server time3.vyos.net" # ] # # ------------------- # # 7. Using parsed # # ------------------- # # sample_config.cfg: # # ------------- # "set service ntp allow-clients address 10.7.7.0/24", # "set service ntp listen-address 10.7.9.1", # "set service ntp server server45 noselect", # "set service ntp allow-clients addres 10.8.6.0/24", # "set service ntp listen-address 10.5.4.1", # "set service ntp server server45 dynamic", # "set service ntp server time1.vyos.net", # "set service ntp server time2.vyos.net", # "set service ntp server time3.vyos.net" # Task: # ------------- - name: Parse externally provided ntp configuration vyos.vyos.vyos_ntp_global: running_config: "{{ lookup('file', './sample_config.cfg') }}" state: parsed # # Task output: # # ------------- # parsed = { # "allow_clients": [ # "10.7.7.0/24", # "10.8.6.0/24 # ], # "listen_addresses": [ # "10.5.4.1", # "10.7.9.1" # ], # "servers": [ # { # "server": "server45", # "options": [ # "noselect", # "dynamic" # # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # # ] # } Return Values ------------- Common return values are documented `here `_, the following are the fields unique to this module: .. raw:: html
Key Returned Description
after
dictionary
when changed
The resulting configuration after module execution.

Sample:
This output will always be in the same format as the module argspec.
before
dictionary
when state is merged, replaced, overridden, deleted or purged
The configuration prior to the module execution.

Sample:
This output will always be in the same format as the module argspec.
commands
list
when state is merged, replaced, overridden, deleted or purged
The set of commands pushed to the remote device.

Sample:
['set system ntp server server1 dynamic', 'set system ntp server server1 prefer', 'set system ntp server server2 noselect', 'set system ntp server server2 preempt', 'set system ntp server server_add preempt']
gathered
list
when state is gathered
Facts about the network resource gathered from the remote device as structured data.

Sample:
This output will always be in the same format as the module argspec.
parsed
list
when state is parsed
The device native config provided in running_config option parsed into structured data as per module argspec.

Sample:
This output will always be in the same format as the module argspec.
rendered
list
when state is rendered
The provided configuration in the task rendered in device-native format (offline).

Sample:
['set system ntp server server1 dynamic', 'set system ntp server server1 prefer', 'set system ntp server server2 noselect', 'set system ntp server server2 preempt', 'set system ntp server server_add preempt']


Status ------ Authors ~~~~~~~ - Varshitha Yataluru (@YVarshitha) diff --git a/plugins/module_utils/network/vyos/argspec/ntp_global/ntp_global.py b/plugins/module_utils/network/vyos/argspec/ntp_global/ntp_global.py index cbbfd22e..6940fb7e 100644 --- a/plugins/module_utils/network/vyos/argspec/ntp_global/ntp_global.py +++ b/plugins/module_utils/network/vyos/argspec/ntp_global/ntp_global.py @@ -1,74 +1,77 @@ # -*- coding: utf-8 -*- # Copyright 2024 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type ############################################# # WARNING # ############################################# # # This file is auto generated by the # cli_rm_builder. # # Manually editing this file is not advised. # # To update the argspec make the desired changes # in the module docstring and re-run # cli_rm_builder. # ############################################# """ The arg spec for the vyos_ntp_global module """ class Ntp_globalArgs(object): # pylint: disable=R0903 """The arg spec for the vyos_ntp_global module""" argument_spec = { "config": { "type": "dict", "options": { "allow_clients": {"type": "list", "elements": "str"}, "listen_addresses": {"type": "list", "elements": "str"}, "servers": { "type": "list", "elements": "dict", "options": { "server": {"type": "str"}, "options": { "type": "list", "elements": "str", "choices": [ - "noselect", "dynamic", + "noselect", "pool", "preempt", "prefer", + "nts", + "ptp", + "interleave", ], }, }, }, }, }, "running_config": {"type": "str"}, "state": { "type": "str", "choices": [ "deleted", "merged", "overridden", "replaced", "gathered", "rendered", "parsed", ], "default": "merged", }, } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py b/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py index 0af1af58..5d294063 100644 --- a/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py +++ b/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py @@ -1,203 +1,205 @@ # # -*- coding: utf-8 -*- # Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # from __future__ import absolute_import, division, print_function __metaclass__ = type """ The vyos_ntp config file. It is in this file where the current configuration (as dict) is compared to the provided configuration (as dict) and the command set necessary to bring the current configuration to its desired end-state is created. """ from ansible.module_utils.six import iteritems from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( ResourceModule, ) from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( dict_merge, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ntp_global import ( NtpTemplate, ) - +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import ( + LooseVersion, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import LooseVersion - class Ntp_global(ResourceModule): """ The vyos_ntp config class """ def __init__(self, module): super(Ntp_global, self).__init__( empty_fact_val={}, facts_module=Facts(module), module=module, resource="ntp_global", tmplt=NtpTemplate(), ) self.parsers = [ "allow_clients", "listen_addresses", "server", "options", "allow_clients_delete", "listen_addresses_delete", ] def execute_module(self): """Execute the module :rtype: A dictionary :returns: The result from module execution """ if self.state not in ["parsed", "gathered"]: self.generate_commands() self.run_commands() return self.result def generate_commands(self): """Generate configuration commands to send based on want, have and desired state. """ + if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"): + path = "service" + ac = "allow-client" + else: + path = "system" + ac = "allow-clients" + + self._tmplt.set_ntp_path(path) + self._tmplt.set_ntp_ac(ac) + wantd = self._ntp_list_to_dict(self.want) haved = self._ntp_list_to_dict(self.have) # if state is merged, merge want onto have and then compare if self.state == "merged": wantd = dict_merge(haved, wantd) # if state is deleted, empty out wantd and set haved to wantd if self.state == "deleted": haved = {k: v for k, v in iteritems(haved) if k in wantd or not wantd} wantd = {} commandlist = self._commandlist(haved) servernames = self._servernames(haved) # removing the servername and commandlist from the list after deleting it from haved + # iterate through the top-level items to delete for k, have in iteritems(haved): if k not in wantd: for hk, hval in iteritems(have): if hk == "allow_clients" and hk in commandlist: self.commands.append( self._tmplt.render({"": hk}, "allow_clients_delete", True), ) commandlist.remove(hk) elif hk == "listen_addresses" and hk in commandlist: self.commands.append( self._tmplt.render({"": hk}, "listen_addresses_delete", True), ) commandlist.remove(hk) elif hk == "server" and have["server"] in servernames: self._compareoverride(want={}, have=have) servernames.remove(have["server"]) - - # remove existing config for overridden,replaced and deleted + # if everything is deleted add the delete command for {path} ntp + # this should be equiv: servernames == [] and commandlist == ["server"]: + if wantd == {} and haved != {}: + self.commands.append( + self._tmplt.render({}, "service_delete", True), + ) + + # remove existing config for overridden and replaced # Getting the list of the server names from haved # to avoid the duplication of overridding/replacing the servers if self.state in ["overridden", "replaced"]: commandlist = self._commandlist(haved) servernames = self._servernames(haved) for k, have in iteritems(haved): - if k not in wantd and "server" not in have: - self._compareoverride(want={}, have=have) - # removing the servername from the list after deleting it from haved - elif k not in wantd and have["server"] in servernames: - self._compareoverride(want={}, have=have) - servernames.remove(have["server"]) + if k not in wantd: + if "server" not in have: + self._compareoverride(want={}, have=have) + # removing the servername from the list after deleting it from haved + elif have["server"] in servernames: + self._compareoverride(want={}, have=have) + servernames.remove(have["server"]) for k, want in iteritems(wantd): self._compare(want=want, have=haved.pop(k, {})) - if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"): - path = "service" - ac = "allow-client" - else: - path = "system" - ac = "allow-clients" - - if self.commands: - self.commands = [cl.replace('%%path%%', path) for cl in self.commands] - self.commands = [nc.replace('%%ac%%', ac) for nc in self.commands] - def _compare(self, want, have): """Leverages the base class `compare()` method and populates the list of commands to be run by comparing the `want` and `have` data with the `parsers` defined for the Ntp network resource. """ if "options" in want: self.compare(parsers="options", want=want, have=have) else: self.compare(parsers=self.parsers, want=want, have=have) def _compareoverride(self, want, have): # do not delete configuration with options level for i, val in iteritems(have): if i == "options": pass else: self.compare(parsers=i, want={}, have=have) def _ntp_list_to_dict(self, entry): servers_dict = {} for k, data in iteritems(entry): if k == "servers": for value in data: if "options" in value: result = self._serveroptions_list_to_dict(value) for res, resvalue in iteritems(result): servers_dict.update({res: resvalue}) else: servers_dict.update({value["server"]: value}) else: for value in data: servers_dict.update({"ip_" + value: {k: value}}) return servers_dict def _serveroptions_list_to_dict(self, entry): serveroptions_dict = {} for Opk, Op in iteritems(entry): if Opk == "options": for val in Op: dict = {} dict.update({"server": entry["server"]}) dict.update({Opk: val}) serveroptions_dict.update({entry["server"] + "_" + val: dict}) return serveroptions_dict def _commandlist(self, haved): commandlist = [] for k, have in iteritems(haved): for ck, cval in iteritems(have): if ck != "options" and ck not in commandlist: commandlist.append(ck) return commandlist def _servernames(self, haved): servernames = [] for k, have in iteritems(haved): for sk, sval in iteritems(have): - if sk == "server" and sval not in [ - "0.pool.ntp.org", - "1.pool.ntp.org", - "2.pool.ntp.org", - ]: - if sval not in servernames: - servernames.append(sval) + if sk != "options" and sval not in servernames: + servernames.append(sval) return servernames diff --git a/plugins/module_utils/network/vyos/rm_templates/ntp_global.py b/plugins/module_utils/network/vyos/rm_templates/ntp_global.py index 1e011dd9..e9d8a0cb 100644 --- a/plugins/module_utils/network/vyos/rm_templates/ntp_global.py +++ b/plugins/module_utils/network/vyos/rm_templates/ntp_global.py @@ -1,135 +1,169 @@ # -*- coding: utf-8 -*- # Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type """ The Ntp parser templates file. This contains a list of parser definitions and associated functions that facilitates both facts gathering and native command generation for the given network resource. """ import re from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) class NtpTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} + self._overrides = { # 1.4+ by default + "_path": "service", # 1.4 or greater, "system" for 1.3 or less + "_ac": "allow-client", # 1.4 or greater, "allow-clients" for 1.3 or less + } super(NtpTemplate, self).__init__(lines=lines, tmplt=self, prefix=prefix, module=module) + def set_ntp_path(self, path: str): + """set_ntp_path""" + self._overrides["_path"] = path + + def set_ntp_ac(self, ac: str): + """set_ntp_ac""" + self._overrides["_ac"] = ac + + def render(self, data, parser_name, negate=False): + """render""" + # add path to the data before rendering + data = data.copy() + data.update(self._overrides) + # call the original method + return super(NtpTemplate, self).render(data, parser_name, negate) + # fmt: off PARSERS = [ # set system ntp allow_clients address
{ "name": "allow_clients", "getval": re.compile( r""" - ^set\s(?Psystem|service)?\sntp\s(?Pallow-clients|allow-client)?\saddress (\s(?P\S+))? + ^set\s(?Psystem|service)\sntp\s(?Pallow-clients|allow-client)\saddress (\s(?P\S+))? $""", re.VERBOSE, ), - "setval": "%%path%% ntp %%ac%% address {{allow_clients}}", + "setval": "{{_path}} ntp {{_ac}} address {{allow_clients}}", "result": { "allow_clients": ["{{ipaddress}}"], }, }, # set system ntp allow_clients { "name": "allow_clients_delete", "getval": re.compile( r""" - ^set\s(?Psystem|service)?\sntp\s(?Pallow-clients|allow-client)? + ^set\s(?Psystem|service)\sntp\s(?Pallow-clients|allow-client) $""", re.VERBOSE, ), - "setval": "%%path%% ntp %%ac%%", + "setval": "{{_path}} ntp {{_ac}}", "result": { }, }, # set system ntp listen_address
{ "name": "listen_addresses", "getval": re.compile( r""" - ^set\s(?Psystem|service)?\sntp\slisten-address (\s(?P\S+))? + ^set\s(?Psystem|service)\sntp\slisten-address (\s(?P\S+))? $""", re.VERBOSE, ), - "setval": "%%path%% ntp listen-address {{listen_addresses}}", + "setval": "{{_path}} ntp listen-address {{listen_addresses}}", "result": { "listen_addresses": ["{{ip_address}}"], }, }, # set system ntp listen_address { "name": "listen_addresses_delete", "getval": re.compile( r""" - ^set\s(?Psystem|service)?\sntp\slisten-address + ^set\s(?Psystem|service)\sntp\slisten-address + $""", + re.VERBOSE, + ), + "setval": "{{_path}} ntp listen-address", + "result": { + }, + }, + + # set {{path}} ntp - for deleting the ntp configuration + { + "name": "service_delete", + "getval": re.compile( + r""" + ^set\s(?Psystem|service)\sntp$ $""", re.VERBOSE, ), - "setval": "%%path%% ntp listen-address", + "setval": "{{_path}} ntp", "result": { }, }, # set system ntp server { "name": "server", "getval": re.compile( r""" - ^set\s(?Psystem|service)?\sntp\sserver (\s(?P\S+))? + ^set\s(?Psystem|service)\sntp\sserver (\s(?P\S+)) $""", re.VERBOSE, ), - "setval": "%%path%% ntp server {{server}}", + "setval": "{{_path}} ntp server {{server}}", "result": { "servers": { "{{name}}": { "server": "{{name}}", }, }, }, }, # set system ntp server { "name": "options", "getval": re.compile( r""" - ^set\s(?Psystem|service)?\sntp\sserver + ^set\s(?Psystem|service)\sntp\sserver \s(?P\S+) - \s(?Pnoselect|dynamic|pool|preempt|prefer)? + \s(?Pdynamic|preempt|pool|noselect|prefer|nts|interleave|ptp) $""", re.VERBOSE, ), - "setval": "%%path%% ntp server {{server}} {{options}}", + "setval": "{{_path}} ntp server {{server}} {{options}}", "result": { "servers": { "{{name}}": { "server": "{{name}}", "options": ["{{options}}"], }, }, }, }, ] # fmt: on diff --git a/plugins/modules/vyos_ntp_global.py b/plugins/modules/vyos_ntp_global.py index 4fd9891b..cad08a68 100644 --- a/plugins/modules/vyos_ntp_global.py +++ b/plugins/modules/vyos_ntp_global.py @@ -1,806 +1,812 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # Copyright 2024 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ The module file for vyos_ntp_global """ from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = """ module: vyos_ntp_global version_added: 1.0.0 short_description: NTP global resource module description: - This module manages ntp configuration on devices running Vyos author: - Varshitha Yataluru (@YVarshitha) notes: -- Tested against vyos 1.3 +- Tested against vyos 1.3.8 - This module works with connection C(network_cli). - "VyOS v.1.4+ uses chronyd, and path changes from `system` to `service`" options: config: description: List of configurations for ntp module type: dict suboptions: allow_clients: description: Network Time Protocol (NTP) server options type: list elements: str listen_addresses: description: local IP addresses for service to listen on type: list elements: str servers: description: Network Time Protocol (NTP) server type: list elements: dict suboptions: server: - description: server name for NTP + description: server name or address for NTP type: str options: description: - - server options for NTP - - "`dynamic` changed to `pool` after v1.3" + - "server options for NTP" + - "`pool` replaces `dynamic` in Vyos 1.3" + - "`preempt` is only available in Vyos 1.3 and earlier" + - "`nts` was added in Vyos 1.4" + - "`ptp` and `interleave` were added in Vyos 1.5" type: list elements: str choices: - - noselect - dynamic + - noselect - pool - preempt - prefer + - nts + - ptp + - interleave running_config: description: - This option is used only with state I(parsed). - The value of this option should be the output received from the VYOS device by executing the command B(show configuration commands | grep ntp). - The states I(replaced) and I(overridden) have identical behaviour for this module. - The state I(parsed) reads the configuration from C(show configuration commands | grep ntp) option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the I(parsed) key within the result. type: str state: description: - The state the configuration should be left in. type: str choices: - deleted - merged - overridden - replaced - gathered - rendered - parsed default: merged """ EXAMPLES = """ # # ------------------- # # 1. Using merged # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # Task # # ------------- - name: Replace the existing ntp config with the new config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.6.6.0/24 listen_addresses: - 10.1.3.1 servers: - server: 203.0.113.0 options: - prefer # Task output: # ------------- # "after": { # "allow_clients": [ # "10.6.6.0/24" # ], # "listen_addresses": [ # "10.1.3.1" # ], # "servers": [ # { # "server": "ser", # "options": [ # "prefer" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # }, # "changed": true, # "commands": [ # "set service ntp allow-clients address 10.6.6.0/24", # "set service ntp listen-address 10.1.3.1", # "set service ntp server 203.0.113.0 prefer" # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.6.6.0/24' # set service ntp listen-address '10.1.3.1' # set service ntp server 203.0.113.0 prefer, # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 2. Using replaced # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.4.9.0/24' # set service ntp allow-clients address '10.4.7.0/24' # set service ntp allow-clients address '10.1.2.0/24' # set service ntp allow-clients address '10.2.3.0/24' # set service ntp listen-address '10.1.9.16' # set service ntp listen-address '10.5.3.2' # set service ntp listen-address '10.7.9.21' # set service ntp listen-address '10.8.9.4' # set service ntp listen-address '10.4.5.1' # set service ntp server 10.3.6.5 noselect # set service ntp server 10.3.6.5 dynamic # set service ntp server 10.3.6.5 preempt # set service ntp server 10.3.6.5 prefer # set service ntp server server4 noselect # set service ntp server server4 dynamic # set service ntp server server5 # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # Task # # ------------- - name: Replace the existing ntp config with the new config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.6.6.0/24 listen_addresses: - 10.1.3.1 servers: - server: 203.0.113.0 options: - prefer state: replaced # # Task output: # # ------------- # "after": { # "allow_clients": [ # "10.6.6.0/24" # ], # "listen_addresses": [ # "10.1.3.1" # ], # "servers": [ # { # "server": "ser", # "options": [ # "prefer" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # "allow_clients": [ # "10.4.7.0/24", # "10.2.3.0/24", # "10.1.2.0/24", # "10.4.9.0/24" # ], # "listen_addresses": [ # "10.7.9.21", # "10.4.5.1", # "10.5.3.2", # "10.8.9.4", # "10.1.9.16" # ], # "servers": [ # { # "server": "10.3.6.5", # "options": [ # "noselect", # "dynamic", # "preempt", # "prefer" # ] # }, # { # "server": "server4", # "options": [ # "noselect", # "dynamic" # ] # }, # { # "server": "server5" # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "changed": true, # "commands": [ # "delete service ntp allow-clients address 10.4.7.0/24", # "delete service ntp allow-clients address 10.2.3.0/24", # "delete service ntp allow-clients address 10.1.2.0/24", # "delete service ntp allow-clients address 10.4.9.0/24", # "delete service ntp listen-address 10.7.9.21", # "delete service ntp listen-address 10.4.5.1", # "delete service ntp listen-address 10.5.3.2", # "delete service ntp listen-address 10.8.9.4", # "delete service ntp listen-address 10.1.9.16", # "delete service ntp server 10.3.6.5", # "delete service ntp server server4", # "delete service ntp server server5", # "set service ntp allow-clients address 10.6.6.0/24", # "set service ntp listen-address 10.1.3.1", # "set service ntp server 203.0.113.0 prefer" # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.6.6.0/24' # set service ntp listen-address '10.1.3.1' # set service ntp server 203.0.113.0 prefer, # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 3. Using overridden # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.6.6.0/24' # set service ntp listen-address '10.1.3.1' # set service ntp server 203.0.113.0 prefer, # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # Task # ------------- - name: Override ntp config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.3.3.0/24 listen_addresses: - 10.7.8.1 servers: - server: server1 options: - dynamic - prefer - server: server2 options: - noselect - preempt - server: serv state: overridden # # Task output: # # ------------- # "after": { # "allow_clients": [ # "10.3.3.0/24" # ], # "listen_addresses": [ # "10.7.8.1" # ], # "servers": [ # { # "server": "serv" # }, # { # "server": "server1", # "options": [ # "dynamic", # "prefer" # ] # }, # { # "server": "server2", # "options": [ # "noselect", # "preempt" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # "allow_clients": [ # "10.6.6.0/24" # ], # "listen_addresses": [ # "10.1.3.1" # ], # "servers": [ # { # "server": "ser", # "options": [ # "prefer" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "changed": true, # "commands": [ # "delete service ntp allow-clients address 10.6.6.0/24", # "delete service ntp listen-address 10.1.3.1", # "delete service ntp server ser", # "set service ntp allow-clients address 10.3.3.0/24", # "set service ntp listen-address 10.7.8.1", # "set service ntp server server1 dynamic", # "set service ntp server server1 prefer", # "set service ntp server server2 noselect", # "set service ntp server server2 preempt", # "set service ntp server serv" # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # 4. Using gathered # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # Task # ------------- - name: Gather ntp config vyos.vyos.vyos_ntp_global: state: gathered # # Task output: # # ------------- # "gathered": { # "allow_clients": [ # "10.3.3.0/24" # ], # "listen_addresses": [ # "10.7.8.1" # ], # "servers": [ # { # "server": "serv" # }, # { # "server": "server1", # "options": [ # "dynamic", # "prefer" # ] # }, # { # "server": "server2", # "options": [ # "noselect", # "preempt" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # } # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 5. Using deleted # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp allow-clients address '10.3.3.0/24' # set service ntp listen-address '10.7.8.1' # set service ntp server serv # set service ntp server server1 dynamic # set service ntp server server1 prefer # set service ntp server server2 noselect # set service ntp server server2 preempt # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # Task # # ------------- - name: Delete ntp config vyos.vyos.vyos_ntp_global: state: deleted # # Task output: # # ------------- # "after": { # "servers": [ # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "before": { # "allow_clients": [ # "10.3.3.0/24" # ], # "listen_addresses": [ # "10.7.8.1" # ], # "servers": [ # { # "server": "serv" # }, # { # "server": "server1", # "options": [ # "dynamic", # "prefer" # ] # }, # { # "server": "server2", # "options": [ # "noselect", # "preempt" # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # ] # }, # "changed": true, # "commands": [ # "delete service ntp allow-clients", # "delete service ntp listen-address", # "delete service ntp server serv", # "delete service ntp server server1", # "delete service ntp server server2" # # ] # After state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # # ------------------- # # 6. Using rendered # # ------------------- # # Before state: # # ------------- # vyos@vyos:~$ show configuration commands | grep ntp # set service ntp server time1.vyos.net # set service ntp server time2.vyos.net # set service ntp server time3.vyos.net # vyos@vyos:~$ # Task # ------------- - name: Render ntp config vyos.vyos.vyos_ntp_global: config: allow_clients: - 10.7.7.0/24 - 10.8.8.0/24 listen_addresses: - 10.7.9.1 servers: - server: server7 - server: server45 options: - noselect - prefer - pool - server: time1.vyos.net - server: time2.vyos.net - server: time3.vyos.net state: rendered # # Task output: # # ------------- # "rendered": [ # "set service ntp allow-clients address 10.7.7.0/24", # "set service ntp allow-clients address 10.8.8.0/24", # "set service ntp listen-address 10.7.9.1", # "set service ntp server server7", # "set service ntp server server45 noselect", # "set service ntp server server45 prefer", # "set service ntp server server45 pool", # "set service ntp server time1.vyos.net", # "set service ntp server time2.vyos.net", # "set service ntp server time3.vyos.net" # ] # # ------------------- # # 7. Using parsed # # ------------------- # # sample_config.cfg: # # ------------- # "set service ntp allow-clients address 10.7.7.0/24", # "set service ntp listen-address 10.7.9.1", # "set service ntp server server45 noselect", # "set service ntp allow-clients addres 10.8.6.0/24", # "set service ntp listen-address 10.5.4.1", # "set service ntp server server45 dynamic", # "set service ntp server time1.vyos.net", # "set service ntp server time2.vyos.net", # "set service ntp server time3.vyos.net" # Task: # ------------- - name: Parse externally provided ntp configuration vyos.vyos.vyos_ntp_global: running_config: "{{ lookup('file', './sample_config.cfg') }}" state: parsed # # Task output: # # ------------- # parsed = { # "allow_clients": [ # "10.7.7.0/24", # "10.8.6.0/24 # ], # "listen_addresses": [ # "10.5.4.1", # "10.7.9.1" # ], # "servers": [ # { # "server": "server45", # "options": [ # "noselect", # "dynamic" # # ] # }, # { # "server": "time1.vyos.net" # }, # { # "server": "time2.vyos.net" # }, # { # "server": "time3.vyos.net" # } # # ] # } """ RETURN = """ before: description: The configuration prior to the module execution. returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged) type: dict sample: > This output will always be in the same format as the module argspec. after: description: The resulting configuration after module execution. returned: when changed type: dict sample: > This output will always be in the same format as the module argspec. commands: description: The set of commands pushed to the remote device. returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged) type: list sample: - set system ntp server server1 dynamic - set system ntp server server1 prefer - set system ntp server server2 noselect - set system ntp server server2 preempt - set system ntp server server_add preempt rendered: description: The provided configuration in the task rendered in device-native format (offline). returned: when I(state) is C(rendered) type: list sample: - set system ntp server server1 dynamic - set system ntp server server1 prefer - set system ntp server server2 noselect - set system ntp server server2 preempt - set system ntp server server_add preempt gathered: description: Facts about the network resource gathered from the remote device as structured data. returned: when I(state) is C(gathered) type: list sample: > This output will always be in the same format as the module argspec. parsed: description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. returned: when I(state) is C(parsed) type: list sample: > This output will always be in the same format as the module argspec. """ from ansible.module_utils.basic import AnsibleModule from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ntp_global.ntp_global import ( Ntp_globalArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ntp_global.ntp_global import ( Ntp_global, ) def main(): """ Main entry point for module execution :returns: the result form module invocation """ module = AnsibleModule( argument_spec=Ntp_globalArgs.argument_spec, mutually_exclusive=[["config", "running_config"]], required_if=[ ["state", "merged", ["config"]], ["state", "replaced", ["config"]], ["state", "overridden", ["config"]], ["state", "rendered", ["config"]], ["state", "parsed", ["running_config"]], ], supports_check_mode=True, ) result = Ntp_global(module).execute_module() module.exit_json(**result) if __name__ == "__main__": main() diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/_get_version.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/_get_version.yaml new file mode 100644 index 00000000..2588b194 --- /dev/null +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/_get_version.yaml @@ -0,0 +1,28 @@ +- name: make sure to get facts + vyos.vyos.vyos_facts: + vars: + ansible_connection: ansible.netcommon.network_cli + register: vyos_facts + when: vyos_version is not defined + +- name: debug vyos_facts + debug: + var: vyos_facts + +- name: pull version from facts + set_fact: + vyos_version: "{{ vyos_facts.ansible_facts.ansible_net_version.split('-')[0].split(' ')[-1] }}" + when: vyos_version is not defined + +- name: fix '.0' versions + set_fact: + vyos_version: "{{ vyos_version }}.0" + when: vyos_version.count('.') == 1 + +- name: include correct vars + include_vars: pre-v1_4.yaml + when: vyos_version is version('1.4.0', '<', version_type='semver') + +- name: include correct vars + include_vars: v1_4.yaml + when: vyos_version is version('1.4.0', '>=', version_type='semver') diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/_parsed.cfg b/tests/integration/targets/vyos_ntp_global/tests/cli/_parsed.cfg deleted file mode 100644 index 0608aef6..00000000 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/_parsed.cfg +++ /dev/null @@ -1,5 +0,0 @@ -set system ntp server 10.3.6.5 noselect -set system ntp server 10.3.6.5 dynamic -set system ntp server 0.pool.ntp.org -set system ntp server 1.pool.ntp.org -set system ntp server 2.pool.ntp.org diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/_populate_config.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/_populate_config.yaml index 035fcba7..cf47bc1b 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/_populate_config.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/_populate_config.yaml @@ -1,13 +1,30 @@ --- -- name: setup +- name: ensure facts + include_tasks: _get_version.yaml + +- name: setup before 1.4 vyos.vyos.vyos_config: lines: - - set system ntp server server4 dynamic - - set system ntp server server5 preempt + - set system ntp server server4.example.com pool + - set system ntp server server5.example.com preempt - set system ntp server 10.3.6.5 noselect - set system ntp server 10.3.6.5 preempt - - set system ntp server server4 noselect + - set system ntp server server4.example.com noselect - set system ntp server 10.3.6.5 prefer ignore_errors: true vars: ansible_connection: ansible.netcommon.network_cli + when: vyos_version is version('1.4.0', '<', version_type='semver') +- name: setup 1.4+ + vyos.vyos.vyos_config: + lines: + - set service ntp server server4.example.com pool + - set service ntp server server5.example.com nts + - set service ntp server 10.3.6.5 noselect + - set service ntp server 10.3.6.5 nts + - set service ntp server server4.example.com noselect + - set service ntp server 10.3.6.5 prefer + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli + when: vyos_version is version('1.4.0', '>=', version_type='semver') diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/_remove_config.yaml index 6017bdb3..dce60d3e 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/_remove_config.yaml @@ -1,8 +1,11 @@ --- +- name: ensure facts + include_tasks: _get_version.yaml + - name: Remove pre-existing ntp_global config vyos.vyos.vyos_ntp_global: config: state: deleted ignore_errors: true vars: ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/deleted.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/deleted.yaml index de5cbaeb..3077bd8f 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/deleted.yaml @@ -1,37 +1,37 @@ --- - debug: msg: START vyos_ntp_global deleted integration tests on connection={{ansible_connection }} - include_tasks: _remove_config.yaml - include_tasks: _populate_config.yaml - block: - name: Delete the provided configuration register: result vyos.vyos.vyos_ntp_global: &id001 config: state: deleted - name: Assert that before dicts were correctly generated assert: that: - result.changed == true - result.commands == deleted.commands - name: Assert that the after dicts were correctly generated assert: that: - - result.after == populate.config + - result.after == {} - name: Delete the existing configuration with the provided running configuration (IDEMPOTENT) register: result vyos.vyos.vyos_ntp_global: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/merged.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/merged.yaml index 4d2994d9..c62a5005 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/merged.yaml @@ -1,54 +1,42 @@ --- - debug: msg: START vyos_ntp_global merged integration tests on connection={{ ansible_connection }} - include_tasks: _remove_config.yaml - block: - name: Merge the provided configuration with the existing running configuration register: result vyos.vyos.vyos_ntp_global: &id001 - config: - servers: - - server: server5 - - - server: server4 - options: - - noselect - - dynamic - - - server: 10.3.6.5 - options: - - noselect - - preempt - - dynamic - - prefer + config: "{{ merged.config }}" state: merged - vyos.vyos.vyos_facts: gather_network_resources: ntp_global - assert: that: - result.commands|length == 7 - result.changed == true - result.commands|symmetric_difference(merged.commands) == [] - result.after == ansible_facts['network_resources']['ntp_global'] - result.after == merged.after - name: Assert that before dicts were correctly generated assert: that: - - result.before == populate.config + - result.before == {} - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) register: result vyos.vyos.vyos_ntp_global: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false + - result['commands'] == [] + - result['before'] == ansible_facts['network_resources']['ntp_global'] always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/overridden.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/overridden.yaml index 1b8d4152..0911869b 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/overridden.yaml @@ -1,49 +1,60 @@ --- - debug: msg: START vyos_ntp_global overridden integration tests on connection={{ ansible_connection }} - include_tasks: _remove_config.yaml - include_tasks: _populate_config.yaml - block: - name: Override the existing configuration with the provided running configuration register: result vyos.vyos.vyos_ntp_global: &id001 config: servers: - - server: server1 + - server: server1.example.com options: - - dynamic + - pool - prefer - - server: server2 + - server: server2.example.com options: - noselect - - preempt + - prefer - - server: server_add + - server: server-add.example.com options: - - preempt + - prefer state: overridden - vyos.vyos.vyos_facts: gather_network_resources: ntp_global - - assert: + - name: debug result.after and overridden.after + debug: + msg: "{{ result.after }} != {{ overridden.after }}" + when: result.after != overridden.after + + - name: debug ansible_facts['network_resources']['ntp_global'] + debug: + msg: "{{ ansible_facts['network_resources']['ntp_global'] }}" + when: result.after != ansible_facts['network_resources']['ntp_global'] + + - name: Verify that the configuration was correctly overridden + assert: that: - result.changed == true - result.after == ansible_facts['network_resources']['ntp_global'] - result.after == overridden.after - name: Override the existing configuration with the provided running configuration (IDEMPOTENT) register: result vyos.vyos.vyos_ntp_global: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/parsed.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/parsed.yaml index daf20f91..725384a0 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/parsed.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/parsed.yaml @@ -1,15 +1,18 @@ --- - debug: msg: START vyos_ntp_global parsed integration tests on connection={{ ansible_connection }} +- name: ensure version + include_tasks: _get_version.yaml + - name: Provide the running configuration for parsing (config to be parsed) register: result vyos.vyos.vyos_ntp_global: - running_config: "{{ lookup('file', '_parsed.cfg') }}" + running_config: "{{ parsed.config }}" state: parsed - name: Assert that config was correctly parsed assert: that: - result.changed == false - result.parsed == parsed.after diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/rendered.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/rendered.yaml index 29ed3ada..e5de57e3 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/rendered.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/rendered.yaml @@ -1,31 +1,17 @@ --- - debug: msg: START vyos_ntp_global rendered integration tests on connection={{ ansible_connection }} - include_tasks: _remove_config.yaml - block: - name: Structure provided configuration into device specific commands register: result vyos.vyos.vyos_ntp_global: - config: - servers: - - server: server5 - - - server: server4 - options: - - noselect - - dynamic - - - server: 10.3.6.5 - options: - - noselect - - preempt - - dynamic - - prefer + config: "{{ merged.config }}" state: rendered - assert: that: - result.changed == false - result.rendered|symmetric_difference(merged.commands) == [] diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/replaced.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/replaced.yaml index 3942a340..a78d7f55 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/replaced.yaml @@ -1,39 +1,39 @@ --- - debug: msg: START vyos_ntp_global replaced integration tests on connection={{ ansible_connection }} - include_tasks: _remove_config.yaml - include_tasks: _populate_config.yaml - block: - name: Replace the provided configuration with the existing running configuration register: result vyos.vyos.vyos_ntp_global: &id001 config: servers: - - server: server_new + - server: server-new.example.com options: - prefer state: replaced - vyos.vyos.vyos_facts: gather_network_resources: ntp_global - assert: that: - result.changed == true - result.after == ansible_facts['network_resources']['ntp_global'] - result.after == replaced.after - name: Replace the provided configuration with the existing running configuration (IDEMPOTENT) register: result vyos.vyos.vyos_ntp_global: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ntp_global/tests/cli/rtt.yaml b/tests/integration/targets/vyos_ntp_global/tests/cli/rtt.yaml index 6137c211..92d6cb3c 100644 --- a/tests/integration/targets/vyos_ntp_global/tests/cli/rtt.yaml +++ b/tests/integration/targets/vyos_ntp_global/tests/cli/rtt.yaml @@ -1,69 +1,49 @@ --- - debug: msg: START vyos_ntp_global rtt integration tests on connection={{ ansible_connection }} - include_tasks: _remove_config.yaml - block: - - name: Merge the provided configuration with the existing running configuration + - name: RTT Merge the provided configuration with the existing running configuration register: baseconfig vyos.vyos.vyos_ntp_global: - config: - servers: - - server: 10.3.6.5 - options: - - noselect - - dynamic - - preempt - - prefer - - - server: server4 - options: - - noselect - - dynamic - - - server: 0.pool.ntp.org - - - server: 1.pool.ntp.org - - - server: 2.pool.ntp.org - + config: "{{ rtt.config }}" state: merged - vyos.vyos.vyos_facts: gather_network_resources: ntp_global - assert: that: - - baseconfig.commands|length == 6 + - (baseconfig.commands|length) == (rtt.commands|length) - baseconfig.changed == true - baseconfig.commands|symmetric_difference(rtt.commands) == [] - baseconfig.after == ansible_facts['network_resources']['ntp_global'] - - name: Merge the existing configuration with the provided running configuration + - name: RTT Merge the existing configuration with the provided running configuration register: result vyos.vyos.vyos_ntp_global: config: servers: - server: server1 options: - - dynamic + - pool - prefer - server: server2 options: - noselect - - preempt - - name: Revert back to base config using facts round trip + - name: RTT Revert back to base config using facts round trip register: revert vyos.vyos.vyos_ntp_global: config: "{{ ansible_facts['network_resources']['ntp_global'] }}" state: overridden - - name: Assert that config was reverted + - name: RTT Assert that config was reverted assert: that: baseconfig.after == revert.after always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ntp_global/vars/main.yaml b/tests/integration/targets/vyos_ntp_global/vars/main.yaml index 6cd65ced..43038811 100644 --- a/tests/integration/targets/vyos_ntp_global/vars/main.yaml +++ b/tests/integration/targets/vyos_ntp_global/vars/main.yaml @@ -1,107 +1,2 @@ --- -rtt: - commands: - - set system ntp server server4 dynamic - - set system ntp server 10.3.6.5 noselect - - set system ntp server 10.3.6.5 dynamic - - set system ntp server 10.3.6.5 preempt - - set system ntp server server4 noselect - - set system ntp server 10.3.6.5 prefer - -merged: - commands: - - set system ntp server server5 - - set system ntp server server4 dynamic - - set system ntp server 10.3.6.5 noselect - - set system ntp server 10.3.6.5 dynamic - - set system ntp server 10.3.6.5 preempt - - set system ntp server server4 noselect - - set system ntp server 10.3.6.5 prefer - - after: - servers: - - server: 0.pool.ntp.org - - server: 1.pool.ntp.org - - server: 10.3.6.5 - options: - - dynamic - - noselect - - preempt - - prefer - - server: 2.pool.ntp.org - - - server: server4 - options: - - dynamic - - noselect - - - server: server5 - -replaced: - commands: - - delete system ntp server 10.3.6.5 - - delete system ntp server server4 - - delete system ntp server server5 - - set system ntp server server_new prefer - - after: - servers: - - server: 0.pool.ntp.org - - server: 1.pool.ntp.org - - server: 2.pool.ntp.org - - options: - - prefer - server: server_new - -overridden: - commands: - - delete system ntp server server_new - - set system ntp server server1 dynamic - - set system ntp server server1 prefer - - set system ntp server server2 noselect - - set system ntp server server2 preempt - - set system ntp server server_add preempt - - after: - servers: - - server: 0.pool.ntp.org - - server: 1.pool.ntp.org - - server: 2.pool.ntp.org - - server: server1 - options: - - dynamic - - prefer - - - server: server2 - options: - - noselect - - preempt - - server: server_add - options: - - preempt - -deleted: - commands: - - delete system ntp server 10.3.6.5 - - delete system ntp server server4 - - delete system ntp server server5 - -parsed: - after: - servers: - - server: 0.pool.ntp.org - - - server: 1.pool.ntp.org - - server: 10.3.6.5 - options: - - dynamic - - noselect - - server: 2.pool.ntp.org - -populate: - config: - servers: - - server: 0.pool.ntp.org - - - server: 1.pool.ntp.org - - server: 2.pool.ntp.org +# only common vars here diff --git a/tests/integration/targets/vyos_ntp_global/vars/pre-v1_4.yaml b/tests/integration/targets/vyos_ntp_global/vars/pre-v1_4.yaml new file mode 100644 index 00000000..c82d85d4 --- /dev/null +++ b/tests/integration/targets/vyos_ntp_global/vars/pre-v1_4.yaml @@ -0,0 +1,139 @@ +--- +rtt: + config: + servers: + - server: 10.3.6.5 + options: + - noselect + - pool + - preempt + - prefer + + - server: server4.example.com + options: + - noselect + - pool + + commands: + - set system ntp server server4.example.com pool + - set system ntp server 10.3.6.5 noselect + - set system ntp server 10.3.6.5 pool + - set system ntp server 10.3.6.5 preempt + - set system ntp server server4.example.com noselect + - set system ntp server 10.3.6.5 prefer + +merged: + config: + servers: + - server: server5.example.com + - server: server4.example.com + options: + - noselect + - pool + - server: 10.3.6.5 + options: + - noselect + - preempt + - pool + - prefer + + commands: + - set system ntp server server5.example.com + - set system ntp server server4.example.com pool + - set system ntp server 10.3.6.5 noselect + - set system ntp server 10.3.6.5 pool + - set system ntp server 10.3.6.5 preempt + - set system ntp server server4.example.com noselect + - set system ntp server 10.3.6.5 prefer + + after: + servers: + - server: 10.3.6.5 + options: + - noselect + - pool + - preempt + - prefer + - server: server4.example.com + options: + - noselect + - pool + + - server: server5.example.com + +replaced: + commands: + - delete system ntp server 10.3.6.5 + - delete system ntp server server4.example.com + - delete system ntp server server5.example.com + - set system ntp server server-new.example.com prefer + + after: + servers: + - options: + - prefer + server: server-new.example.com + +overridden: + commands: + - delete system ntp server server-new.example.com + - set system ntp server server1.example.com pool + - set system ntp server server1.example.com prefer + - set system ntp server server2.example.com noselect + - set system ntp server server2.example.com prefer + - set system ntp server server-add.example.com prefer + + after: + servers: + - server: server-add.example.com + options: + - prefer + - server: server1.example.com + options: + - pool + - prefer + - server: server2.example.com + options: + - noselect + - prefer + +deleted: + commands: + - delete system ntp server 10.3.6.5 + - delete system ntp server server4.example.com + - delete system ntp server server5.example.com + - delete system ntp + +parsed: + config: | + set system ntp server 10.3.6.5 noselect + set system ntp server 10.3.6.5 pool + set system ntp server 0.pool.ntp.org + set system ntp server 1.pool.ntp.org + set system ntp server 2.pool.ntp.org + after: + servers: + - server: 0.pool.ntp.org + + - server: 1.pool.ntp.org + - server: 10.3.6.5 + options: + - noselect + - pool + - server: 2.pool.ntp.org + +populate: + config: + servers: + - server: server5.example.com + options: + - preempt + - server: server4.example.com + options: + - noselect + - pool + - server: 10.3.6.5 + options: + - noselect + - preempt + - prefer diff --git a/tests/integration/targets/vyos_ntp_global/vars/v1_4.yaml b/tests/integration/targets/vyos_ntp_global/vars/v1_4.yaml new file mode 100644 index 00000000..2a655bf5 --- /dev/null +++ b/tests/integration/targets/vyos_ntp_global/vars/v1_4.yaml @@ -0,0 +1,141 @@ +--- +rtt: + config: + servers: + - server: 10.3.6.5 + options: + - noselect + - nts + - pool + - prefer + + - server: server4.example.com + options: + - noselect + - pool + + commands: + - set service ntp server server4.example.com pool + - set service ntp server 10.3.6.5 noselect + - set service ntp server 10.3.6.5 nts + - set service ntp server 10.3.6.5 pool + - set service ntp server server4.example.com noselect + - set service ntp server 10.3.6.5 prefer + +merged: + config: + servers: + - server: server5.example.com + - server: server4.example.com + options: + - noselect + - pool + - server: 10.3.6.5 + options: + - noselect + - nts + - pool + - prefer + + commands: + - set service ntp server server5.example.com + - set service ntp server server4.example.com pool + - set service ntp server 10.3.6.5 noselect + - set service ntp server 10.3.6.5 nts + - set service ntp server 10.3.6.5 pool + - set service ntp server server4.example.com noselect + - set service ntp server 10.3.6.5 prefer + + after: + servers: + - server: 10.3.6.5 + options: + - noselect + - nts + - pool + - prefer + + - server: server4.example.com + options: + - noselect + - pool + + - server: server5.example.com + +replaced: + commands: + - delete service ntp server 10.3.6.5 + - delete service ntp server server4.example.com + - delete service ntp server server5.example.com + - set service ntp server server-new.example.com prefer + + after: + servers: + - options: + - prefer + server: server-new.example.com + +overridden: + commands: + - delete service ntp server server-new.example.com + - set service ntp server server1.example.com pool + - set service ntp server server1.example.com prefer + - set service ntp server server2.example.com noselect + - set service ntp server server2.example.com prefer + - set service ntp server server-add.example.com prefer + + after: + servers: + - server: server-add.example.com + options: + - prefer + + - server: server1.example.com + options: + - pool + - prefer + + - server: server2.example.com + options: + - noselect + - prefer + +deleted: + commands: + - delete service ntp server 10.3.6.5 + - delete service ntp server server4.example.com + - delete service ntp server server5.example.com + - delete service ntp + +parsed: + config: | + set service ntp server 10.3.6.5 noselect + set service ntp server 10.3.6.5 pool + set service ntp server 0.pool.ntp.org + set service ntp server 1.pool.ntp.org + set service ntp server 2.pool.ntp.org + after: + servers: + - server: 0.pool.ntp.org + - server: 1.pool.ntp.org + - server: 10.3.6.5 + options: + - noselect + - pool + - server: 2.pool.ntp.org + +populate: + config: + servers: + - server: server4.example.com + options: + - prefer + - server: server4.example.com + options: + - noselect + - pool + - server: 10.3.6.5 + options: + - noselect + - prefer + - prefer diff --git a/tests/unit/modules/network/vyos/test_vyos_ntp_global.py b/tests/unit/modules/network/vyos/test_vyos_ntp_global.py index 0bf61078..b8adeae7 100644 --- a/tests/unit/modules/network/vyos/test_vyos_ntp_global.py +++ b/tests/unit/modules/network/vyos/test_vyos_ntp_global.py @@ -1,683 +1,705 @@ # (c) 2021 Red Hat Inc. # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # Make coding more python3-ish from __future__ import absolute_import, division, print_function __metaclass__ = type from unittest.mock import patch from ansible_collections.vyos.vyos.plugins.modules import vyos_ntp_global from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_args from .vyos_module import TestVyosModule, load_fixture class TestVyosNTPModule(TestVyosModule): module = vyos_ntp_global def setUp(self): super(TestVyosNTPModule, self).setUp() self.mock_get_resource_connection_config = patch( "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", ) self.get_resource_connection_config = self.mock_get_resource_connection_config.start() self.mock_get_resource_connection_facts = patch( "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", ) self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() self.mock_execute_show_command = patch( "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ntp_global.ntp_global.Ntp_globalFacts.get_config", ) self.execute_show_command = self.mock_execute_show_command.start() self.mock_get_os_version = patch( "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ntp_global.ntp_global.get_os_version", ) self.get_os_version = self.mock_get_os_version.start() self.get_os_version.return_value = "1.2" def tearDown(self): super(TestVyosNTPModule, self).tearDown() self.mock_get_resource_connection_config.stop() self.mock_get_resource_connection_facts.stop() self.mock_execute_show_command.stop() self.mock_get_os_version.stop() def load_fixtures(self, commands=None, filename=None): if filename is None: filename = "vyos_ntp_config.cfg" def load_from_file(*args, **kwargs): output = load_fixture(filename) return output self.execute_show_command.side_effect = load_from_file def test_ntp_merged_idempotent(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24", "10.1.2.0/24"], listen_addresses=["10.2.3.1", "10.4.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect", "dynamic"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="merged", ), ) self.execute_module(changed=False, commands=[]) def test_ntp_merged(self): set_module_args( dict( config=dict( allow_clients=["10.2.2.0/24", "10.3.3.0/24"], listen_addresses=["10.3.4.1", "10.4.5.1"], servers=[ dict(server="server4", options=["dynamic", "preempt"]), dict( server="server5", options=[ "noselect", "dynamic", "preempt", "prefer", ], ), ], ), state="merged", ), ) commands = [ "set system ntp allow-clients address 10.2.2.0/24", "set system ntp allow-clients address 10.3.3.0/24", "set system ntp listen-address 10.3.4.1", "set system ntp listen-address 10.4.5.1", "set system ntp server server4 dynamic", "set system ntp server server4 preempt", "set system ntp server server5 dynamic", "set system ntp server server5 noselect", "set system ntp server server5 preempt", "set system ntp server server5 prefer", ] self.execute_module(changed=True, commands=commands) def test_ntp_replaced(self): set_module_args( dict( config=dict( allow_clients=["10.3.4.0/24", "10.4.5.0/24"], listen_addresses=["10.3.3.1", "10.4.4.1"], servers=[ dict(server="server4", options=["noselect", "prefer"]), dict( server="server6", options=[ "noselect", "dynamic", "prefer", "preempt", ], ), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="replaced", ), ) commands = [ "delete system ntp allow-clients address 10.1.1.0/24", "delete system ntp allow-clients address 10.1.2.0/24", "delete system ntp listen-address 10.2.3.1", "delete system ntp listen-address 10.4.3.1", "delete system ntp server server1", "delete system ntp server server3", "set system ntp allow-clients address 10.3.4.0/24", "set system ntp allow-clients address 10.4.5.0/24", "set system ntp listen-address 10.3.3.1", "set system ntp listen-address 10.4.4.1", "set system ntp server server4 noselect", "set system ntp server server4 prefer", "set system ntp server server6 noselect", "set system ntp server server6 dynamic", "set system ntp server server6 prefer", "set system ntp server server6 preempt", ] self.execute_module(changed=True, commands=commands) def test_ntp_replaced_idempotent(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24", "10.1.2.0/24"], listen_addresses=["10.2.3.1", "10.4.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect", "dynamic"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="replaced", ), ) self.execute_module(changed=False, commands=[]) def test_ntp_overridden(self): set_module_args( dict( config=dict( allow_clients=["10.9.9.0/24"], listen_addresses=["10.9.9.1"], servers=[ dict(server="server9"), dict(server="server6", options=["noselect", "dynamic"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="overridden", ), ) commands = [ "delete system ntp allow-clients address 10.1.1.0/24", "delete system ntp allow-clients address 10.1.2.0/24", "delete system ntp listen-address 10.2.3.1", "delete system ntp listen-address 10.4.3.1", "delete system ntp server server1", "delete system ntp server server3", "set system ntp allow-clients address 10.9.9.0/24", "set system ntp listen-address 10.9.9.1", "set system ntp server server9", "set system ntp server server6 noselect", "set system ntp server server6 dynamic", ] self.execute_module(changed=True, commands=commands) def test_ntp_overridden_idempotent(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24", "10.1.2.0/24"], listen_addresses=["10.2.3.1", "10.4.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect", "dynamic"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="overridden", ), ) self.execute_module(changed=False, commands=[]) def test_ntp_rendered(self): set_module_args( dict( config=dict( allow_clients=["10.7.7.0/24", "10.8.8.0/24"], listen_addresses=["10.7.9.1"], servers=[ dict(server="server79"), dict(server="server46", options=["noselect", "dynamic"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="rendered", ), ) rendered_commands = [ "set system ntp allow-clients address 10.7.7.0/24", "set system ntp allow-clients address 10.8.8.0/24", "set system ntp listen-address 10.7.9.1", "set system ntp server server79", "set system ntp server server46 noselect", "set system ntp server server46 dynamic", "set system ntp server time1.vyos.net", "set system ntp server time2.vyos.net", "set system ntp server time3.vyos.net", ] result = self.execute_module(changed=False) self.assertEqual( sorted(result["rendered"]), sorted(rendered_commands), result["rendered"], ) def test_ntp_parsed(self): commands = ( "set system ntp allow-clients address 10.7.7.0/24", "set system ntp allow-clients address 10.6.7.0/24", "set system ntp listen-address 10.7.9.1", "set system ntp listen-address 10.7.7.1", "set system ntp server check", "set system ntp server server46 noselect", "set system ntp server server46 prefer", "set system ntp server time1.vyos.net", "set system ntp server time2.vyos.net", "set system ntp server time3.vyos.net", ) parsed_str = "\n".join(commands) set_module_args(dict(running_config=parsed_str, state="parsed")) result = self.execute_module(changed=False) parsed_list = { "allow_clients": ["10.6.7.0/24", "10.7.7.0/24"], "listen_addresses": ["10.7.7.1", "10.7.9.1"], "servers": [ {"server": "check"}, {"server": "server46", "options": ["noselect", "prefer"]}, {"server": "time1.vyos.net"}, {"server": "time2.vyos.net"}, {"server": "time3.vyos.net"}, ], } self.assertEqual(parsed_list, result["parsed"]) def test_ntp_gathered(self): set_module_args(dict(state="gathered")) result = self.execute_module(changed=False) gathered_list = { "allow_clients": ["10.1.1.0/24", "10.1.2.0/24"], "listen_addresses": ["10.2.3.1", "10.4.3.1"], "servers": [ {"server": "server1"}, {"server": "server3", "options": ["dynamic", "noselect"]}, {"server": "time1.vyos.net"}, {"server": "time2.vyos.net"}, {"server": "time3.vyos.net"}, ], } self.assertEqual(gathered_list, result["gathered"]) def test_ntp_deleted(self): + # Delete the subsections that we include (listen_addresses and servers) set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24"], listen_addresses=["10.2.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="deleted", ), ) + commands = [ + "delete system ntp allow-clients", # 10.1.1.0/24", + "delete system ntp listen-address", # 10.2.3.1", + "delete system ntp server server1", + "delete system ntp server server3", + "delete system ntp server time1.vyos.net", + "delete system ntp server time2.vyos.net", + "delete system ntp server time3.vyos.net", + "delete system ntp", + ] + self.execute_module(changed=True, commands=commands) + + def test_ntp__all_deleted(self): + set_module_args( + dict( + config=dict(), + state="deleted", + ), + ) commands = [ "delete system ntp allow-clients", "delete system ntp listen-address", "delete system ntp server server1", "delete system ntp server server3", "delete system ntp server time1.vyos.net", "delete system ntp server time2.vyos.net", "delete system ntp server time3.vyos.net", + "delete system ntp", ] self.execute_module(changed=True, commands=commands) class TestVyosNTPModule14(TestVyosModule): module = vyos_ntp_global def setUp(self): super(TestVyosNTPModule14, self).setUp() self.mock_get_resource_connection_config = patch( "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", ) self.get_resource_connection_config = self.mock_get_resource_connection_config.start() self.mock_get_resource_connection_facts = patch( "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", ) self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() self.mock_execute_show_command = patch( "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ntp_global.ntp_global.Ntp_globalFacts.get_config", ) self.execute_show_command = self.mock_execute_show_command.start() self.mock_get_os_version = patch( "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ntp_global.ntp_global.get_os_version", ) self.get_os_version = self.mock_get_os_version.start() self.get_os_version.return_value = "1.4" def tearDown(self): super(TestVyosNTPModule14, self).tearDown() self.mock_get_resource_connection_config.stop() self.mock_get_resource_connection_facts.stop() self.mock_execute_show_command.stop() self.mock_get_os_version.stop() def load_fixtures(self, commands=None, filename=None): if filename is None: filename = "vyos_ntp_config_v14.cfg" def load_from_file(*args, **kwargs): output = load_fixture(filename) return output self.execute_show_command.side_effect = load_from_file def test_ntp_merged_idempotent(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24", "10.1.2.0/24"], listen_addresses=["10.2.3.1", "10.4.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect", "pool"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="merged", ), ) self.execute_module(changed=False, commands=[]) def test_ntp_merged(self): set_module_args( dict( config=dict( allow_clients=["10.2.2.0/24", "10.3.3.0/24"], listen_addresses=["10.3.4.1", "10.4.5.1"], servers=[ - dict(server="server4", options=["pool", "preempt"]), + dict(server="server4", options=["pool", "prefer"]), dict( server="server5", options=[ "noselect", "pool", - "preempt", + "nts", "prefer", ], ), ], ), state="merged", ), ) commands = [ "set service ntp allow-client address 10.2.2.0/24", "set service ntp allow-client address 10.3.3.0/24", "set service ntp listen-address 10.3.4.1", "set service ntp listen-address 10.4.5.1", "set service ntp server server4 pool", - "set service ntp server server4 preempt", + "set service ntp server server4 prefer", "set service ntp server server5 pool", "set service ntp server server5 noselect", - "set service ntp server server5 preempt", + "set service ntp server server5 nts", "set service ntp server server5 prefer", ] self.execute_module(changed=True, commands=commands) def test_ntp_replaced(self): set_module_args( dict( config=dict( allow_clients=["10.3.4.0/24", "10.4.5.0/24"], listen_addresses=["10.3.3.1", "10.4.4.1"], servers=[ dict(server="server4", options=["noselect", "prefer"]), dict( server="server6", options=[ "noselect", "pool", "prefer", - "preempt", + "nts", ], ), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="replaced", ), ) commands = [ "delete service ntp allow-client address 10.1.1.0/24", "delete service ntp allow-client address 10.1.2.0/24", "delete service ntp listen-address 10.2.3.1", "delete service ntp listen-address 10.4.3.1", "delete service ntp server server1", "delete service ntp server server3", "set service ntp allow-client address 10.3.4.0/24", "set service ntp allow-client address 10.4.5.0/24", "set service ntp listen-address 10.3.3.1", "set service ntp listen-address 10.4.4.1", "set service ntp server server4 noselect", "set service ntp server server4 prefer", "set service ntp server server6 noselect", "set service ntp server server6 pool", "set service ntp server server6 prefer", - "set service ntp server server6 preempt", + "set service ntp server server6 nts", ] self.execute_module(changed=True, commands=commands) def test_ntp_replaced_idempotent(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24", "10.1.2.0/24"], listen_addresses=["10.2.3.1", "10.4.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect", "pool"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="replaced", ), ) self.execute_module(changed=False, commands=[]) def test_ntp_overridden(self): set_module_args( dict( config=dict( allow_clients=["10.9.9.0/24"], listen_addresses=["10.9.9.1"], servers=[ dict(server="server9"), dict(server="server6", options=["noselect", "pool"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="overridden", ), ) commands = [ "delete service ntp allow-client address 10.1.1.0/24", "delete service ntp allow-client address 10.1.2.0/24", "delete service ntp listen-address 10.2.3.1", "delete service ntp listen-address 10.4.3.1", "delete service ntp server server1", "delete service ntp server server3", "set service ntp allow-client address 10.9.9.0/24", "set service ntp listen-address 10.9.9.1", "set service ntp server server9", "set service ntp server server6 noselect", "set service ntp server server6 pool", ] self.execute_module(changed=True, commands=commands) def test_ntp_overridden_idempotent(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24", "10.1.2.0/24"], listen_addresses=["10.2.3.1", "10.4.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect", "pool"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="overridden", ), ) self.execute_module(changed=False, commands=[]) def test_ntp_rendered(self): set_module_args( dict( config=dict( allow_clients=["10.7.7.0/24", "10.8.8.0/24"], listen_addresses=["10.7.9.1"], servers=[ dict(server="server79"), dict(server="server46", options=["noselect", "pool"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="rendered", ), ) rendered_commands = [ "set service ntp allow-client address 10.7.7.0/24", "set service ntp allow-client address 10.8.8.0/24", "set service ntp listen-address 10.7.9.1", "set service ntp server server79", "set service ntp server server46 noselect", "set service ntp server server46 pool", "set service ntp server time1.vyos.net", "set service ntp server time2.vyos.net", "set service ntp server time3.vyos.net", ] result = self.execute_module(changed=False) self.assertEqual( sorted(result["rendered"]), sorted(rendered_commands), result["rendered"], ) def test_ntp_parsed(self): commands = ( "set service ntp allow-client address 10.7.7.0/24", "set service ntp allow-client address 10.6.7.0/24", "set service ntp listen-address 10.7.9.1", "set service ntp listen-address 10.7.7.1", "set service ntp server check", "set service ntp server server46 noselect", "set service ntp server server46 prefer", "set service ntp server time1.vyos.net", "set service ntp server time2.vyos.net", "set service ntp server time3.vyos.net", ) parsed_str = "\n".join(commands) set_module_args(dict(running_config=parsed_str, state="parsed")) result = self.execute_module(changed=False) parsed_list = { "allow_clients": ["10.6.7.0/24", "10.7.7.0/24"], "listen_addresses": ["10.7.7.1", "10.7.9.1"], "servers": [ {"server": "check"}, {"server": "server46", "options": ["noselect", "prefer"]}, {"server": "time1.vyos.net"}, {"server": "time2.vyos.net"}, {"server": "time3.vyos.net"}, ], } self.assertEqual(parsed_list, result["parsed"]) def test_ntp_gathered(self): set_module_args(dict(state="gathered")) result = self.execute_module(changed=False) gathered_list = { "allow_clients": ["10.1.1.0/24", "10.1.2.0/24"], "listen_addresses": ["10.2.3.1", "10.4.3.1"], "servers": [ {"server": "server1"}, {"server": "server3", "options": ["noselect", "pool"]}, {"server": "time1.vyos.net"}, {"server": "time2.vyos.net"}, {"server": "time3.vyos.net"}, ], } self.assertEqual(gathered_list, result["gathered"]) def test_ntp_deleted(self): set_module_args( dict( config=dict( allow_clients=["10.1.1.0/24"], listen_addresses=["10.2.3.1"], servers=[ dict(server="server1"), dict(server="server3", options=["noselect"]), dict(server="time1.vyos.net"), dict(server="time2.vyos.net"), dict(server="time3.vyos.net"), ], ), state="deleted", ), ) commands = [ "delete service ntp allow-client", "delete service ntp listen-address", "delete service ntp server server1", "delete service ntp server server3", "delete service ntp server time1.vyos.net", "delete service ntp server time2.vyos.net", "delete service ntp server time3.vyos.net", + "delete service ntp", ] self.execute_module(changed=True, commands=commands)