feature: stateless planning
Add a feature to plan a configuration without reading from the VPP Dataplane. In this mode, the configuration file is read and validated in the same way as `check` or `plan`, but then instead of retrieving the running state from the VPP API, a state is re-created using the physical interfaces specified in the YAML config. Implement this by creating vppapi:mockconfig() which reads the 'interfaces' scope from the YAML config file, and creates a VPPMessage() of type sw_interface_details for each interface that is a PHY (for now, only supporting device-type 'dpdk'). If the flag --novpp is specified in the planner, call mockconfig() instead of readconfig(). Some further details: - if the MAC is not set in the YAML config, it won't be set in the output exec file. - for bondethernets, no MAC can be generated unless it's set in the first member. - the MTU is always set, because it's mocked to 64b and the YAML file will always be higher. TESTED: - the unit tests and YAML tests all pass - the integration tests all pass, but they do not call this new codepath - Based on an empty VPP on Hippo, I compared the output of these two, side by side: for i in intest/*yaml; do ./vppcfg.py plan -c $i -o /tmp/$i-vpp.exec; done for i in intest/*yaml; do ./vppcfg.py plan --novpp -c $i -o /tmp/$i-novpp.exec; done ==> The only changes here are: * if I cannot determine the bondether MAC in the --novpp case, it is not emitted * if the MAC address is set in the YAML file, the --novpp case will always emit it * if VPP has mtu 9000, the --novpp case will end up still emitting interface and packet MTU, because it mocks the interface MTU at 64. In all cases, --novpp emits more configuration statements, and the statements that it emits are redundant.
This commit is contained in:
@@ -130,6 +130,12 @@ def main():
|
||||
type=str,
|
||||
help="""YAML configuration file for vppcfg""",
|
||||
)
|
||||
plan_p.add_argument(
|
||||
"--novpp",
|
||||
dest="novpp",
|
||||
action="store_true",
|
||||
help="""Don't query VPP API, assume 'empty' dataplane config""",
|
||||
)
|
||||
plan_p.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
@@ -238,22 +244,26 @@ def main():
|
||||
sys.exit(0)
|
||||
|
||||
reconciler = Reconciler(cfg, **opt_kwargs)
|
||||
if not reconciler.vpp.readconfig():
|
||||
sys.exit(-3)
|
||||
if args.novpp:
|
||||
if not reconciler.vpp.mockconfig(cfg):
|
||||
sys.exit(-7)
|
||||
else:
|
||||
if not reconciler.vpp.readconfig():
|
||||
sys.exit(-3)
|
||||
|
||||
if not reconciler.phys_exist_in_vpp():
|
||||
logging.error("Not all PHYs in the config exist in VPP")
|
||||
sys.exit(-4)
|
||||
if not reconciler.phys_exist_in_vpp():
|
||||
logging.error("Not all PHYs in the config exist in VPP")
|
||||
sys.exit(-4)
|
||||
|
||||
if not reconciler.phys_exist_in_config():
|
||||
logging.error("Not all PHYs in VPP exist in the config")
|
||||
sys.exit(-5)
|
||||
if not reconciler.phys_exist_in_config():
|
||||
logging.error("Not all PHYs in VPP exist in the config")
|
||||
sys.exit(-5)
|
||||
|
||||
if not reconciler.lcps_exist_with_lcp_enabled():
|
||||
logging.error(
|
||||
"Linux Control Plane is needed, but linux-cp API is not available"
|
||||
)
|
||||
sys.exit(-6)
|
||||
if not reconciler.lcps_exist_with_lcp_enabled():
|
||||
logging.error(
|
||||
"Linux Control Plane is needed, but linux-cp API is not available"
|
||||
)
|
||||
sys.exit(-6)
|
||||
|
||||
failed = False
|
||||
if not reconciler.prune():
|
||||
|
||||
Reference in New Issue
Block a user