summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2023-10-05 12:39:48 -0500
committerGitHub <noreply@github.com>2023-10-05 12:39:48 -0500
commit669acb05c91aa90f28b9aee823b27c7a29afdec0 (patch)
treee65674b329776aed3fa25cfddcaa5b3afdda8a88
parentaf17ef9b1069da7a00b4ed3ef03e7417e95150ec (diff)
parent0b832eca6d2da63bcebb324b44ceac22a925efbd (diff)
downloadvyos-1x-669acb05c91aa90f28b9aee823b27c7a29afdec0.tar.gz
vyos-1x-669acb05c91aa90f28b9aee823b27c7a29afdec0.zip
Merge pull request #2341 from vyos/mergify/bp/sagitta/pr-2339
config: T5631: save copy of config in JSON format on commit (backport #2339)
-rw-r--r--python/vyos/config_mgmt.py29
-rwxr-xr-xsrc/helpers/vyos-save-config.py19
2 files changed, 42 insertions, 6 deletions
diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py
index dbf17ade4..654a8d698 100644
--- a/python/vyos/config_mgmt.py
+++ b/python/vyos/config_mgmt.py
@@ -25,7 +25,7 @@ from datetime import datetime
from textwrap import dedent
from pathlib import Path
from tabulate import tabulate
-from shutil import copy
+from shutil import copy, chown
from vyos.config import Config
from vyos.configtree import ConfigTree, ConfigTreeError, show_diff
@@ -37,6 +37,7 @@ from vyos.utils.process import is_systemd_service_active
from vyos.utils.process import rc_cmd
SAVE_CONFIG = '/usr/libexec/vyos/vyos-save-config.py'
+config_json = '/run/vyatta/config/config.json'
# created by vyatta-cfg-postinst
commit_post_hook_dir = '/etc/commit/post-hooks.d'
@@ -64,8 +65,11 @@ formatter = logging.Formatter('%(funcName)s: %(levelname)s:%(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
-def save_config(target):
- cmd = f'{SAVE_CONFIG} {target}'
+def save_config(target, json_out=None):
+ if json_out is None:
+ cmd = f'{SAVE_CONFIG} {target}'
+ else:
+ cmd = f'{SAVE_CONFIG} {target} --write-json-file {json_out}'
rc, out = rc_cmd(cmd)
if rc != 0:
logger.critical(f'save config failed: {out}')
@@ -326,6 +330,12 @@ Proceed ?'''
"""
mask = os.umask(0o002)
os.makedirs(archive_dir, exist_ok=True)
+ json_dir = os.path.dirname(config_json)
+ try:
+ os.makedirs(json_dir, exist_ok=True)
+ chown(json_dir, group='vyattacfg')
+ except OSError as e:
+ logger.warning(f'cannot create {json_dir}: {e}')
self._add_logrotate_conf()
@@ -481,10 +491,21 @@ Proceed ?'''
ext = os.getpid()
cmp_saved = f'/tmp/config.boot.{ext}'
if save_to_tmp:
- save_config(cmp_saved)
+ save_config(cmp_saved, json_out=config_json)
else:
copy(config_file, cmp_saved)
+ # on boot, we need to manually create the config.json file; after
+ # boot, it is written by save_config, above
+ if not os.path.exists(config_json):
+ ct = self._get_saved_config_tree()
+ try:
+ with open(config_json, 'w') as f:
+ f.write(ct.to_json())
+ chown(config_json, group='vyattacfg')
+ except OSError as e:
+ logger.warning(f'cannot create {config_json}: {e}')
+
try:
if cmp(cmp_saved, archive_config_file, shallow=False):
os.unlink(cmp_saved)
diff --git a/src/helpers/vyos-save-config.py b/src/helpers/vyos-save-config.py
index 8af4a7916..518bd9864 100755
--- a/src/helpers/vyos-save-config.py
+++ b/src/helpers/vyos-save-config.py
@@ -19,6 +19,7 @@ import os
import re
import sys
from tempfile import NamedTemporaryFile
+from argparse import ArgumentParser
from vyos.config import Config
from vyos.remote import urlc
@@ -28,8 +29,15 @@ from vyos.defaults import directories
DEFAULT_CONFIG_PATH = os.path.join(directories['config'], 'config.boot')
remote_save = None
-if len(sys.argv) > 1:
- save_file = sys.argv[1]
+parser = ArgumentParser(description='Save configuration')
+parser.add_argument('file', type=str, nargs='?', help='Save configuration to file')
+parser.add_argument('--write-json-file', type=str, help='Save JSON of configuration to file')
+args = parser.parse_args()
+file = args.file
+json_file = args.write_json_file
+
+if file is not None:
+ save_file = file
else:
save_file = DEFAULT_CONFIG_PATH
@@ -51,6 +59,13 @@ with open(write_file, 'w') as f:
f.write("\n")
f.write(system_footer())
+if json_file is not None and ct is not None:
+ try:
+ with open(json_file, 'w') as f:
+ f.write(ct.to_json())
+ except OSError as e:
+ print(f'failed to write JSON file: {e}')
+
if remote_save is not None:
try:
remote_save.upload(write_file)