From b09773ae75ed138b870b0741dd73a5b038456d8a Mon Sep 17 00:00:00 2001 From: Dave Wallace Date: Tue, 26 Apr 2022 21:04:31 -0400 Subject: [PATCH] vppcfg: add args to specify location of vpp api files - refactor to address review comments. Signed-off-by: Dave Wallace --- vpp/dumper.py | 9 ++++++-- vpp/reconciler.py | 4 ++-- vpp/vppapi.py | 22 ++++++++++++------ vppcfg | 58 +++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/vpp/dumper.py b/vpp/dumper.py index 13ced60..476d517 100644 --- a/vpp/dumper.py +++ b/vpp/dumper.py @@ -31,8 +31,13 @@ class Dumper(VPPApi): Note that not all running VPP configs are "valid" in vppcfg's eyes. It is not guaranteed that the output of the Dumper() will stand validation.""" - def __init__(self, address="/run/vpp/api.sock", clientname="vppcfg"): - VPPApi.__init__(self, address, clientname) + def __init__( + self, + vpp_api_socket="/run/vpp/api.sock", + vpp_json_dir="/usr/share/vpp/api/", + clientname="vppcfg", + ): + VPPApi.__init__(self, vpp_api_socket, vpp_json_dir, clientname) def write(self, outfile): """Emit the configuration to either stdout (outfile=='-') or a filename""" diff --git a/vpp/reconciler.py b/vpp/reconciler.py index 8eda3e8..d5c5599 100644 --- a/vpp/reconciler.py +++ b/vpp/reconciler.py @@ -38,11 +38,11 @@ class Reconciler: but not yet in the dataplane; and finally it syncs the configuration attributes of objects that can be changed at runtime.""" - def __init__(self, cfg): + def __init__(self, cfg, vpp_api_socket='/run/vpp/api.sock', vpp_json_dir='/usr/share/vpp/api/'): self.logger = logging.getLogger("vppcfg.reconciler") self.logger.addHandler(logging.NullHandler()) - self.vpp = VPPApi() + self.vpp = VPPApi(vpp_api_socket, vpp_json_dir) self.cfg = cfg ## List of CLI calls emitted during the prune, create and sync phases. diff --git a/vpp/vppapi.py b/vpp/vppapi.py index 40dbd32..a4caf94 100644 --- a/vpp/vppapi.py +++ b/vpp/vppapi.py @@ -28,11 +28,22 @@ from vpp_papi import VPPApiClient class VPPApi: """The VPPApi class is a base class that abstracts the vpp_papi.""" - def __init__(self, address="/run/vpp/api.sock", clientname="vppcfg"): + def __init__( + self, + vpp_api_socket="/run/vpp/api.sock", + vpp_json_dir="/usr/share/vpp/api/", + clientname="vppcfg", + ): self.logger = logging.getLogger("vppcfg.vppapi") self.logger.addHandler(logging.NullHandler()) - self.address = address + if not os.path.exists(vpp_api_socket): + self.logger.error(f"VPP api socket file not found: {vpp_api_socket}") + if not os.path.isdir(vpp_json_dir): + self.logger.error(f"VPP api json directory not found: {vpp_json_dir}") + + self.vpp_api_socket = vpp_api_socket + self.vpp_json_dir = vpp_json_dir self.connected = False self.clientname = clientname self.vpp = None @@ -45,12 +56,9 @@ class VPPApi: if self.connected: return True - vpp_json_dir = "/usr/share/vpp/api/" - ## vpp_json_dir = "/home/pim/src/vpp/build-root/build-vpp_debug-native/vpp/CMakeFiles/" - # construct a list of all the json api files jsonfiles = [] - for root, _dirnames, filenames in os.walk(vpp_json_dir): + for root, _dirnames, filenames in os.walk(self.vpp_json_dir): for filename in fnmatch.filter(filenames, "*.api.json"): jsonfiles.append(os.path.join(root, filename)) @@ -58,7 +66,7 @@ class VPPApi: self.logger.error("no json api files found") return False - self.vpp = VPPApiClient(apifiles=jsonfiles, server_address=self.address) + self.vpp = VPPApiClient(apifiles=jsonfiles, server_address=self.vpp_api_socket) try: self.logger.debug("Connecting to VPP") self.vpp.connect(self.clientname) diff --git a/vppcfg b/vppcfg index 7ce9fe6..4075999 100755 --- a/vppcfg +++ b/vppcfg @@ -86,6 +86,22 @@ def main(): type=str, help="""Output file for YAML config, default stdout""", ) + dump_p.add_argument( + "-j", + "--vpp-json-dir", + dest="vpp_json_dir", + required=False, + type=str, + help="""Directory where VPP API JSON files are located""", + ) + dump_p.add_argument( + "-a", + "--vpp-api-socket", + dest="vpp_api_socket", + required=False, + type=str, + help="""Pathname of VPP API socket file""", + ) plan_p = subparsers.add_parser( "plan", @@ -115,6 +131,22 @@ def main(): type=str, help="""Output file for VPP CLI commands, default stdout""", ) + plan_p.add_argument( + "-j", + "--vpp-json-dir", + dest="vpp_json_dir", + required=False, + type=str, + help="""Directory where VPP API JSON files are located""", + ) + plan_p.add_argument( + "-a", + "--vpp-api-socket", + dest="vpp_api_socket", + required=False, + type=str, + help="""Pathname of VPP API socket file""", + ) apply_p = subparsers.add_parser( "apply", help="apply changes from current VPP dataplane to target config" @@ -134,6 +166,22 @@ def main(): type=str, help="""YAML configuration file for vppcfg""", ) + apply_p.add_argument( + "-j", + "--vpp-json-dir", + dest="vpp_json_dir", + required=False, + type=str, + help="""Directory where VPP API JSON files are located""", + ) + apply_p.add_argument( + "-a", + "--vpp-api-socket", + dest="vpp_api_socket", + required=False, + type=str, + help="""Pathname of VPP API socket file""", + ) args = parser.parse_args() if not args.command: @@ -150,8 +198,14 @@ def main(): format="[%(levelname)-8s] %(name)s.%(funcName)s: %(message)s", level=level ) + opt_kwargs = {} + if args.vpp_json_dir: + opt_kwargs["vpp_json_dir"] = args.vpp_json_dir + if args.vpp_api_socket: + opt_kwargs["vpp_api_socket"] = args.vpp_api_socket + if args.command == "dump": - dumper = Dumper() + dumper = Dumper(**opt_kwargs) if not dumper.readconfig(): logging.error("Could not retrieve config from VPP") sys.exit(-7) @@ -175,7 +229,7 @@ def main(): if args.command == "check": sys.exit(0) - reconciler = Reconciler(cfg) + reconciler = Reconciler(cfg, **opt_kwargs) if not reconciler.vpp.readconfig(): sys.exit(-3)