Your first steps in modifying the SORESPO codebase and seeing the effects in the lab.
Introduction
This tutorial will guide you through making your first changes to the SORESPO automation code and building the application. If you are not yet familiar with the basic steps involved in running and interacting with SORESPO, you might want to start out with the tutorial on running SORESPO first.
Preparing the Environment
- Install the following prerequisites:
- Docker Desktop (or Colima for an open-source alternative)
- Git, coreutils , and
Acton, all of which
you can install with Homebrew:
- Note: Acton is an additional prerequisite compared to running SORESPO
brew install git coreutils actonlang/acton/acton - After the installation has completed, start your container runtime.
- For Docker Desktop, open Settings and in the Resources section make sure you've allocated at least 4 CPU cores and 8GB of RAM to Docker.
- Or, start your Colima VM with the appropriate resources:
colima start --cpu 4 --memory 8
Starting the SORESPO Network
NOTE: If you already completed the tutorial on running SORESPO, you can skip ahead to the next step!
Clone the project:
git clone https://github.com/stratoweave/sorespo.git
Go into the sorespo/test/quicklab-srl directory and start the development
tutorial:
cd sorespo/test/quicklab-srl
make dev-tutorial
...
... # Containerlab starts the SR Linux lab, this may take a few minutes ...
...
StratoWeave/sorespo running..
...
All config files applied
...
You now have a running lab topology with fully configured containerized routers. The current state of the lab is identical to the final step in the tutorial on running SORESPO.
Notes:
- The SORESPO process runs interactively in this shell window. When you kill it with Ctrl+C, SORESPO itself will stop, but the lab and all the routers will continue to run.
- Open a second shell to continue with the tutorial.
- The lab can be shut down with
make stop.
Modifying the SORESPO application
Changing the application typically involves modifying the RFS transforms to modify the output configuration and optionally modifying the models.
Retrieve the current configuration on the ams-core-1 router, by connecting to
the router directly over NETCONF.
In a new shell navigate to the sorespo/test/quicklab-srl
directory and get the configuration:
cd sorespo/test/quicklab-srl
make get-dev-config-ams-core-1 | sed -n '/<interface xmlns="urn:nokia.com:srlinux:chassis:interfaces">/,/<\/interface>/p'
NOTE: The sed command filters the output down to the interface section.
Part of the output is the VRF interface:
...
<interface xmlns="urn:nokia.com:srlinux:chassis:interfaces">
<name>ethernet-1/3</name>
<admin-state>enable</admin-state>
<vlan-tagging xmlns="urn:nokia.com:srlinux:chassis:interfaces-vlans">true</vlan-tagging>
<subinterface>
<index>100</index>
<description>Customer VPN access SITE-1 [SNA-1-1] in VPN acme-65501</description>
<admin-state>enable</admin-state>
<ipv4>
<admin-state>enable</admin-state>
<address>
<ip-prefix>10.201.1.1/30</ip-prefix>
</address>
</ipv4>
<vlan xmlns="urn:nokia.com:srlinux:chassis:interfaces-vlans">
<encap>
<single-tagged>
<vlan-id>100</vlan-id>
</single-tagged>
</encap>
</vlan>
</subinterface>
</interface>
...
Notice how SORESPO filled in a handy interface description for the
subinterface, but there is no description on the main ethernet-1/3
interface. Modify the SORESPO code to add in a description.
Open sorespo/src/sorespo/rfs.act in your favorite editor and find the
following section of the code:
class VrfInterface(base.VrfInterface):
def transform(self, i, di):
...
elif "srl_nokia-system" in di.modules:
print("RFS /rfs{{{di.name}}}/vrf-interface transform running {i.name} for Nokia SRLinux", err=True)
dev = srl25.root()
# Create the main interface
intf = dev.interface.create(main_intf)
intf.admin_state = "enable"
intf.vlan_tagging = True
Modify sorespo/src/sorespo/rfs.act to set an interface description on
VRF interfaces:
class VrfInterface(base.VrfInterface):
def transform(self, i, di):
...
elif "srl_nokia-system" in di.modules:
print("RFS /rfs{{{di.name}}}/vrf-interface transform running {i.name} for Nokia SRLinux", err=True)
dev = srl25.root()
# Create the main interface
intf = dev.interface.create(main_intf)
intf.admin_state = "enable"
intf.vlan_tagging = True
+ intf.description = "VRF Interface for customer connections"
After you have saved the file to disk, re-build the SORESPO binary to incorporate the change. Press Ctrl+C in the terminal window where SORESPO is running.
In the same terminal window trigger a build:
- If you are running macOS on Apple Silicon use:
make -C ../../ build-linux-aarch64
- If you are running macOS on Intel use:
make -C ../../ build-linux-x86_64
NOTE: With -C ../../ make runs the build recipe two
levels up from the current directory, saving us the hassle of moving around in
the directory structure.
After the build has completed copy your updated binary into the lab and re-run and re-configure SORESPO:
make copy run-and-configure
Wait a few seconds for SORESPO to apply your changes to the routers and repeat the steps above to validate your change was successful.
make get-dev-config-ams-core-1 | sed -n '/<interface xmlns="urn:nokia.com:srlinux:chassis:interfaces">/,/<\/interface>/p'
The interface description has been applied to each of the VRF interfaces:
...
<interface xmlns="urn:nokia.com:srlinux:chassis:interfaces">
<name>ethernet-1/3</name>
+ <description>VRF Interface for customer connections</description>
<admin-state>enable</admin-state>
<vlan-tagging xmlns="urn:nokia.com:srlinux:chassis:interfaces-vlans">true</vlan-tagging>
<subinterface>
<index>100</index>
<description>Customer VPN access SITE-1 [SNA-1-1] in VPN acme-65501</description>
<admin-state>enable</admin-state>
<ipv4>
<admin-state>enable</admin-state>
<address>
<ip-prefix>10.201.1.1/30</ip-prefix>
</address>
</ipv4>
<vlan xmlns="urn:nokia.com:srlinux:chassis:interfaces-vlans">
<encap>
<single-tagged>
<vlan-id>100</vlan-id>
</single-tagged>
</encap>
</vlan>
</subinterface>
</interface>
...Modifying the SORESPO YANG models
Besides modifying transform code, you may also want to modify the YANG models themselves to be able to pass different parameters from layer to layer.
Retrieve the current input to the RFS layer, i.e. layer2:
make get-config2 | sed -n '/<vrf-interface>/,/<\/vrf-interface>/p'
Part of the output will be a configuration instance for the vrf-interface on ams-core-1:
...
<vrf-interface>
<name>ethernet-1/3.100</name>
<description>Customer VPN access SITE-1 [SNA-1-1] in VPN acme-65501</description>
<vrf>acme-65501</vrf>
<ipv4-address>10.201.1.1</ipv4-address>
<ipv4-prefix-length>30</ipv4-prefix-length>
</vrf-interface>
</rfs>
...
This RFS instance at present does not have an input for MTU configuration.
Review the YANG model for this layer in sorespo/spec/yang/rfs/sorespo-rfs.yang.
...
list vrf-interface {
key "name";
sw:rfs-transform sorespo.rfs.VrfInterface;
leaf name {
type string;
}
leaf description {
type string;
}
leaf vrf {
type string;
description
"VRF name";
mandatory true;
}
leaf ipv4-address {
type inet:ipv4-address;
}
leaf ipv4-prefix-length {
type uint8 {
range "1..31";
}
default "30";
}
}
Modify the YANG module to add in the mtu leaf:
...
list vrf-interface {
key "name";
sw:rfs-transform sorespo.rfs.VrfInterface;
leaf name {
type string;
}
leaf description {
type string;
}
leaf vrf {
type string;
description
"VRF name";
mandatory true;
}
leaf ipv4-address {
type inet:ipv4-address;
}
leaf ipv4-prefix-length {
type uint8 {
range "1..31";
}
default "30";
}
+ leaf mtu {
+ type uint16 {
+ range "1..9000";
+ }
+ }
}
Open sorespo/src/sorespo/inter.act in your favorite editor and find the
following section of the code:
...
class L3Vpn(base.L3Vpn):
def transform(self, i):
...
vi = rfs.vrf_interface.create(ep.interface)
vi.description = "Customer VPN access %s [%s] in VPN %s" % (ep.site, ep.site_network_access, i.name)
vi.ipv4_address = ep.provider_ipv4_address
vi.ipv4_prefix_length = ep.ipv4_prefix_length
vi.vrf = i.name
Modify sorespo/src/sorespo/inter.act to set an MTU on VRF interfaces:
...
class L3Vpn(base.L3Vpn):
def transform(self, i):
...
vi = rfs.vrf_interface.create(ep.interface)
vi.description = "Customer VPN access %s [%s] in VPN %s" % (ep.site, ep.site_network_access, i.name)
vi.ipv4_address = ep.provider_ipv4_address
vi.ipv4_prefix_length = ep.ipv4_prefix_length
vi.vrf = i.name
+ vi.mtu = 1500
After you have saved the files to disk, you can re-build the SORESPO binary to incorporate the change. Press Ctrl+C in the terminal window where SORESPO is running.
In the same terminal window, request the StratoWeave build system and Acton YANG parser to re-generate the codebase from the SORESPO YANG modules:
make -C ../../ gen
In the same terminal window trigger a build:
- If you are running macOS on Apple Silicon use:
make -C ../../ build-linux-aarch64
- If you are running macOS on Intel use:
make -C ../../ build-linux-x86_64
After the build has completed copy your updated binary into the lab and re-run and re-configure SORESPO:
make copy run-and-configure
Wait a few seconds for SORESPO to start and retrieve the configuration for
layer2.
make get-config2
Part of the output will be a configuration instance for the vrf-interface on
ams-core-1:
...
<vrf-interface>
<name>ethernet-1/3.100</name>
<description>Customer VPN access SITE-1 [SNA-1-1] in VPN acme-65501</description>
<vrf>acme-65501</vrf>
<ipv4-address>10.201.1.1</ipv4-address>
<ipv4-prefix-length>30</ipv4-prefix-length>
+ <mtu>1500</mtu>
</vrf-interface>
...
Note: In reality, You wouldn't likely hard-code the MTU in the Intermediate Transform. We would expect the MTU to be passed down from higher layers, e.g. from the CFS intent all the way down to the device configuration. But the development process from here on out is always the same.
What's Next
Now that you are familiar with running and developing for SORESPO, continue to explore the other labs we have available, including more router vendors etc..