Move VPPApi into a Reconciler class, add (empty) prune() create() and sync() methods. Add --force flag to enable making progress after warnings are issued

This commit is contained in:
Pim van Pelt
2022-03-24 15:57:12 +00:00
parent 2e2f63e1dd
commit de95e522ab
3 changed files with 77 additions and 9 deletions

View File

@ -20,4 +20,5 @@ from __future__ import (
)
import logging
import vpp.vppapi
from vpp.vppapi import VPPApi
from vpp.reconciler import Reconciler

49
vpp/reconciler.py Normal file
View File

@ -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

34
vppcfg
View File

@ -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()