-
Notifications
You must be signed in to change notification settings - Fork 3
netlab
Pre-Alpha. This page describes behavior that may change.
netlab builds a lab from a short YAML topology and starts each node under containerlab. Ze runs as one of those nodes. You write the topology, netlab renders a configuration for every node and starts the containers, and netlab validate reads each node back through its CLI. The ze side of the integration lives in contrib/netlab/ in the main repository.
netlab integrates a network operating system at one of two tiers. Ze uses the second one.
| Tier | What it needs | Runs under |
|---|---|---|
| Device | Ansible task lists, one per module, and a Vagrant box | containerlab or Vagrant |
| Daemon | One YAML file (netsim/daemons/<name>.yml) and one directory of Jinja2 templates |
containerlab only |
BIRD, dnsmasq, VPP, and netscaler are daemons. Ze is a daemon too. The tier costs less to write and to keep current, and it removes the Vagrant box from the list of artifacts to publish.
| Component | Why |
|---|---|
| netlab 26.08 | Renders the topology and calls containerlab |
| containerlab and Docker | Start the nodes |
netlab/ze:latest |
The lab image, built from the ze tree |
netlab daemons usually build their own image. Ze does not: contrib/netlab/ze.yml sets clab.build: False and image: netlab/ze:latest, so netlab starts an image you build first.
make ze-docker-lab-buildThis is a second image, not a replacement for the deployment image. docker/Dockerfile stays a static binary on a scratch base. The lab image adds a shell and iproute2, because containerlab and netlab drive a node from the outside: they run sh and ip inside the container to assign the addresses the topology declares. Both images derive their feature tags from feature-gates.txt, so a defect cannot reproduce in a lab and disappear in production. See Docker for the two images.
ZE_LAB_IMAGE and ZE_LAB_TAG change the name and the tag. Change them and change image: in ze.yml to match. No image is published, so there is nothing to pull.
There are two routes. Copy the daemon definition and the templates into the netlab package:
cp contrib/netlab/ze.yml <netlab>/netsim/daemons/ze.yml
cp -R contrib/netlab/ze <netlab>/netsim/daemons/zeOr leave the netlab install alone and let a topology carry them. netlab reads a topology-defaults.yml beside the topology, with the contents of ze.yml under a daemons: ze: key, and a templates/ze/ directory beside it. This second route is what make ze-netlab-render-check uses.
netlab up -t contrib/netlab/topology.ymlcontrib/netlab/topology.yml has three ze nodes:
r1 ---- internal ---- r2 AS 65001, iBGP + OSPF + IS-IS + BFD
\
---- external ---- r3 AS 65002, eBGP only
netlab runs an IGP on internal links only, so the eBGP peer sits on its own link. r1 carries two static routes, one with a next hop and one discard. r3 covers what the template renders for a node whose modules are a subset of the declared set.
netlab decides which templates a node needs from the daemon_config map in ze.yml, one entry per module. A module a node uses with no entry fails netlab create with Cannot find <module> configuration template.
Ze has no include directive, so it cannot read one file per module. ze/ze.j2 renders the whole running configuration into /etc/ze/ze.conf, and every other key points at an .ignore file that nothing reads. This is the dnsmasq pattern, and it is required, not stylistic.
| Key | File | Read by ze |
|---|---|---|
ze |
/etc/ze/ze.conf |
Yes, the whole configuration |
bgp |
/etc/ze/bgp.ignore |
No |
ospf |
/etc/ze/ospf.ignore |
No |
isis |
/etc/ze/isis.ignore |
No |
bfd |
/etc/ze/bfd.ignore |
No |
routing |
/etc/ze/routing.ignore |
No |
containerlab bind-mounts the rendered file into the node, and the node starts with ze start /etc/ze/ze.conf. netlab assigns the interface addresses with ip inside the container, so the rendered configuration carries no interface block.
Ze re-reads its configuration on SIGHUP only. netlab sends no SIGHUP, and ze.yml says so with features.initial.reload: false. A configuration change in a running lab needs kill -HUP on the ze process inside the node, or a node restart.
netlab validate reads the daemon through the CLI. ze.yml declares the show command as ze cli -c "show $@ | json compact" and netlab runs it with docker exec, so the output is JSON that netlab parses.
The rendered configuration declares one user, netlab, with the password netlab, and ze.yml puts the same pair in the container environment. This is a well-known credential in a throwaway container. Nothing in ze defaults to it and no image carries it. Override both with netlab_lab_user and netlab_lab_password in the topology, and change clab.node.env in ze.yml to match.
The template writes the password as plaintext-password. Ze hashes that leaf when it loads the file, so the running tree holds a bcrypt hash. The daemon warns once, naming the file, because the file still holds the secret.
ze.yml declares five modules plus the initial block: bgp, ospf, isis, bfd, and routing (static routes). netlab tests whatever a daemon declares, so the file declares only what the template emits.
| Daemon or device | Feature keys |
|---|---|
| Ze | 6 |
| BIRD | 10 |
| FRR | 18 |
| Arista EOS | 19 |
Counts measured against netlab 26.08. Ze declares isis and BIRD does not. FRR declares twelve keys ze does not: evpn, gateway, lag, mpls, ripv2, sr, srv6, stp, tunnel, vlan, vrf, and vxlan.
The lab has never been started. The machine that wrote this integration has no containerlab, so netlab up and netlab validate were not run. Only BGP has evidence past "renders and parses": a functional test starts a daemon from the BGP-only render, logs in, and reads the peer list back as JSON. It establishes no session, and OSPF, IS-IS, BFD, and static routes need interfaces an unprivileged test host does not have.
| Statement | Evidence |
|---|---|
| netlab accepts the daemon definition and finds a template for each module |
netlab create exits 0 on the reference topology |
| The render is valid ze configuration |
ze config validate exits 0 on each file under contrib/netlab/golden/
|
| A daemon runs one of those renders and answers the show command with JSON | test/plugin/netlab-lab-profile.ci |
Routes reach the FIB of a running lab, and a ping validation passes |
Not run |
| Each declared module passes netlab's integration test for it | Not run |
Ze sends and receives no LLDP frame, so a netlab validation that reads an LLDP table cannot pass. containerlab needs no LLDP, because its links are veths the topology names.
make ze-netlab-render-checkIt renders the templates with a real netlab, compares the result against contrib/netlab/golden/, and runs ze config validate on each golden file. A missing netlab is an error, never a skip. ARGS=--update rewrites the golden files, and you review the diff.
test/plugin/netlab-lab-profile.ci is the other half and needs no netlab. It starts a daemon from a golden file, logs in as the user the render declared, and parses the output of the show command netlab runs. The render check proves the templates emit what ze accepts. The functional test proves ze runs what they emitted.
- In-tree netlab guide for the full reference.
- contrib/netlab/README.md, the source of truth for the artifacts.
- Docker for the two container images.
- Testing for the test targets.
Adapted from main/docs/guide/netlab.md.
Unreviewed draft. This wiki was authored in bulk and has not been reviewed. File corrections on the issue tracker.
- Overview
- YANG Model
- Editor Workflow
- Archive and Rollback
- System
- Interfaces
- VRRP
- BFD
- FIB
- OSPF
- IS-IS
- MPLS / LDP / RSVP-TE
- RSVP-TE
- SRv6
- Static Routes
- Policy Routing
- Firewall
- Traffic Control
- Class of Service
- L2TP/PPP
- PPPoE
- VPP Data Plane
- RPKI
- IPsec VPN
- TACACS+ AAA
- RADIUS AAA
- AS112 DNS
- DNS
- Authorization
- Fleet
- BGP
- Starting and Stopping
- Show Commands
- Monitoring
- Flow Export
- DDoS Mitigation
- Anomaly Detection
- Health Checks
- Audit Trail
- Production Diagnostics
- Logging
- Operational Reports
- Healthcheck
- Self-Update
- Zero-Touch Provisioning
- MRT Analysis
- Upgrade and Restart
- Storage
- Policy
- Core
- Resilience
- Validation
- Capabilities
- Address Families
- Protocol
- Subsystems
- Infrastructure
- Route Server at an IXP
- Transit Edge with RPKI
- Public Looking Glass
- ExaBGP Migration Walkthrough
- FlowSpec Injection
- Chaos-Tested Peering
- AS Path Topology