From e738cc567bb52e267c172719c723048e67f129b5 Mon Sep 17 00:00:00 2001
From: Simone Spinelli <simone.spinelli@GA0503-SSPINELLI.local>
Date: Tue, 17 Jun 2025 10:40:35 +0200
Subject: [PATCH 1/6] Add a custom callback plugin for managing logs
---
.../callback_plugins/filtering_syslog.py | 70 +++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
diff --git a/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
new file mode 100644
index 00000000..7e8cf052
--- /dev/null
+++ b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
@@ -0,0 +1,70 @@
+# callback_plugins/filtering_syslog.py
+import syslog
+import uuid
+from datetime import datetime
+from ansible.plugins.callback import CallbackBase
+from ansible.utils.display import Display
+
+display = Display()
+
+class CallbackModule(CallbackBase):
+ """
+ Logs all task results to syslog with timestamp and run ID.
+ One line per result. Only prints tasks tagged with 'print_action'.
+ Always prints and logs playbook summary.
+ """
+
+ CALLBACK_VERSION = 2.0
+ CALLBACK_TYPE = 'stdout'
+ CALLBACK_NAME = 'filtering_syslog'
+
+ def __init__(self):
+ super().__init__()
+ syslog.openlog(ident="ansible", logoption=syslog.LOG_PID, facility=syslog.LOG_USER)
+ self.run_id = str(uuid.uuid4())[:8] # Shorten for readability
+
+ def _log_to_syslog(self, message: str):
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ syslog.syslog(syslog.LOG_INFO, f"[{timestamp}] [run_id:{self.run_id}] {message}")
+
+ def _should_print(self, task):
+ return hasattr(task, "tags") and "print_action" in task.tags
+
+ def _pretty_print(self, result, status):
+ task_name = result.task_name or result._task.get_name()
+ host = result._host.get_name()
+
+ display.banner(f"TASK [{task_name}]")
+ display.display(f"{host} | {status}", color="green" if status == "ok" else "red")
+ display.display(self._dump_results(result._result))
+
+ def v2_runner_on_ok(self, result):
+ task = result.task_name or result._task.get_name()
+ host = result._host.get_name()
+ self._log_to_syslog(f"{host} | OK | Task: {task}")
+ if self._should_print(result._task):
+ self._pretty_print(result, "ok")
+
+ def v2_runner_on_failed(self, result, ignore_errors=False):
+ task = result.task_name or result._task.get_name()
+ host = result._host.get_name()
+ self._log_to_syslog(f"{host} | FAILED | Task: {task}")
+ if self._should_print(result._task):
+ self._pretty_print(result, "failed")
+
+ def v2_runner_on_skipped(self, result):
+ task = result.task_name or result._task.get_name()
+ host = result._host.get_name()
+ self._log_to_syslog(f"{host} | SKIPPED | Task: {task}")
+ if self._should_print(result._task):
+ self._pretty_print(result, "skipped")
+
+ def v2_playbook_on_stats(self, stats):
+ summary = {}
+ for host in stats.processed.keys():
+ s = stats.summarize(host)
+ summary_line = f"{host} | SUMMARY | ok={s['ok']} changed={s['changed']} unreachable={s['unreachable']} failed={s['failures']} skipped={s['skipped']}"
+ self._log_to_syslog(summary_line)
+ display.display(summary_line)
+
+ display.banner("PLAYBOOK SUMMARY")
--
GitLab
From e12b34d925ee14072100177b0edb74d7f8ed7d21 Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Tue, 8 Jul 2025 19:15:29 +0100
Subject: [PATCH 2/6] Update `filtering_syslog` to use diff
---
.../plugins/callback_plugins/filtering_syslog.py | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
index 7e8cf052..5199d63e 100644
--- a/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
+++ b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
@@ -1,4 +1,5 @@
# callback_plugins/filtering_syslog.py
+import difflib
import syslog
import uuid
from datetime import datetime
@@ -36,7 +37,19 @@ class CallbackModule(CallbackBase):
display.banner(f"TASK [{task_name}]")
display.display(f"{host} | {status}", color="green" if status == "ok" else "red")
- display.display(self._dump_results(result._result))
+
+ # Display diff if present
+ if 'diff' in result._result:
+ display.display("DIFF:", color="blue")
+ _before = result._result['diff']['before']
+ _after = result._result['diff']['after']
+ for line in difflib.ndiff(_before.splitlines(), _after.splitlines()):
+ if line.startswith('+ ') or line.startswith('- ') or line.startswith('? '):
+ display.display(line)
+
+ # Display full result if not ok
+ if status != "ok":
+ display.display(self._dump_results(result._result))
def v2_runner_on_ok(self, result):
task = result.task_name or result._task.get_name()
--
GitLab
From b9201c5a69cdf9ffa88b6ae0a334465d1868d8de Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Tue, 8 Jul 2025 19:15:58 +0100
Subject: [PATCH 3/6] Link to callback_plugins from the playbooks dir
---
geant/gap_ansible/playbooks/callback_plugins | 1 +
1 file changed, 1 insertion(+)
create mode 120000 geant/gap_ansible/playbooks/callback_plugins
diff --git a/geant/gap_ansible/playbooks/callback_plugins b/geant/gap_ansible/playbooks/callback_plugins
new file mode 120000
index 00000000..6a368d07
--- /dev/null
+++ b/geant/gap_ansible/playbooks/callback_plugins
@@ -0,0 +1 @@
+../plugins/callback_plugins
\ No newline at end of file
--
GitLab
From 2b09d88848d28cbc15bdff7c4bbe0cd8e9ff9ff5 Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Tue, 8 Jul 2025 19:16:37 +0100
Subject: [PATCH 4/6] Update edge_port/tasks/deploy to use filter_syslog plugin
---
.../gap_ansible/roles/edge_port/tasks/deploy.yaml | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml b/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml
index 57cc6aa2..405a3fc0 100644
--- a/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml
+++ b/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml
@@ -14,6 +14,15 @@
diff: true
register: output
check_mode: true
+ tags: [print_action]
+
+- name: Fail if there is any diff
+ ansible.builtin.fail:
+ msg: Base config drift detected!!!
+ when: >
+ output.changed | ansible.builtin.bool
+ and
+ is_verification_workflow | ansible.builtin.bool
- name: Config deploy [CHECK ONLY][JUNIPER]
when: >
@@ -28,6 +37,11 @@
diff: true
register: output
+# - name: Display the output
+# ansible.builtin.debug:
+# msg: "{{ output }}"
+# tags: [print_action]
+
- name: Fail if there is any diff
ansible.builtin.fail:
msg: Base config drift detected!!!
--
GitLab
From faac00258c6435e091b475aa2ff1b8ea3b668713 Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Wed, 9 Jul 2025 11:04:24 +0100
Subject: [PATCH 5/6] callback_plugin: difflib: ndiff -> context_diff
---
.../plugins/callback_plugins/filtering_syslog.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
index 5199d63e..f2065551 100644
--- a/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
+++ b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py
@@ -43,9 +43,9 @@ class CallbackModule(CallbackBase):
display.display("DIFF:", color="blue")
_before = result._result['diff']['before']
_after = result._result['diff']['after']
- for line in difflib.ndiff(_before.splitlines(), _after.splitlines()):
- if line.startswith('+ ') or line.startswith('- ') or line.startswith('? '):
- display.display(line)
+ difference = difflib.context_diff(_before.splitlines(), _after.splitlines(), n=10)
+ for line in difference:
+ display.display(line)
# Display full result if not ok
if status != "ok":
--
GitLab
From f17cb6a925ba630af98f60968f81307e7603e24a Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Wed, 9 Jul 2025 11:20:15 +0100
Subject: [PATCH 6/6] edge_port/tasks/deploy.yaml
- Added separate output.changed evaluation after Nokia dry-run;
- cleanup.
---
geant/gap_ansible/roles/edge_port/tasks/deploy.yaml | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml b/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml
index 405a3fc0..0d74fdfd 100644
--- a/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml
+++ b/geant/gap_ansible/roles/edge_port/tasks/deploy.yaml
@@ -36,11 +36,7 @@
check_commit: true
diff: true
register: output
-
-# - name: Display the output
-# ansible.builtin.debug:
-# msg: "{{ output }}"
-# tags: [print_action]
+ tags: [print_action]
- name: Fail if there is any diff
ansible.builtin.fail:
--
GitLab