summaryrefslogtreecommitdiff
path: root/plugins/modules/vyos_logging_global.py
diff options
context:
space:
mode:
authoromnom62 <omnom62@outlook.com>2026-05-06 08:08:27 +1000
committeromnom62 <omnom62@outlook.com>2026-05-06 08:08:27 +1000
commit9a3fa5777e7203d46faf1185cfb56c4fc121d885 (patch)
tree80988400ba3582cfc97ff6445fb8f97c724d3fc6 /plugins/modules/vyos_logging_global.py
parentc2493986714604aa992bea28628b74587b3b51bd (diff)
downloadrest.vyos-9a3fa5777e7203d46faf1185cfb56c4fc121d885.tar.gz
rest.vyos-9a3fa5777e7203d46faf1185cfb56c4fc121d885.zip
More modules
Diffstat (limited to 'plugins/modules/vyos_logging_global.py')
-rw-r--r--plugins/modules/vyos_logging_global.py482
1 files changed, 482 insertions, 0 deletions
diff --git a/plugins/modules/vyos_logging_global.py b/plugins/modules/vyos_logging_global.py
new file mode 100644
index 0000000..be240ff
--- /dev/null
+++ b/plugins/modules/vyos_logging_global.py
@@ -0,0 +1,482 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.vyos.rest.plugins.module_utils.vyos import VyOSModule
+
+
+DOCUMENTATION = r"""
+---
+module: vyos_logging_global
+short_description: Manage syslog configuration on VyOS devices using REST API
+description:
+ - Manages syslog (logging) configuration on VyOS devices via the REST API.
+ - Supports console, file, host, user, and global logging targets with
+ per-target facility and severity configuration.
+ - Uses REST API (C(connection=httpapi)) instead of CLI.
+version_added: "1.0.0"
+author:
+ - Sagar Paul (@KB-perByte)
+
+options:
+ config:
+ description: Logging configuration.
+ type: dict
+ suboptions:
+ console:
+ description: Logging to serial console.
+ type: dict
+ suboptions:
+ facilities:
+ type: list
+ elements: dict
+ suboptions:
+ facility:
+ type: str
+ severity:
+ type: str
+ files:
+ description: Logging to local files.
+ type: list
+ elements: dict
+ suboptions:
+ path:
+ type: str
+ archive:
+ type: dict
+ suboptions:
+ file_num:
+ type: int
+ size:
+ type: int
+ facilities:
+ type: list
+ elements: dict
+ suboptions:
+ facility:
+ type: str
+ severity:
+ type: str
+ global_params:
+ description: Global syslog parameters (maps to C(system syslog global)).
+ type: dict
+ suboptions:
+ archive:
+ type: dict
+ suboptions:
+ file_num:
+ type: int
+ size:
+ type: int
+ facilities:
+ type: list
+ elements: dict
+ suboptions:
+ facility:
+ type: str
+ severity:
+ type: str
+ marker_interval:
+ type: int
+ preserve_fqdn:
+ type: bool
+ hosts:
+ description: Logging to remote syslog hosts.
+ type: list
+ elements: dict
+ suboptions:
+ hostname:
+ type: str
+ port:
+ type: int
+ protocol:
+ type: str
+ facilities:
+ type: list
+ elements: dict
+ suboptions:
+ facility:
+ type: str
+ severity:
+ type: str
+ protocol:
+ description: Per-facility protocol override.
+ type: str
+ users:
+ description: Logging to local user terminals.
+ type: list
+ elements: dict
+ suboptions:
+ username:
+ type: str
+ facilities:
+ type: list
+ elements: dict
+ suboptions:
+ facility:
+ type: str
+ severity:
+ type: str
+
+ running_config:
+ description: Used only with state C(parsed).
+ type: str
+
+ state:
+ description:
+ - Desired state of the logging configuration.
+ type: str
+ default: merged
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - gathered
+ - rendered
+ - parsed
+"""
+
+EXAMPLES = r"""
+- name: Merge logging configuration
+ vyos.rest.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
+ port: 223
+ facilities:
+ - facility: local7
+ severity: all
+ - facility: all
+ protocol: udp
+ 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
+
+- name: Delete all logging configuration
+ vyos.rest.vyos_logging_global:
+ state: deleted
+
+- name: Gather current logging configuration
+ vyos.rest.vyos_logging_global:
+ state: gathered
+"""
+
+RETURN = r"""
+before:
+ description: Logging configuration before this module ran.
+ returned: when state is merged, replaced, overridden or deleted
+ type: dict
+after:
+ description: Logging configuration after this module ran.
+ returned: when changed
+ type: dict
+commands:
+ description: List of API command tuples sent to the device.
+ returned: always
+ type: list
+gathered:
+ description: Current logging configuration from the device.
+ returned: when state is gathered
+ type: dict
+saved:
+ description: Result of save_config after applying changes.
+ returned: when changes are applied
+ type: dict
+"""
+
+
+# ------------------------------------------------------------
+# Normalization
+# ------------------------------------------------------------
+
+
+def normalize_config(cfg):
+ result = {
+ "console": {"facilities": {}},
+ "global": {"facilities": {}},
+ "hosts": {},
+ "files": {},
+ "users": {},
+ }
+
+ for f in cfg.get("console", {}).get("facilities", []):
+ result["console"]["facilities"][f["facility"]] = f.get("severity")
+
+ gp = cfg.get("global_params", {})
+ for f in gp.get("facilities", []):
+ result["global"]["facilities"][f["facility"]] = f.get("severity")
+ if gp.get("archive"):
+ result["global"]["archive"] = gp["archive"]
+ if gp.get("marker_interval"):
+ result["global"]["marker_interval"] = gp["marker_interval"]
+ if gp.get("preserve_fqdn"):
+ result["global"]["preserve_fqdn"] = True
+
+ for h in cfg.get("hosts", []):
+ host = {"port": h.get("port"), "facilities": {}}
+ for f in h.get("facilities", []):
+ host["facilities"][f["facility"]] = {k: v for k, v in f.items() if k != "facility"}
+ result["hosts"][h["hostname"]] = host
+
+ for f in cfg.get("files", []):
+ facilities = {x["facility"]: x.get("severity") for x in f.get("facilities", [])}
+ result["files"][f["path"]] = {
+ "archive": f.get("archive"),
+ "facilities": facilities,
+ }
+
+ for u in cfg.get("users", []):
+ result["users"][u["username"]] = {
+ "facilities": {f["facility"]: f.get("severity") for f in u.get("facilities", [])},
+ }
+
+ return result
+
+
+def normalize_running(raw):
+ result = {
+ "console": {"facilities": {}},
+ "global": {"facilities": {}},
+ "hosts": {},
+ "files": {},
+ "users": {},
+ }
+
+ if not raw:
+ return result
+
+ for f, data in raw.get("console", {}).get("facility", {}).items():
+ result["console"]["facilities"][f] = data.get("level")
+
+ g = raw.get("global", {})
+ for f, data in g.get("facility", {}).items():
+ result["global"]["facilities"][f] = data.get("level")
+ if "archive" in g:
+ result["global"]["archive"] = g["archive"]
+ if "marker" in g and "interval" in g["marker"]:
+ result["global"]["marker_interval"] = g["marker"]["interval"]
+ if "preserve-fqdn" in g:
+ result["global"]["preserve_fqdn"] = True
+
+ for host, data in raw.get("host", {}).items():
+ h = {"port": data.get("port"), "facilities": {}}
+ for f, fd in data.get("facility", {}).items():
+ h["facilities"][f] = {
+ "severity": fd.get("level"),
+ "protocol": fd.get("protocol"),
+ }
+ result["hosts"][host] = h
+
+ for path, data in raw.get("file", {}).items():
+ facilities = {}
+ for f, fd in data.get("facility", {}).items():
+ facilities[f] = fd.get("level")
+ result["files"][path] = {
+ "archive": data.get("archive"),
+ "facilities": facilities,
+ }
+
+ for user, data in raw.get("user", {}).items():
+ facilities = {}
+ for f, fd in data.get("facility", {}).items():
+ facilities[f] = fd.get("level")
+ result["users"][user] = {"facilities": facilities}
+
+ return result
+
+
+# ------------------------------------------------------------
+# Diff helpers
+# ------------------------------------------------------------
+
+
+def diff_facilities(base, want, have, state):
+ cmds = []
+ want_keys = set(want)
+ have_keys = set(have)
+
+ for f in want_keys:
+ if f not in have_keys or want[f] != have[f]:
+ path = base + ["facility", f]
+ if want[f]:
+ path += ["level", want[f]]
+ cmds.append(("set", path))
+
+ if state in ["replaced", "deleted"]:
+ for f in have_keys - want_keys:
+ cmds.append(("delete", base + ["facility", f]))
+
+ return cmds
+
+
+def diff_map(base, want, have, state):
+ cmds = []
+ w = set(want)
+ h = set(have)
+
+ if state in ["merged", "replaced"]:
+ for k in w - h:
+ cmds.append(("set", base + [k]))
+
+ if state in ["replaced", "deleted"]:
+ for k in h - w:
+ cmds.append(("delete", base + [k]))
+
+ return cmds
+
+
+# ------------------------------------------------------------
+# Build commands
+# ------------------------------------------------------------
+
+
+def build_commands(want, have, state):
+ cmds = []
+
+ if state == "overridden":
+ cmds.append(("delete", ["system", "syslog"]))
+ state = "merged"
+
+ cmds += diff_facilities(
+ ["system", "syslog", "console"],
+ want["console"]["facilities"],
+ have["console"]["facilities"],
+ state,
+ )
+
+ cmds += diff_facilities(
+ ["system", "syslog", "global"],
+ want["global"]["facilities"],
+ have["global"]["facilities"],
+ state,
+ )
+
+ cmds += diff_map(
+ ["system", "syslog", "file"],
+ want["files"],
+ have["files"],
+ state,
+ )
+
+ cmds += diff_map(
+ ["system", "syslog", "host"],
+ want["hosts"],
+ have["hosts"],
+ state,
+ )
+
+ cmds += diff_map(
+ ["system", "syslog", "user"],
+ want["users"],
+ have["users"],
+ state,
+ )
+
+ return cmds
+
+
+# ------------------------------------------------------------
+# Running config
+# ------------------------------------------------------------
+
+
+def get_running_config(vyos):
+ raw = vyos.get_config(["system", "syslog"])
+ return normalize_running(raw)
+
+
+# ------------------------------------------------------------
+# Main
+# ------------------------------------------------------------
+
+
+def main():
+ argument_spec = dict(
+ config=dict(type="dict"),
+ running_config=dict(type="str"),
+ state=dict(
+ default="merged",
+ choices=[
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ ),
+ )
+
+ module = AnsibleModule(argument_spec, supports_check_mode=True)
+ vyos = VyOSModule(module)
+
+ state = module.params["state"]
+ config = module.params.get("config") or {}
+
+ if state == "gathered":
+ module.exit_json(gathered=get_running_config(vyos))
+
+ want = normalize_config(config)
+ have = get_running_config(vyos)
+
+ if state == "deleted":
+ want = {
+ "console": {"facilities": {}},
+ "global": {"facilities": {}},
+ "hosts": {},
+ "files": {},
+ "users": {},
+ }
+
+ commands = build_commands(want, have, state)
+
+ if module.check_mode:
+ module.exit_json(changed=bool(commands), commands=commands, before=have)
+
+ if commands:
+ response = vyos.apply_commands(commands)
+ saved = vyos.save_config()
+ module.exit_json(
+ changed=True,
+ before=have,
+ after=want,
+ commands=commands,
+ saved=saved,
+ response=response,
+ )
+
+ module.exit_json(changed=False, before=have, after=have, commands=[])
+
+
+if __name__ == "__main__":
+ main()