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:
@ -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
49
vpp/reconciler.py
Normal 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
34
vppcfg
@ -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()
|
||||||
|
Reference in New Issue
Block a user