Repository URL to install this package:
Version:
6.0.0 ▾
|
#!/usr/bin/python
#
# 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 <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = """
module: ios_ntp
extends_documentation_fragment:
- cisco.ios.ios
short_description: (deprecated, removed after 2024-01-01) Manages core NTP configuration.
description:
- Manages core NTP configuration.
version_added: 1.0.0
deprecated:
alternative: ios_ntp_global
why: Updated module released with more functionality.
removed_at_date: '2024-01-01'
author:
- Federico Olivieri (@Federico87)
- Joanie Sylvain (@JoanieAda)
options:
server:
description:
- Network address of NTP server.
type: str
source_int:
description:
- Source interface for NTP packets.
type: str
acl:
description:
- ACL for peer/server access restricition.
type: str
logging:
description:
- Enable NTP logs. Data type boolean.
type: bool
default: false
auth:
description:
- Enable NTP authentication. Data type boolean.
type: bool
default: false
auth_key:
description:
- md5 NTP authentication key of tye 7.
type: str
key_id:
description:
- auth_key id. Data type string
type: str
state:
description:
- Manage the state of the resource.
default: present
choices:
- present
- absent
type: str
vrf:
description:
- VRF configuration for NTP servers
type: str
"""
EXAMPLES = """
# Set new NTP server and source interface
- cisco.ios.ios_ntp:
server: 10.0.255.10
source_int: Loopback0
logging: false
state: present
# Remove NTP ACL and logging
- cisco.ios.ios_ntp:
acl: NTP_ACL
logging: true
state: absent
# Set NTP authentication
- cisco.ios.ios_ntp:
key_id: 10
auth_key: 15435A030726242723273C21181319000A
auth: true
state: present
# Set new NTP configuration
- cisco.ios.ios_ntp:
server: 10.0.255.10
source_int: Loopback0
acl: NTP_ACL
logging: true
vrf: mgmt
key_id: 10
auth_key: 15435A030726242723273C21181319000A
auth: true
state: present
"""
RETURN = """
commands:
description: command sent to the device
returned: always
type: list
sample: ["no ntp server 10.0.255.10", "no ntp source Loopback0"]
"""
import re
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.ios import (
get_config,
load_config,
)
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.ios import (
ios_argument_spec,
)
def parse_server(line, dest):
if dest == "server":
match = re.search(
"(ntp\\sserver\\s)(vrf\\s\\w+\\s)?(\\d+\\.\\d+\\.\\d+\\.\\d+)",
line,
re.M,
)
if match.group(2) and match.group(3):
vrf = match.group(2)
server = match.group(3)
return vrf, server
if match.group(3):
vrf = None
server = match.group(3)
return vrf, server
def parse_source_int(line, dest):
if dest == "source":
match = re.search("(ntp\\ssource\\s)(\\S+)", line, re.M)
if match:
source = match.group(2)
return source
def parse_acl(line, dest):
if dest == "access-group":
match = re.search(
"ntp\\saccess-group\\s(?:peer|serve)(?:\\s+)(\\S+)", line, re.M
)
if match:
acl = match.group(1)
return acl
def parse_logging(line, dest):
if dest == "logging":
logging = dest
return logging
def parse_auth_key(line, dest):
if dest == "authentication-key":
match = re.search(
"(ntp\\sauthentication-key\\s\\d+\\smd5\\s)(\\w+)", line, re.M
)
if match:
auth_key = match.group(2)
return auth_key
def parse_key_id(line, dest):
if dest == "trusted-key":
match = re.search("(ntp\\strusted-key\\s)(\\d+)", line, re.M)
if match:
auth_key = match.group(2)
return auth_key
def parse_auth(dest):
if dest == "authenticate":
return dest
def map_config_to_obj(module):
obj_dict = dict()
obj = list()
server_list = list()
config = get_config(module, flags=["| include ntp"])
for line in config.splitlines():
match = re.search("ntp\\s(\\S+)", line, re.M)
if match:
dest = match.group(1)
server = parse_server(line, dest)
source_int = parse_source_int(line, dest)
acl = parse_acl(line, dest)
logging = parse_logging(line, dest)
auth = parse_auth(dest)
auth_key = parse_auth_key(line, dest)
key_id = parse_key_id(line, dest)
if server:
if server[0] is None:
server_list.append((server[0], server[1]))
else:
server_list.append((server[0].split()[1], server[1]))
if source_int:
obj_dict["source_int"] = source_int
if acl:
obj_dict["acl"] = acl
if logging:
obj_dict["logging"] = True
if auth:
obj_dict["auth"] = True
if auth_key:
obj_dict["auth_key"] = auth_key
if key_id:
obj_dict["key_id"] = key_id
obj_dict["server"] = server_list
obj.append(obj_dict)
return obj
def map_params_to_obj(module):
obj = list()
obj.append(
{
"state": module.params["state"],
"server": module.params["server"],
"source_int": module.params["source_int"],
"logging": module.params["logging"],
"acl": module.params["acl"],
"auth": module.params["auth"],
"auth_key": module.params["auth_key"],
"key_id": module.params["key_id"],
"vrf": module.params["vrf"],
}
)
return obj
def map_obj_to_commands(want, have, module):
commands = list()
server_have = have[0].get("server", None)
source_int_have = have[0].get("source_int", None)
acl_have = have[0].get("acl", None)
logging_have = have[0].get("logging", None)
auth_have = have[0].get("auth", None)
auth_key_have = have[0].get("auth_key", None)
key_id_have = have[0].get("key_id", None)
for w in want:
server = w["server"]
source_int = w["source_int"]
acl = w["acl"]
logging = w["logging"]
state = w["state"]
auth = w["auth"]
auth_key = w["auth_key"]
key_id = w["key_id"]
vrf = w["vrf"]
if vrf == "":
vrf = None
if state == "absent":
if server_have and (vrf, server) in server_have:
if vrf is not None:
commands.append(
"no ntp server vrf {0} {1}".format(vrf, server)
)
else:
commands.append("no ntp server {0}".format(server))
if source_int and source_int_have:
commands.append("no ntp source {0}".format(source_int))
if acl and acl_have:
commands.append("no ntp access-group peer {0}".format(acl))
if logging is True and logging_have:
commands.append("no ntp logging")
if auth is True and auth_have:
commands.append("no ntp authenticate")
if key_id and key_id_have:
commands.append("no ntp trusted-key {0}".format(key_id))
if auth_key and auth_key_have:
if key_id and key_id_have:
commands.append(
"no ntp authentication-key {0} md5 {1} 7".format(
key_id, auth_key
)
)
elif state == "present":
if server is not None and (vrf, server) not in server_have:
if vrf is not None:
commands.append(
"ntp server vrf {0} {1}".format(vrf, server)
)
else:
commands.append("ntp server {0}".format(server))
if source_int is not None and source_int != source_int_have:
commands.append("ntp source {0}".format(source_int))
if acl is not None and acl != acl_have:
commands.append("ntp access-group peer {0}".format(acl))
if (
logging is not None
and logging != logging_have
and logging is not False
):
commands.append("ntp logging")
if auth is not None and auth != auth_have and auth is not False:
commands.append("ntp authenticate")
if key_id is not None and key_id != key_id_have:
commands.append("ntp trusted-key {0}".format(key_id))
if auth_key is not None and auth_key != auth_key_have:
if key_id is not None:
commands.append(
"ntp authentication-key {0} md5 {1} 7".format(
key_id, auth_key
)
)
return commands
def main():
argument_spec = dict(
server=dict(),
source_int=dict(),
acl=dict(),
logging=dict(type="bool", default=False),
auth=dict(type="bool", default=False),
auth_key=dict(no_log=True),
key_id=dict(),
state=dict(choices=["absent", "present"], default="present"),
vrf=dict(),
)
argument_spec.update(ios_argument_spec)
module = AnsibleModule(
argument_spec=argument_spec, supports_check_mode=True
)
result = {"changed": False}
warnings = list()
if warnings:
result["warnings"] = warnings
want = map_params_to_obj(module)
have = map_config_to_obj(module)
commands = map_obj_to_commands(want, have, module)
result["commands"] = commands
if commands:
if not module.check_mode:
load_config(module, commands)
result["changed"] = True
module.exit_json(**result)
if __name__ == "__main__":
main()