From 3f3621b6874354fbf824171bfe2e3aed6360482f Mon Sep 17 00:00:00 2001
From: Indrajit Raychaudhuri <irc@indrajit.com>
Date: Mon, 3 Apr 2023 18:24:29 -0500
Subject: dns: T5144: Improve dns dynamic status output

Improve and fix the output of dynamic dns status to be compatible with
new ddclient cache format.

Additional details:
- The status output is now formatted as a table with per-host dual-stack
  information in rows. Columns not having actual value present in the
  output will be kept empty.
- The 'Last update' column is now formatted in Local time format instead
  of UTC.
---
 src/op_mode/dynamic_dns.py | 72 +++++++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 39 deletions(-)

diff --git a/src/op_mode/dynamic_dns.py b/src/op_mode/dynamic_dns.py
index 263a3b6a5..2cba33cc8 100755
--- a/src/op_mode/dynamic_dns.py
+++ b/src/op_mode/dynamic_dns.py
@@ -16,69 +16,63 @@
 
 import os
 import argparse
-import jinja2
 import sys
 import time
+from tabulate import tabulate
 
 from vyos.config import Config
 from vyos.util import call
 
 cache_file = r'/run/ddclient/ddclient.cache'
 
-OUT_TMPL_SRC = """
-{% for entry in hosts %}
-ip address   : {{ entry.ip }}
-host-name    : {{ entry.host }}
-last update  : {{ entry.time }}
-update-status: {{ entry.status }}
+columns = {
+    'host':        'Hostname',
+    'ipv4':        'IPv4 address',
+    'status-ipv4': 'IPv4 status',
+    'ipv6':        'IPv6 address',
+    'status-ipv6': 'IPv6 status',
+    'mtime':       'Last update',
+}
+
+
+def _get_formatted_host_records(host_data):
+    data_entries = []
+    for entry in host_data:
+        data_entries.append([entry.get(key) for key in columns.keys()])
+
+    header = columns.values()
+    output = tabulate(data_entries, header, numalign='left')
+    return output
 
-{% endfor %}
-"""
 
 def show_status():
     # A ddclient status file must not always exist
     if not os.path.exists(cache_file):
         sys.exit(0)
 
-    data = {
-        'hosts': []
-    }
+    data = []
 
     with open(cache_file, 'r') as f:
         for line in f:
             if line.startswith('#'):
                 continue
 
-            outp = {
-                'host': '',
-                'ip': '',
-                'time': ''
-            }
-
-            if 'host=' in line:
-                host = line.split('host=')[1]
-                if host:
-                    outp['host'] = host.split(',')[0]
-
-            if 'ip=' in line:
-                ip = line.split('ip=')[1]
-                if ip:
-                    outp['ip'] = ip.split(',')[0]
-
-            if 'mtime=' in line:
-                mtime = line.split('mtime=')[1]
-                if mtime:
-                    outp['time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(mtime.split(',')[0], base=10)))
+            props = {}
+            # ddclient cache rows have properties in 'key=value' format separated by comma
+            # we pick up the ones we are interested in
+            for kvraw in line.split(' ')[0].split(','):
+                k, v = kvraw.split('=')
+                if k in columns.keys():
+                    props[k] = v
 
-            if 'status=' in line:
-                status = line.split('status=')[1]
-                if status:
-                    outp['status'] = status.split(',')[0]
+            # Convert mtime to human readable format
+            if 'mtime' in props:
+                props['mtime'] = time.strftime(
+                    "%Y-%m-%d %H:%M:%S", time.localtime(int(props['mtime'], base=10)))
 
-            data['hosts'].append(outp)
+            data.append(props)
 
-    tmpl = jinja2.Template(OUT_TMPL_SRC)
-    print(tmpl.render(data))
+    print(_get_formatted_host_records(data))
 
 
 def update_ddns():
-- 
cgit v1.2.3