diff options
author | Sagar Paul <sagpaul@redhat.com> | 2021-07-24 22:49:38 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-24 17:19:38 +0000 |
commit | 36004b2657d1c271a5c6c8ddfee0488ad36c1236 (patch) | |
tree | abe6730bc03a7e3f66a20fea020a4bf3a8bb1a02 /plugins | |
parent | 5c767d4266fe028cc0c11b05447e61ae89af9d45 (diff) | |
download | vyos-ansible-old-36004b2657d1c271a5c6c8ddfee0488ad36c1236.tar.gz vyos-ansible-old-36004b2657d1c271a5c6c8ddfee0488ad36c1236.zip |
vyos logging_global resource module (#177)
vyos logging_global resource module
SUMMARY
Logging resource module vyos_logging_global
ISSUE TYPE
New Module Pull Request
COMPONENT NAME
vyos_logging_global
Reviewed-by: Nilashish Chakraborty <nilashishchakraborty8@gmail.com>
Diffstat (limited to 'plugins')
10 files changed, 1886 insertions, 0 deletions
diff --git a/plugins/module_utils/network/vyos/argspec/logging_global/__init__.py b/plugins/module_utils/network/vyos/argspec/logging_global/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/logging_global/__init__.py diff --git a/plugins/module_utils/network/vyos/argspec/logging_global/logging_global.py b/plugins/module_utils/network/vyos/argspec/logging_global/logging_global.py new file mode 100644 index 0000000..503f723 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/logging_global/logging_global.py @@ -0,0 +1,370 @@ +# -*- 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 + +############################################# +# 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_logging_global module +""" + + +class Logging_globalArgs(object): # pylint: disable=R0903 + """The arg spec for the vyos_logging_global module""" + + argument_spec = { + "config": { + "type": "dict", + "options": { + "console": { + "type": "dict", + "options": { + "state": { + "type": "str", + "choices": ["enabled", "disabled"], + }, + "facilities": { + "type": "list", + "elements": "dict", + "options": { + "facility": { + "type": "str", + "choices": [ + "all", + "auth", + "authpriv", + "cron", + "daemon", + "kern", + "lpr", + "mail", + "mark", + "news", + "protocols", + "security", + "syslog", + "user", + "uucp", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + ], + }, + "severity": { + "type": "str", + "choices": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "all", + ], + }, + }, + }, + }, + }, + "files": { + "type": "list", + "elements": "dict", + "options": { + "path": {"type": "str"}, + "archive": { + "type": "dict", + "options": { + "state": { + "type": "str", + "choices": ["enabled", "disabled"], + }, + "file_num": {"type": "int"}, + "size": {"type": "int"}, + }, + }, + "facilities": { + "type": "list", + "elements": "dict", + "options": { + "facility": { + "type": "str", + "choices": [ + "all", + "auth", + "authpriv", + "cron", + "daemon", + "kern", + "lpr", + "mail", + "mark", + "news", + "protocols", + "security", + "syslog", + "user", + "uucp", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + ], + }, + "severity": { + "type": "str", + "choices": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "all", + ], + }, + }, + }, + }, + }, + "global_params": { + "type": "dict", + "options": { + "state": { + "type": "str", + "choices": ["enabled", "disabled"], + }, + "archive": { + "type": "dict", + "options": { + "state": { + "type": "str", + "choices": ["enabled", "disabled"], + }, + "file_num": {"type": "int"}, + "size": {"type": "int"}, + }, + }, + "facilities": { + "type": "list", + "elements": "dict", + "options": { + "facility": { + "type": "str", + "choices": [ + "all", + "auth", + "authpriv", + "cron", + "daemon", + "kern", + "lpr", + "mail", + "mark", + "news", + "protocols", + "security", + "syslog", + "user", + "uucp", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + ], + }, + "severity": { + "type": "str", + "choices": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "all", + ], + }, + }, + }, + "marker_interval": {"type": "int"}, + "preserve_fqdn": {"type": "bool"}, + }, + }, + "hosts": { + "type": "list", + "elements": "dict", + "options": { + "port": {"type": "int"}, + "facilities": { + "type": "list", + "elements": "dict", + "options": { + "facility": { + "type": "str", + "choices": [ + "all", + "auth", + "authpriv", + "cron", + "daemon", + "kern", + "lpr", + "mail", + "mark", + "news", + "protocols", + "security", + "syslog", + "user", + "uucp", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + ], + }, + "severity": { + "type": "str", + "choices": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "all", + ], + }, + "protocol": { + "type": "str", + "choices": ["udp", "tcp"], + }, + }, + }, + "hostname": {"type": "str"}, + }, + }, + "syslog": { + "type": "dict", + "options": { + "state": { + "type": "str", + "choices": ["enabled", "disabled"], + } + }, + }, + "users": { + "type": "list", + "elements": "dict", + "options": { + "username": {"type": "str"}, + "facilities": { + "type": "list", + "elements": "dict", + "options": { + "facility": { + "type": "str", + "choices": [ + "all", + "auth", + "authpriv", + "cron", + "daemon", + "kern", + "lpr", + "mail", + "mark", + "news", + "protocols", + "security", + "syslog", + "user", + "uucp", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + ], + }, + "severity": { + "type": "str", + "choices": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "all", + ], + }, + }, + }, + }, + }, + }, + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/logging_global/__init__.py b/plugins/module_utils/network/vyos/config/logging_global/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/logging_global/__init__.py diff --git a/plugins/module_utils/network/vyos/config/logging_global/logging_global.py b/plugins/module_utils/network/vyos/config/logging_global/logging_global.py new file mode 100644 index 0000000..696090d --- /dev/null +++ b/plugins/module_utils/network/vyos/config/logging_global/logging_global.py @@ -0,0 +1,237 @@ +# +# -*- 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_logging_global 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 copy import deepcopy + +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + dict_merge, + get_from_dict, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( + ResourceModule, +) +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.logging_global import ( + Logging_globalTemplate, +) + + +class Logging_global(ResourceModule): + """ + The vyos_logging_global config class + """ + + def __init__(self, module): + super(Logging_global, self).__init__( + empty_fact_val={}, + facts_module=Facts(module), + module=module, + resource="logging_global", + tmplt=Logging_globalTemplate(), + ) + self.parsers = [ + "console.facilities", + "global_params.archive.file_num", + "global_params.archive.size", + "global_params.marker_interval", + "global_params.preserve_fqdn", + "global_params.facilities", + "files.archive.size", + "files.archive.file_num", + "files", + "hosts.port", + "hosts", + "users", + ] + + 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 self.want: + wantd = self.list_to_dict(self.want, "want") + else: + wantd = dict() + if self.have: + haved = self.list_to_dict(self.have, "have") + else: + haved = dict() + + if self.state in ["overridden", "replaced"]: + if wantd != haved: + wantx, havex = self.call_op(wantd, haved, "overridden") + for k, have in iteritems(havex): + if k not in wantx: + self._compare(want={}, have=have) + + if not self.state == "deleted": + wantd, haved = self.call_op(wantd, haved) + + if self.state == "merged": + wantd = dict_merge(haved, wantd) + + for k, want in iteritems(wantd): + self._compare(want=want, have=haved.pop(k, {})) + + 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 Logging_global network resource. + """ + self.compare(parsers=self.parsers, want=want, have=have) + self.handleStates(want=want, have=have) + + def operation_rep(self, params): + op_val = dict() + for k, val in iteritems(params): + if k in ["console", "global_params"]: + mod_val = deepcopy(val) + op_val.update(self.flatten_facility({k: mod_val})) + elif k in ["files", "hosts", "users"]: + for m, n in iteritems(val): + mod_n = deepcopy(n) + if mod_n.get("archive"): + del mod_n["archive"] + if mod_n.get("facilities"): + del mod_n["facilities"] + if mod_n.get("port"): + del mod_n["port"] + tm = self.flatten_facility({k: {m: mod_n}}) + op_val.update(tm) + return op_val + + def call_op(self, _want, _have, mode=None): + if mode == "overridden": + w = self.operation_rep(_want) + h = self.operation_rep(_have) + else: + w = self.flatten_facility(_want) + h = self.flatten_facility(_have) + return w, h + + def handleStates(self, want=None, have=None): + stateparsers = [ + "syslog.state", + "console.state", + "global_params.state", + "global_params.archive.state", + "files.archive.state", + ] + for par in stateparsers: + op = get_from_dict(want, par) + if op == "enabled": + self.addcmd(want, par) + elif op == "disabled": + self.addcmd(want, par, True) + break + + def flatten_facility(self, param): + temp_param = dict() + for element, val in iteritems(param): + if element in ["console", "global_params", "syslog"]: + if element != "syslog" and val.get("facilities"): + for k, v in iteritems(val.get("facilities")): + temp_param[k + element] = {element: {"facilities": v}} + del val["facilities"] + if val: + temp_param[element] = {element: val} + if element in ["files", "hosts", "users"]: + for k, v in iteritems(val): + if v.get("facilities"): + for pk, dat in iteritems(v.get("facilities")): + temp_param[pk + k] = { + element: { + "facilities": dat, + self.pkey.get(element): v.get( + self.pkey.get(element) + ), + } + } + del v["facilities"] + if len(list(v.keys())) > 1: + temp_param[k] = {element: v} + else: + temp_param[k] = {element: v} + return temp_param + + def list_to_dict(self, param, op=None): + updated_param = dict() + if self.state == "deleted": + if op == "have" and param: + self.handleStates({"syslog": {"state": "disabled"}}) + updated_param == {} + else: + self.pkey = { + "files": "path", + "hosts": "hostname", + "users": "username", + } + for element, val in iteritems(param): + if element == "facilities": # only with recursion call + _tem_par = {} + for par in val: + if par.get("facility") and par.get("severity"): + _tem_par.update( + { + par.get("facility") + + par.get("severity"): par + } + ) + elif par.get("facility") and par.get("protocol"): + _tem_par.update( + { + par.get("facility") + + par.get("protocol"): par + } + ) + else: + _tem_par.update({par.get("facility"): par}) + return _tem_par + elif element in ["console", "global_params", "syslog"]: + if element != "syslog" and val.get("facilities"): + val["facilities"] = self.list_to_dict(val) + updated_param[element] = val + elif element in ["hosts", "users", "files"]: + for v in val: + if v.get("facilities"): + v["facilities"] = self.list_to_dict(v) + if updated_param.get(element): + updated_param[element].update( + {v.get(self.pkey.get(element)): v} + ) + else: + updated_param[element] = { + v.get(self.pkey.get(element)): v + } + return updated_param diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index 90ee03c..ab074b0 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -61,6 +61,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.route from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.prefix_lists.prefix_lists import ( Prefix_listsFacts, ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.logging_global.logging_global import ( + Logging_globalFacts, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import ( Default, Neighbors, @@ -86,6 +89,7 @@ FACT_RESOURCE_SUBSETS = dict( bgp_address_family=Bgp_address_familyFacts, route_maps=Route_mapsFacts, prefix_lists=Prefix_listsFacts, + logging_global=Logging_globalFacts, ) diff --git a/plugins/module_utils/network/vyos/facts/logging_global/__init__.py b/plugins/module_utils/network/vyos/facts/logging_global/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/logging_global/__init__.py diff --git a/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py b/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py new file mode 100644 index 0000000..5f9d65d --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py @@ -0,0 +1,107 @@ +# -*- 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 logging_global fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" + +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.logging_global import ( + Logging_globalTemplate, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.logging_global.logging_global import ( + Logging_globalArgs, +) + + +class Logging_globalFacts(object): + """The vyos logging_global facts class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Logging_globalArgs.argument_spec + + def get_logging_data(self, connection): + return connection.get("show configuration commands | grep syslog") + + def process_facts(self, objFinal): + if objFinal: + for ke, vl in iteritems(objFinal): + if ke == "files": + _files = [] + for k, v in vl.items(): + _files.append(v) + objFinal[ke] = _files + objFinal[ke] = sorted( + objFinal[ke], key=lambda item: item["path"] + ) + elif ke == "hosts": + _hosts = [] + for k, v in vl.items(): + _hosts.append(v) + objFinal[ke] = _hosts + objFinal[ke] = sorted( + objFinal[ke], key=lambda item: item["hostname"] + ) + elif ke == "users": + _users = [] + for k, v in vl.items(): + _users.append(v) + objFinal[ke] = _users + objFinal[ke] = sorted( + objFinal[ke], key=lambda item: item["username"] + ) + elif ke == "console" or ke == "global_params": + if objFinal[ke].get("facilities"): + objFinal[ke]["facilities"] = sorted( + objFinal[ke]["facilities"], + key=lambda item: item["facility"], + ) + return objFinal + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for Logging_global network resource + + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + + :rtype: dictionary + :returns: facts + """ + facts = {} + objs = [] + + if not data: + data = self.get_logging_data(connection) + + # parse native config using the Logging_global template + logging_global_parser = Logging_globalTemplate( + lines=data.splitlines(), module=self._module + ) + objs = logging_global_parser.parse() + ansible_facts["ansible_network_resources"].pop("logging_global", None) + objs = self.process_facts(objs) + + params = utils.remove_empties( + logging_global_parser.validate_config( + self.argument_spec, {"config": objs}, redact=True + ) + ) + + facts["logging_global"] = params.get("config", {}) + ansible_facts["ansible_network_resources"].update(facts) + + return ansible_facts diff --git a/plugins/module_utils/network/vyos/rm_templates/logging_global.py b/plugins/module_utils/network/vyos/rm_templates/logging_global.py new file mode 100644 index 0000000..8cfe7a6 --- /dev/null +++ b/plugins/module_utils/network/vyos/rm_templates/logging_global.py @@ -0,0 +1,388 @@ +# -*- 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 Logging_global 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, +) + + +def tmplt_params(config_data): + def templt_common(val, tmplt): + if val.get("facility"): + tmplt += " facility {facility}".format(facility=val["facility"]) + if val.get("severity"): + tmplt += " level {level}".format(level=val["severity"]) + if val.get("protocol"): + tmplt += " protocol {protocol}".format(protocol=val["protocol"]) + return tmplt + + tmplt = "" + if config_data.get("global_params"): + val = config_data.get("global_params") + if not val.get("archive"): + tmplt += "system syslog global" + tmplt = templt_common(val.get("facilities"), tmplt) + elif config_data.get("console"): + val = config_data.get("console") + tmplt += "system syslog console" + tmplt = templt_common(val.get("facilities"), tmplt) + elif config_data.get("users"): + val = config_data.get("users") + if val.get("username") and not val.get("archive"): + tmplt += "system syslog user {username}".format( + username=val["username"] + ) + if val.get("facilities"): + tmplt = templt_common(val.get("facilities"), tmplt) + elif config_data.get("hosts"): + val = config_data.get("hosts") + if ( + val.get("hostname") + and not val.get("archive") + and not val.get("port") + ): + tmplt += "system syslog host {hostname}".format( + hostname=val["hostname"] + ) + if val.get("facilities"): + tmplt = templt_common(val.get("facilities"), tmplt) + elif config_data.get("files"): + val = config_data.get("files") + if val.get("path") and not val.get("archive"): + tmplt += "system syslog file {path}".format(path=val["path"]) + if val.get("facilities"): + tmplt = templt_common(val.get("facilities"), tmplt) + return tmplt + + +class Logging_globalTemplate(NetworkTemplate): + def __init__(self, lines=None, module=None): + prefix = {"set": "set", "remove": "delete"} + super(Logging_globalTemplate, self).__init__( + lines=lines, tmplt=self, prefix=prefix, module=module + ) + + # fmt: off + PARSERS = [ + { + "name": "syslog.state", + "getval": re.compile( + r""" + ^set\ssystem + (\s(?P<syslog>syslog)) + $""", re.VERBOSE), + "setval": "system syslog", + "result": { + "syslog": { + "state": "{{ 'enabled' if syslog is defined else 'disabled' }}", + } + } + }, + { + "name": "console.facilities", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sconsole\sfacility + (\s(?P<facility>all|auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local[0-7]))? + (\slevel\s(?P<level>'(emerg|alert|crit|err|warning|notice|info|debug|all)'))? + $""", re.VERBOSE), + "setval": tmplt_params, + "remval": "system syslog console facility {{ console.facilities.facility }}", + "result": { + "console": { + "facilities": [{ + "facility": "{{ facility }}", + "severity": "{{ level }}", + }, ] + } + } + }, + { + "name": "console.state", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog + (\s(?P<console>console)) + $""", re.VERBOSE), + "setval": "system syslog console", + "result": { + "console": { + "state": "{{ 'enabled' if console is defined else 'disabled' }}", + } + } + }, + { + "name": "files.archive.state", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sfile + (\s(?P<path>\S+))? + (\s(?P<archive>archive)) + $""", re.VERBOSE), + "setval": "system syslog file {{ files.path }} archive", + "result": { + "files": { + "{{ path }}": { + "path": "{{ path }}", + "archive": { + "state": "{{ 'enabled' if archive is defined else 'disabled' }}", + }, + }, + } + } + }, + { + "name": "files.archive.size", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sfile + (\s(?P<path>\S+))? + (\sarchive\ssize\s(?P<size>'(\d+)'))? + $""", re.VERBOSE), + "setval": "system syslog file {{ files.path }} archive size {{ files.archive.size }}", + "result": { + "files": { + "{{ path }}": { + "path": "{{ path }}", + "archive": { + "size": "{{ size }}", + }, + }, + } + } + }, + { + "name": "files.archive.file_num", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sfile + (\s(?P<path>\S+))? + (\sarchive\sfile\s(?P<file_num>'(\d+)'))? + $""", re.VERBOSE), + "setval": "system syslog file {{ files.path }} archive file {{ files.archive.file_num }}", + "result": { + "files": { + "{{ path }}": { + "path": "{{ path }}", + "archive": { + "file_num": "{{ file_num }}", + }, + }, + } + } + }, + { + "name": "files", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sfile + (\s(?P<path>\S+))? + (\sfacility\s(?P<facility>all|auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local[0-7]))? + (\slevel\s(?P<level>'(emerg|alert|crit|err|warning|notice|info|debug|all)'))? + $""", re.VERBOSE), + "setval": tmplt_params, + "remval": "system syslog file{{ (' ' + files.path) if files.path|d('') is defined else '' }}", + "result": { + "files": { + "{{ path }}": { + "path": "{{ path }}", + "facilities": [{ + "facility": "{{ facility }}", + "severity": "{{ level }}", + }, ] + }, + } + } + }, + { + "name": "global_params.state", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog + (\s(?P<global>global)) + $""", re.VERBOSE), + "setval": "system syslog global", + "result": { + "global_params": { + "state": "{{ 'enabled' if global is defined else 'disabled' }}", + } + } + }, + { + "name": "global_params.archive.state", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sglobal + (\s(?P<archive>archive)) + $""", re.VERBOSE), + "setval": "system syslog global archive", + "result": { + "global_params": { + "archive": { + "state": "{{ 'enabled' if archive is defined else 'disabled' }}", + }, + } + } + }, + { + "name": "global_params.archive.file_num", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sglobal\sarchive\sfile + (\s(?P<file_num>'(\d+)'))? + $""", re.VERBOSE), + "setval": "system syslog global archive file {{ global_params.archive.file_num }}", + "result": { + "global_params": { + "archive": { + "file_num": "{{ file_num }}", + }, + } + } + }, + { + "name": "global_params.archive.size", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sglobal\sarchive\ssize + (\s(?P<size>'(\d+)'))? + $""", re.VERBOSE), + "setval": "system syslog global archive size {{ global_params.archive.size }}", + "result": { + "global_params": { + "archive": { + "size": "{{ size }}", + }, + } + } + }, + { + "name": "global_params.marker_interval", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sglobal\smarker\sinterval + (\s(?P<marker_interval>'(\d+)'))? + $""", re.VERBOSE), + "setval": "system syslog global marker interval {{ global_params.marker_interval }}", + "remval": "system syslog global marker", + "result": { + "global_params": { + "marker_interval": "{{ marker_interval }}", + } + } + }, + { + "name": "global_params.preserve_fqdn", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sglobal + (\s(?P<preserve_fqdn>preserve-fqdn)) + $""", re.VERBOSE), + "setval": "system syslog global preserve-fqdn", + "result": { + "global_params": { + "preserve_fqdn": "{{ True if preserve_fqdn is defined }}", + } + } + }, + { + "name": "global_params.facilities", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\sglobal\sfacility + (\s(?P<facility>all|auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local[0-7]))? + (\slevel\s(?P<level>'(emerg|alert|crit|err|warning|notice|info|debug|all)'))? + $""", re.VERBOSE), + "setval": tmplt_params, + "remval": "system syslog global facility {{ global_params.facilities.facility }}", + "result": { + "global_params": { + "facilities": [{ + "facility": "{{ facility }}", + "severity": "{{ level }}", + }, ], + } + } + }, + { + "name": "hosts.port", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\shost + (\s(?P<hostname>\S+)) + (\sport\s(?P<port>'(\d+)')) + $""", re.VERBOSE), + "setval": "system syslog host {{ hosts.hostname }} port {{ hosts.port }}", + "result": { + "hosts": { + "{{ hostname }}": { + "hostname": "{{ hostname }}", + "port": "{{ port }}", + }, + } + } + }, + { + "name": "hosts", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\shost + (\s(?P<hostname>\S+)) + (\sfacility\s(?P<facility>all|auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local[0-7])) + (\slevel\s(?P<level>'(emerg|alert|crit|err|warning|notice|info|debug|all)'))? + (\sprotocol\s(?P<protocol>'(udp|tcp)'))? + $""", re.VERBOSE), + "setval": tmplt_params, + "remval": "system syslog host {{ hosts.hostname }}", + "result": { + "hosts": { + "{{ hostname }}": { + "hostname": "{{ hostname }}", + "facilities": [{ + "facility": "{{ facility }}", + "severity": "{{ level }}", + "protocol": "{{ protocol }}", + }, ] + }, + } + } + }, + { + "name": "users", + "getval": re.compile( + r""" + ^set\ssystem\ssyslog\suser + (\s(?P<username>\S+))? + (\sfacility\s(?P<facility>all|auth|authpriv|cron|daemon|kern|lpr|mail|mark|news|protocols|security|syslog|user|uucp|local[0-7]))? + (\slevel\s(?P<level>'(emerg|alert|crit|err|warning|notice|info|debug|all)'))? + $""", re.VERBOSE), + "setval": tmplt_params, + "remval": "system syslog user {{ users.username }}", + "result": { + "users": { + "{{ username }}": { + "username": "{{ username }}", + "facilities": [{ + "facility": "{{ facility }}", + "severity": "{{ level }}", + }, ] + } + } + } + }, + ] + # fmt: on diff --git a/plugins/modules/vyos_logging.py b/plugins/modules/vyos_logging.py index d4f0cfc..44238f4 100644 --- a/plugins/modules/vyos_logging.py +++ b/plugins/modules/vyos_logging.py @@ -30,6 +30,10 @@ short_description: Manage logging on network devices description: - This module provides declarative management of logging on Vyatta Vyos devices. version_added: 1.0.0 +deprecated: + alternative: vyos_logging_global + why: Updated module released with more functionality. + removed_at_date: '2023-08-01' notes: - Tested against VyOS 1.1.8 (helium). - This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). diff --git a/plugins/modules/vyos_logging_global.py b/plugins/modules/vyos_logging_global.py new file mode 100644 index 0000000..6a4e2dd --- /dev/null +++ b/plugins/modules/vyos_logging_global.py @@ -0,0 +1,776 @@ +#!/usr/bin/python +# -*- 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) + +""" +The module file for vyos_logging_global +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +module: vyos_logging_global +version_added: 2.4.0 +short_description: Logging resource module +description: This module manages the logging attributes of Vyos network devices +author: Sagar Paul (@KB-perByte) +notes: + - Tested against vyos 1.2 + - This module works with connection C(network_cli). + - The Configuration defaults of the Vyos network devices + are supposed to hinder idempotent behavior of plays +options: + config: + description: A list containing dictionary of logging options + type: dict + suboptions: + console: + description: logging to serial console + type: dict + suboptions: + state: &state_config + description: enable or disable the command + type: str + choices: + - enabled + - disabled + facilities: + description: facility configurations for console + type: list + elements: dict + suboptions: + facility: &facility + description: Facility for logging + type: str + choices: + - all + - auth + - authpriv + - cron + - daemon + - kern + - lpr + - mail + - mark + - news + - protocols + - security + - syslog + - user + - uucp + - local0 + - local1 + - local2 + - local3 + - local4 + - local5 + - local6 + - local7 + severity: &severity + description: logging level + type: str + choices: + - emerg + - alert + - crit + - err + - warning + - notice + - info + - debug + - all + files: + description: logging to file + type: list + elements: dict + suboptions: + path: + description: file name or path + type: str + archive: &archive + description: Log file size and rotation characteristics + type: dict + suboptions: + state: *state_config + file_num: + description: Number of saved files (default is 5) + type: int + size: + description: Size of log files (in kilobytes, default is 256) + type: int + facilities: ¶ms + description: facility configurations + type: list + elements: dict + suboptions: + facility: *facility + severity: *severity + global_params: + description: logging to serial console + type: dict + suboptions: + state: *state_config + archive: *archive + facilities: *params + marker_interval: + description: time interval how often a mark message is being sent in seconds (default is 1200) + type: int + preserve_fqdn: + description: uses FQDN for logging + type: bool + hosts: + description: logging to serial console + type: list + elements: dict + suboptions: + port: + description: Destination port (1-65535) + type: int + facilities: + description: facility configurations for host + type: list + elements: dict + suboptions: + facility: *facility + severity: *severity + protocol: + description: syslog communication protocol + type: str + choices: + - udp + - tcp + hostname: + description: Remote host name or IP address + type: str + syslog: + description: logging syslog + type: dict + suboptions: + state: *state_config + users: + description: logging to file + type: list + elements: dict + suboptions: + username: + description: user login name + type: str + facilities: *params + 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 syslog). + - The state I(parsed) reads the configuration from C(running_config) 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: + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged + description: + - The state the configuration should be left in + - The states I(replaced) and I(overridden) have identical + behaviour for this module. + - Refer to examples for more details. + type: str +""" + +EXAMPLES = """ +# Using state: merged + +# Before state: +# ------------- + +# vyos:~$show configuration commands | grep syslog + +- name: Apply the provided configuration + vyos.vyos.vyos_logging_global: + config: + console: + facilities: + - facility: local7 + severity: err + files: + - path: logFile + archive: + file_num: 2 + facilities: + - facility: local6 + severity: emerg + hosts: + - hostname: 172.16.0.1 + facilities: + - facility: local7 + severity: all + - facility: all + protocol: udp + port: 223 + users: + - username: vyos + facilities: + - facility: local7 + severity: debug + global_params: + archive: + file_num: 2 + size: 111 + facilities: + - facility: cron + severity: debug + marker_interval: 111 + preserve_fqdn: true + state: merged + +# Commands Fired: +# --------------- + +# "commands": [ +# "set system syslog console facility local7 level err", +# "set system syslog file logFile archive file 2", +# "set system syslog host 172.16.0.1 facility local7 level all", +# "set system syslog file logFile facility local6 level emerg", +# "set system syslog host 172.16.0.1 facility all protocol udp", +# "set system syslog user vyos facility local7 level debug", +# "set system syslog host 172.16.0.1 port 223", +# "set system syslog global facility cron level debug", +# "set system syslog global archive file 2", +# "set system syslog global archive size 111", +# "set system syslog global marker interval 111", +# "set system syslog global preserve-fqdn" +# ], + +# After state: +# ------------ + +# vyos:~$ show configuration commands | grep syslog +# set system syslog console facility local7 level 'err' +# set system syslog file logFile archive file '2' +# set system syslog file logFile facility local6 level 'emerg' +# set system syslog global archive file '2' +# set system syslog global archive size '111' +# set system syslog global facility cron level 'debug' +# set system syslog global marker interval '111' +# set system syslog global preserve-fqdn +# set system syslog host 172.16.0.1 facility all protocol 'udp' +# set system syslog host 172.16.0.1 facility local7 level 'all' +# set system syslog host 172.16.0.1 port '223' +# set system syslog user vyos facility local7 level 'debug' + +# Using state: deleted + +# Before state: +# ------------- + +# vyos:~$show configuration commands | grep syslog +# set system syslog console facility local7 level 'err' +# set system syslog file logFile archive file '2' +# set system syslog file logFile facility local6 level 'emerg' +# set system syslog global archive file '2' +# set system syslog global archive size '111' +# set system syslog global facility cron level 'debug' +# set system syslog global marker interval '111' +# set system syslog global preserve-fqdn +# set system syslog host 172.16.0.1 facility all protocol 'udp' +# set system syslog host 172.16.0.1 facility local7 level 'all' +# set system syslog host 172.16.0.1 port '223' +# set system syslog user vyos facility local7 level 'debug' + +- name: delete the existing configuration + vyos.vyos.vyos_logging_global: + state: deleted + +# Commands Fired: +# --------------- + +# "commands": [ +# "delete system syslog" +# ], + +# After state: +# ------------ + +# vyos:~$show configuration commands | grep syslog + +# Using state: overridden + +# Before state: +# ------------- + +# vyos:~$show configuration commands | grep syslog +# set system syslog console facility local7 level 'err' +# set system syslog file logFile archive file '2' +# set system syslog file logFile facility local6 level 'emerg' +# set system syslog global archive file '2' +# set system syslog global archive size '111' +# set system syslog global facility cron level 'debug' +# set system syslog global marker interval '111' +# set system syslog global preserve-fqdn +# set system syslog host 172.16.0.1 facility all protocol 'udp' +# set system syslog host 172.16.0.1 facility local7 level 'all' +# set system syslog host 172.16.0.1 port '223' +# set system syslog user vyos facility local7 level 'debug' + +- name: Override the current configuration + vyos.vyos.vyos_logging_global: + config: + console: + facilities: + - facility: all + - facility: local7 + severity: err + - facility: news + severity: debug + files: + - path: logFileNew + hosts: + - hostname: 172.16.0.2 + facilities: + - facility: local5 + severity: all + global_params: + archive: + file_num: 10 + state: overridden + +# Commands Fired: +# --------------- + +# "commands": [ +# "delete system syslog file logFile", +# "delete system syslog global facility cron", +# "delete system syslog host 172.16.0.1", +# "delete system syslog user vyos", +# "set system syslog console facility all", +# "set system syslog console facility news level debug", +# "set system syslog file logFileNew", +# "set system syslog host 172.16.0.2 facility local5 level all", +# "set system syslog global archive file 10", +# "delete system syslog global archive size 111", +# "delete system syslog global marker", +# "delete system syslog global preserve-fqdn" +# ], + +# After state: +# ------------ + +# vyos:~$show configuration commands | grep syslog +# set system syslog console facility all +# set system syslog console facility local7 level 'err' +# set system syslog console facility news level 'debug' +# set system syslog file logFileNew +# set system syslog global archive file '10' +# set system syslog host 172.16.0.2 facility local5 level 'all' + +# Using state: replaced + +# Before state: +# ------------- + +# vyos:~$show configuration commands | grep syslog +# set system syslog console facility all +# set system syslog console facility local7 level 'err' +# set system syslog console facility news level 'debug' +# set system syslog file logFileNew +# set system syslog global archive file '10' +# set system syslog host 172.16.0.2 facility local5 level 'all' + +- name: Replace with the provided configuration + register: result + vyos.vyos.vyos_logging_global: + config: + console: + facilities: + - facility: local6 + users: + - username: paul + facilities: + - facility: local7 + severity: err + state: replaced + +# Commands Fired: +# --------------- + +# "commands": [ +# "delete system syslog console facility all", +# "delete system syslog console facility local7", +# "delete system syslog console facility news", +# "delete system syslog file logFileNew", +# "delete system syslog global archive file 10", +# "delete system syslog host 172.16.0.2", +# "set system syslog console facility local6", +# "set system syslog user paul facility local7 level err" +# ], + +# After state: +# ------------ + +# vyos:~$show configuration commands | grep syslog +# set system syslog console facility local6 +# set system syslog user paul facility local7 level 'err' + +# Using state: gathered + +- name: Gather logging config + vyos.vyos.vyos_logging_global: + state: gathered + +# Module Execution Result: +# ------------------------ + +# "gathered": { +# "console": { +# "facilities": [ +# { +# "facility": "local6" +# }, +# { +# "facility": "local7", +# "severity": "err" +# } +# ] +# }, +# "files": [ +# { +# "archive": { +# "file_num": 2 +# }, +# "facilities": [ +# { +# "facility": "local6", +# "severity": "emerg" +# } +# ], +# "path": "logFile" +# } +# ], +# "global_params": { +# "archive": { +# "file_num": 2, +# "size": 111 +# }, +# "facilities": [ +# { +# "facility": "cron", +# "severity": "debug" +# } +# ], +# "marker_interval": 111, +# "preserve_fqdn": true +# }, +# "hosts": [ +# { +# "facilities": [ +# { +# "facility": "all", +# "protocol": "udp" +# }, +# { +# "facility": "local7", +# "severity": "all" +# } +# ], +# "hostname": "172.16.0.1", +# "port": 223 +# } +# ], +# "users": [ +# { +# "facilities": [ +# { +# "facility": "local7", +# "severity": "err" +# } +# ], +# "username": "paul" +# }, +# { +# "facilities": [ +# { +# "facility": "local7", +# "severity": "debug" +# } +# ], +# "username": "vyos" +# } +# ] +# }, + +# After state: +# ------------ + +# vyos:~$show configuration commands | grep syslog +# set system syslog console facility local6 +# set system syslog console facility local7 level 'err' +# set system syslog file logFile archive file '2' +# set system syslog file logFile facility local6 level 'emerg' +# set system syslog global archive file '2' +# set system syslog global archive size '111' +# set system syslog global facility cron level 'debug' +# set system syslog global marker interval '111' +# set system syslog global preserve-fqdn +# set system syslog host 172.16.0.1 facility all protocol 'udp' +# set system syslog host 172.16.0.1 facility local7 level 'all' +# set system syslog host 172.16.0.1 port '223' +# set system syslog user paul facility local7 level 'err' +# set system syslog user vyos facility local7 level 'debug' + +# Using state: rendered + +- name: Render the provided configuration + vyos.vyos.vyos_logging_global: + config: + console: + facilities: + - facility: local7 + severity: err + files: + - path: logFile + archive: + file_num: 2 + facilities: + - facility: local6 + severity: emerg + hosts: + - hostname: 172.16.0.1 + facilities: + - facility: local7 + severity: all + - facility: all + protocol: udp + port: 223 + users: + - username: vyos + facilities: + - facility: local7 + severity: debug + global_params: + archive: + file_num: 2 + size: 111 + facilities: + - facility: cron + severity: debug + marker_interval: 111 + preserve_fqdn: true + state: rendered + +# Module Execution Result: +# ------------------------ + +# "rendered": [ +# "set system syslog console facility local7 level err", +# "set system syslog file logFile facility local6 level emerg", +# "set system syslog file logFile archive file 2", +# "set system syslog host 172.16.0.1 facility local7 level all", +# "set system syslog host 172.16.0.1 facility all protocol udp", +# "set system syslog host 172.16.0.1 port 223", +# "set system syslog user vyos facility local7 level debug", +# "set system syslog global facility cron level debug", +# "set system syslog global archive file 2", +# "set system syslog global archive size 111", +# "set system syslog global marker interval 111", +# "set system syslog global preserve-fqdn" +# ] + +# Using state: parsed + +# File: parsed.cfg +# ---------------- + +# set system syslog console facility local6 +# set system syslog console facility local7 level 'err' +# set system syslog file logFile archive file '2' +# set system syslog file logFile facility local6 level 'emerg' +# set system syslog global archive file '2' +# set system syslog global archive size '111' +# set system syslog global facility cron level 'debug' +# set system syslog global marker interval '111' +# set system syslog global preserve-fqdn +# set system syslog host 172.16.0.1 facility all protocol 'udp' +# set system syslog host 172.16.0.1 facility local7 level 'all' +# set system syslog host 172.16.0.1 port '223' +# set system syslog user paul facility local7 level 'err' +# set system syslog user vyos facility local7 level 'debug' + +- name: Parse the provided configuration + vyos.vyos.vyos_logging_global: + running_config: "{{ lookup('file', 'parsed_vyos.cfg') }}" + state: parsed + +# Module Execution Result: +# ------------------------ + +# "parsed": { +# "console": { +# "facilities": [ +# { +# "facility": "local6" +# }, +# { +# "facility": "local7", +# "severity": "err" +# } +# ] +# }, +# "files": [ +# { +# "archive": { +# "file_num": 2 +# }, +# "facilities": [ +# { +# "facility": "local6", +# "severity": "emerg" +# } +# ], +# "path": "logFile" +# } +# ], +# "global_params": { +# "archive": { +# "file_num": 2, +# "size": 111 +# }, +# "facilities": [ +# { +# "facility": "cron", +# "severity": "debug" +# } +# ], +# "marker_interval": 111, +# "preserve_fqdn": true +# }, +# "hosts": [ +# { +# "facilities": [ +# { +# "facility": "all", +# "protocol": "udp" +# }, +# { +# "facility": "local7", +# "severity": "all" +# } +# ], +# "hostname": "172.16.0.1", +# "port": 223 +# } +# ], +# "users": [ +# { +# "facilities": [ +# { +# "facility": "local7", +# "severity": "err" +# } +# ], +# "username": "paul" +# }, +# { +# "facilities": [ +# { +# "facility": "local7", +# "severity": "debug" +# } +# ], +# "username": "vyos" +# } +# ] +# } +# } +""" + +RETURN = """ +before: + description: The configuration prior to the module execution. + returned: when state is I(merged), I(replaced), I(overridden), I(deleted) or I(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 state is I(merged), I(replaced), I(overridden), I(deleted) or I(purged) + type: list + sample: + - "set system syslog console facility local7 level err" + - "set system syslog host 172.16.0.1 port 223" + - "set system syslog global archive size 111" +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when state is I(rendered) + type: list + sample: + - "set system syslog host 172.16.0.1 port 223" + - "set system syslog user vyos facility local7 level debug" + - "set system syslog global facility cron level debug" +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when state is I(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 state is I(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.logging_global.logging_global import ( + Logging_globalArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.logging_global.logging_global import ( + Logging_global, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule( + argument_spec=Logging_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 = Logging_global(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() |