Skip to content

networkop/cue-networking-II

Repository files navigation

CUE for Network Automation (Part II)

Walkthrough

  1. Pre-seed demo.nautobot.com with test data
cue apply ./...
  1. Retrieve device data from Nautobot and save it as a set of host variables
cue fetch ./...
  1. Print per-device structured configurations
cue try ./...
  1. Print final device configurations
cue show ./...
  1. Apply network configurations
cue push ./...
  1. Cleanup demo.nautobot.com
cue cleanup ./...

Creating CUE schemas

Option 1 - from Jinja templates

  1. Download the required Jinja templates and put them in the ./schemas/<vendor> directory.
cat schemas/arista/eos.conf_original.j2
  1. Remove all custom filters from a copy of each template.
cp arista/eos.conf_original.j2 arista/eos.conf.j2
sed -E -i 's/\|\s+arista\.avd\.\S+//' arista/eos.conf.j2
sed -E -i 's/arista.avd.defined/defined/g' arista/eos.conf.j2
sed -i -E 's/defined\(true\)/defined/' schemas/arista/eos.conf.j2
sed -i -E 's/defined\(false\)/defined/' schemas/arista/eos.conf.j2
sed -i -E 's/defined\(\'all\'\)/defined/' schemas/arista/eos.conf.j2
  1. Convert Jinja templates to a JSON schema
$ pip install jinja2schema
$ ./jinja-to-json-schema.py arista/eos.conf.j2
  1. Convert JSON schema into CUE
cue import -f -p schema schema.json -o arista/schema.cue
  1. (Optional) Make all fields optional
sed -i -E 's/(\s+\w+):/\1\?\:/' schemas/arista/schema.cue

Option 2 - from YAML files

  1. Get a copy of target device configuration in YAML format
cat schemas/nvidia/config.yml
  1. Generate a JSON schema from the YAML file
cat schemas/nvidia/schema.json
  1. Import as CUE
cue import -f -p schema nvidia/schema.json
  1. Cleanup the schema (remove concrete values and add constraints)
< import "net"
<
---
> @jsonschema(schema="http://json-schema.org/draft-06/schema#")
> _
12c12,15
< #Interface: [string]: #InterfaceClass
---
> #Interface: {
>       lo:   #Lo
>       swp1: #InterfaceSwp1
> }
14,15c17,18
< #InterfaceClass: {
<       ip?:   #IP
---
> #Lo: {
>       ip:   #IP
19c22,30
< #IP: address: [string & net.IPCIDR]: {}
---
> #IP: address: #Address
>
> #Address: "198.51.100.1/32": #["198.51.100.132"]
>
> #: "198.51.100.132": {
>       ...
> }
>
> #InterfaceSwp1: type: string
48c59
< #Neighbor: [string]: #NeighborClass
---
> #Neighbor: swp1: #NeighborSwp1
50c61
< #NeighborClass: {
---
> #NeighborSwp1: {

Working with Jinja (j2cli)

  1. Install j2cli
pip install j2cli
  1. Download any custom Jinja filters and test into the ./jinja directory.
tree jinja
jinja
├── filters
│   └── combined.py
└── tests
    └── defined.py
  1. Rename custom filters to get rid of namespacing
sed -E -i 's/arista.avd./arista_avd_/g' arista/eos.conf_original.j2
  1. Update Python functions inside ./jinja directory to match the new naming scheme

  2. Pass updated python files as arguments to j2cli

j2 --tests jinja/tests/defined.py --filters jinja/filters/combined.py -f json schemas/arista/eos.conf_original.j2 -

Working with the lab

Build the lab topology using containerlab:

cue lab-up ./...

Destroy the lab

cue lab-down ./...

If running on WSL2, adjust the default iptables rules

docker exec lon-sw-02 ip6tables -P INPUT ACCEPT
docker exec lon-sw-02 ip6tables -P FORWARD ACCEPT
docker exec lon-sw-02 iptables -P FORWARD ACCEPT
docker exec lon-sw-02 iptables -P INPUT ACCEPT

About

github.com/networkop/cue-networking Part II

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published