From ce15b5a6fd440af1fe86d9c7ed848a9190857c07 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Sun, 3 Apr 2022 13:18:32 +0000 Subject: [PATCH] Document 'vppcfg plan' including an example --- docs/user-guide.md | 68 +++++++++++++++++++++++++++++++++++++++- example.exec | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 example.exec diff --git a/docs/user-guide.md b/docs/user-guide.md index e1b092a..190589e 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -104,7 +104,8 @@ $ vppcfg check -c semantic-invalid.yaml && echo OK In general, it's good practice to check the validity of a YAML file before attempting to offer it for reconciliation. `vppcfg` will make no guarantees in case its input is not -fully valid! +fully valid! For a full write up of the syntax and semantic validation, see +[this post](https://ipng.ch/s/articles/2022/03/27/vppcfg-1.html). ### vppcfg dump @@ -152,4 +153,69 @@ $ vppcfg dump ### vppcfg plan +The purpose of the **plan** module, is to read a configuration file given by the `-c/--config` +flag, ensure it is valid (see the **check** module for details), then connect to the running +VPP instance, retrieve its dataplane configuration into an in-memory cache, and plan a path +from the currently running dataplane configuration to the target configuration given in the +YAML file. + +*Note*: The planner will read the VPP runtime state exactly once at startup, and it will not +make any changes to the dataplane. This operation is safe to run. + +After it reads the YAML target config and the currently running dataplane config from VPP, it +will plan a path to get into the desired target config. It does this in three phases: + +***Pruning***: First, vppcfg will ensure all objects do not have attributes which they should not +(eg. IP addresses) and that objects are destroyed that are not needed (ie. have been removed from +the target config). After this phase, I am certain that any object that exists in the dataplane, +both (a) has the right to exist (because it’s in the target configuration), and (b) has the correct +create-time (ie non syncable) attributes. + +***Creating***: Next, vppcfg will ensure that all objects that are not yet present (including the +ones that it just removed because they were present but had incorrect attributes), get (re)created +in the right order. After this phase, I am certain that all objects in the dataplane now (a) have +the right to exist (because they are in the target configuration), (b) have the correct attributes, +but newly, also that (c) all objects that are in the target configuration also got created and now +exist in the dataplane. + +***Syncing***: Finally, all objects are synchronized with the target configuration (IP addresses, +MTU etc), taking care to shrink children before their parents, and growing parents before their +children (this is for the special case of any given sub-interface’s MTU having to be equal to or +lower than their parent’s MTU). + +If no further flags are given, planning output is given to stdout. Optionally an output file +can be specified by calling with the `-o/--output` flag. The contents of the output is +a set of CLI commands that could be pasted into a `vppctl` shell in the order they are presented. +Alternatively, the output file can be consumed by VPP by issuing `vppctl exec `, noting +that the filename has to be an absolute path. + +Users are not encouraged to program VPP this way (see the **apply** module for that), however +for the sake of completeness: + +``` +$ vppcfg plan -c example.yaml -o example.exec +[INFO ] root.main: Loading configfile example.yaml +[INFO ] vppcfg.config.valid_config: Configuration validated successfully +[INFO ] root.main: Configuration is valid +[INFO ] vppcfg.vppapi.connect: VPP version is 22.06-rc0~320-g8f60318ac +[INFO ] vppcfg.reconciler.write: Wrote 78 lines to example.exec +[INFO ] root.main: Planning succeeded + +$ vppctl exec ~/src/vppcfg/example.exec + +$ vppcfg plan -c example.yaml +[INFO ] root.main: Loading configfile example.yaml +[INFO ] vppcfg.config.valid_config: Configuration validated successfully +[INFO ] root.main: Configuration is valid +[INFO ] vppcfg.vppapi.connect: VPP version is 22.06-rc0~320-g8f60318ac +[INFO ] vppcfg.reconciler.write: Wrote 0 lines to (stdout) +[INFO ] root.main: Planning succeeded +``` + +For an in-depth discussion on path-planning and how `vppcfg` operates, see +[this post](https://ipng.ch/s/articles/2022/04/02/vppcfg-2.html). + ### vppcfg apply + +Applying state is not (yet) implemented. Don't worry, it's not much work, but this is punted until +developer community feedback is reviewed :-) diff --git a/example.exec b/example.exec new file mode 100644 index 0000000..22ac729 --- /dev/null +++ b/example.exec @@ -0,0 +1,78 @@ +comment { vppcfg prune: 4 CLI statement(s) follow } +set interface l3 HundredGigabitEthernet12/0/0 +create bridge-domain 10 del +set interface ip address del GigabitEthernet3/0/0.100 2001:db8:1::1/64 +delete sub GigabitEthernet3/0/0.100 +comment { vppcfg create: 20 CLI statement(s) follow } +create loopback interface instance 0 +create loopback interface instance 1 +create bond mode lacp load-balance l34 id 0 +create vxlan tunnel src 192.0.2.1 dst 192.0.2.2 instance 1 vni 101 decap-next l2 +create sub HundredGigabitEthernet12/0/0 1234 dot1q 1234 exact-match +create sub BondEthernet0 10 dot1q 10 exact-match +create sub BondEthernet0 100 dot1q 100 +create sub BondEthernet0 200 dot1q 200 +create sub BondEthernet0 500 dot1ad 500 +create sub BondEthernet0 501 dot1ad 501 +create sub HundredGigabitEthernet12/0/0 1235 dot1q 1234 inner-dot1q 1000 exact-match +create bridge-domain 1 +create bridge-domain 11 +lcp create HundredGigabitEthernet12/0/0 host-if ice12-0-0 +lcp create BondEthernet0 host-if bond0 +lcp create loop0 host-if lo0 +lcp create loop1 host-if bvi1 +lcp create HundredGigabitEthernet12/0/0.1234 host-if ice0.1234 +lcp create BondEthernet0.10 host-if bond0.10 +lcp create HundredGigabitEthernet12/0/0.1235 host-if ice0.1234.1000 +comment { vppcfg sync: 51 CLI statement(s) follow } +bond add BondEthernet0 GigabitEthernet3/0/0 +bond add BondEthernet0 GigabitEthernet3/0/1 +comment { ip link set bond0 address 00:25:90:0c:05:01 } +set interface l2 bridge loop1 1 bvi +set interface l2 bridge BondEthernet0.500 1 +set interface l2 tag-rewrite BondEthernet0.500 pop 1 +set interface l2 bridge BondEthernet0.501 1 +set interface l2 tag-rewrite BondEthernet0.501 pop 1 +set interface l2 bridge HundredGigabitEthernet12/0/1 1 +set interface l2 tag-rewrite HundredGigabitEthernet12/0/1 disable +set interface l2 bridge vxlan_tunnel1 1 +set interface l2 tag-rewrite vxlan_tunnel1 disable +set interface l2 xconnect BondEthernet0.100 BondEthernet0.200 +set interface l2 tag-rewrite BondEthernet0.100 pop 1 +set interface l2 xconnect BondEthernet0.200 BondEthernet0.100 +set interface l2 tag-rewrite BondEthernet0.200 pop 1 +set interface mtu 9000 HundredGigabitEthernet12/0/0 +set interface mtu packet 2000 HundredGigabitEthernet12/0/1 +set interface mtu packet 2000 vxlan_tunnel1 +set interface mtu packet 1500 loop0 +set interface mtu packet 1500 loop1 +set interface mtu packet 9000 HundredGigabitEthernet12/0/0 +set interface mtu packet 1200 HundredGigabitEthernet12/0/0.1234 +set interface mtu packet 3000 BondEthernet0.10 +set interface mtu packet 2500 BondEthernet0.100 +set interface mtu packet 2500 BondEthernet0.200 +set interface mtu packet 2000 BondEthernet0.500 +set interface mtu packet 2000 BondEthernet0.501 +set interface mtu packet 1100 HundredGigabitEthernet12/0/0.1235 +set interface mtu 2000 HundredGigabitEthernet12/0/1 +set interface ip address HundredGigabitEthernet12/0/0 192.0.2.17/30 +set interface ip address HundredGigabitEthernet12/0/0 2001:db8:3::1/64 +set interface ip address loop0 10.0.0.1/32 +set interface ip address loop0 2001:db8::1/128 +set interface ip address loop1 10.0.1.1/24 +set interface ip address loop1 2001:db8:1::1/64 +set interface state GigabitEthernet3/0/0 up +set interface state GigabitEthernet3/0/1 up +set interface state HundredGigabitEthernet12/0/0 up +set interface state HundredGigabitEthernet12/0/0.1234 up +set interface state HundredGigabitEthernet12/0/0.1235 up +set interface state HundredGigabitEthernet12/0/1 up +set interface state BondEthernet0 up +set interface state BondEthernet0.10 up +set interface state BondEthernet0.100 up +set interface state BondEthernet0.200 up +set interface state BondEthernet0.500 up +set interface state BondEthernet0.501 up +set interface state vxlan_tunnel1 up +set interface state loop0 up +set interface state loop1 up