From de95e522ab675364a26d1a3f248595734b414d9b Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Thu, 24 Mar 2022 15:57:12 +0000 Subject: [PATCH] Move VPPApi into a Reconciler class, add (empty) prune() create() and sync() methods. Add --force flag to enable making progress after warnings are issued --- vpp/__init__.py | 3 ++- vpp/reconciler.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++ vppcfg | 34 ++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 vpp/reconciler.py diff --git a/vpp/__init__.py b/vpp/__init__.py index 965dd04..3b20c4b 100644 --- a/vpp/__init__.py +++ b/vpp/__init__.py @@ -20,4 +20,5 @@ from __future__ import ( ) import logging -import vpp.vppapi +from vpp.vppapi import VPPApi +from vpp.reconciler import Reconciler diff --git a/vpp/reconciler.py b/vpp/reconciler.py new file mode 100644 index 0000000..614e6cd --- /dev/null +++ b/vpp/reconciler.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# +# Copyright (c) 2022 Pim van Pelt +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# -*- coding: utf-8 -*- +import logging +from vpp.vppapi import VPPApi + +class Reconciler(): + def __init__(self, cfg): + self.logger = logging.getLogger('vppcfg.vppapi') + self.logger.addHandler(logging.NullHandler()) + + self.vpp = VPPApi() + + def readconfig(self): + return self.vpp.readconfig() + + def phys_exist(self, ifname_list): + """ Return True if all interfaces in the `ifname_list` exist as physical interface names + in VPP. Return False otherwise.""" + ret = True + for ifname in ifname_list: + if not ifname in self.vpp.config['interface_names']: + self.logger.warning("Interface %s does not exist in VPP" % ifname) + ret = False + return ret + + def prune_addresses(self, ifname, address_list): + """ Remove all addresses from interface ifname, except those in address_list """ + + def prune(self): + return False + + def create(self): + return False + + def sync(self): + return False diff --git a/vppcfg b/vppcfg index 732090e..934a323 100755 --- a/vppcfg +++ b/vppcfg @@ -19,7 +19,7 @@ import yaml import logging from config import Validator import config.interface as interface -from vpp.vppapi import VPPApi +from vpp.reconciler import Reconciler try: import argparse @@ -34,6 +34,7 @@ def main(): parser.add_argument('-s', '--schema', dest='schema', type=str, default='./schema.yaml', help="""YAML schema validation file""") parser.add_argument('-d', '--debug', dest='debug', action='store_true', help="""Enable debug, default False""") parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', help="""Be quiet (only log warnings/errors), default False""") + parser.add_argument('-f', '--force', dest='force', action='store_true', help="""Force progress despite warnings, default False""") args = parser.parse_args() @@ -58,16 +59,33 @@ def main(): logging.error("Configuration is not valid, bailing") sys.exit(-2) - vpp = VPPApi() - vpp.readconfig() - if not vpp.phys_exist(interface.get_phys(cfg)): - logging.error("Not all PHYs in the config exist in VPP") - vpp.disconnect() + r = Reconciler(cfg) + if not r.readconfig(): + logging.error("Couldn't read config from VPP") sys.exit(-3) - vpp.dump() + if not r.phys_exist(interface.get_phys(cfg)): + logging.error("Not all PHYs in the config exist in VPP") + sys.exit(-4) + + if not r.prune(): + if not args.force: + logging.error("Reconciliation prune failure") + sys.exit(-5) + logging.warning("Reconciliation prune failure, continuing due to --force") + + if not r.create(): + if not args.force: + logging.error("Reconciliation create failure") + sys.exit(-6) + logging.warning("Reconciliation create failure, continuing due to --force") + + if not r.sync(): + if not args.force: + logging.error("Reconciliation sync failure") + sys.exit(-7) + logging.warning("Reconciliation sync failure, continuing due to --force") - vpp.disconnect() if __name__ == "__main__": main()