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 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 import logging
from config import Validator from config import Validator
import config.interface as interface import config.interface as interface
from vpp.vppapi import VPPApi from vpp.reconciler import Reconciler
try: try:
import argparse 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('-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('-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('-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() args = parser.parse_args()
@ -58,16 +59,33 @@ def main():
logging.error("Configuration is not valid, bailing") logging.error("Configuration is not valid, bailing")
sys.exit(-2) sys.exit(-2)
vpp = VPPApi() r = Reconciler(cfg)
vpp.readconfig() if not r.readconfig():
if not vpp.phys_exist(interface.get_phys(cfg)): logging.error("Couldn't read config from VPP")
logging.error("Not all PHYs in the config exist in VPP")
vpp.disconnect()
sys.exit(-3) 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__": if __name__ == "__main__":
main() main()