Add IP Infusion OcNOS device (best-effort) - #3679
Conversation
fe70e7e to
cf13db1
Compare
ipspace
left a comment
There was a problem hiding this comment.
Thanks a million for the PR!
Not sure what timezone you're in, so just a short comment (more later today or tomorrow): we're pretty strict about having one functionality/change per PR, as it makes things easier to track down when you're trying to figure out why something was changed.
Considering that, please submit the validation-using-ansible changes as a separate PR. Doesn't have to be anything more complex than creating a new branch, picking the relevant files from this branch into that one, and submitting that one as a PR.
Thank you, Ivan
ansible validation action|
Thanks Ivan — done. The |
Add IP Infusion OcNOS as a containerlab-provisioned device (a vrnetlab-packaged OcNOS VM; clab provider only) at best-effort support level. Configuration is deployed with the ipinfusion.ocnos Ansible collection over network_cli (driving the interactive cmlsh shell). Supported modules include initial, OSPFv2/OSPFv3, BGP, IS-IS, VRF (including per-VRF IS-IS), VLAN, LAG, first-hop gateway (VRRP), STP, MPLS/LDP, segment routing, VXLAN/EVPN, BFD, DHCP relay/client, and static/policy routing, plus the bgp.session, bgp.policy, ebgp.multihop, ospf.areas, evpn.multihoming and tunnel.gre plugins. Because OcNOS cmlsh has no non-interactive SSH exec, `netlab validate` reads device state through the ansible validation action: the device sets netlab_validate.ansible_module to ipinfusion.ocnos.ocnos_command, and the OcNOS OSPFv2/OSPFv3, BGP and IS-IS validators use the ansible_/valid_ contract to screen-scrape the CLI text. Live-verified against vrnetlab ipinfusion_ocnos 7.0.0-262 with FRR probes: OSPFv2, OSPFv3, BGP and IS-IS DUT-side validation all pass through the ansible action.
- docs/platforms.md: add IP Infusion OcNOS (best-effort) to the device list and to the per-module support tables it passes. - docs/caveats.md: OcNOS platform caveats (commercial image, the cmlsh restricted shell and ansible-action validation, the OSPF commit-notice re-run, loopback naming, and the DHCP-relay and GRE datapath limitations). - docs/install/ocnos.md: installation, container image build, configuration deployment, and the ansible-action validation notes. - docs/release/26.07.md: release-note entries for the OcNOS device and the ansible validation action.
cf13db1 to
d1df080
Compare
There was a problem hiding this comment.
Pull request overview
Adds best-effort support for IP Infusion OcNOS as a Containerlab device, including device definition, Ansible deployment/readiness/collection tasks, a broad set of OcNOS configuration templates, and device-side validation plugins used by the integration validation framework. The PR also updates documentation and adds an OcNOS-specific integration smoke test topology + notes.
Changes:
- Introduces the
ocnosdevice definition and Ansible tasking (deploy, fetch-config, readiness-check) tailored to OcNOS’s restricted CLI behavior. - Adds OcNOS configuration templates across core modules and several extra plugins (OSPF areas, BGP policy/session, EVPN multihoming, GRE, etc.).
- Adds OcNOS validation plugins for OSPF, IS-IS, and BGP, plus platform docs and an integration smoke test.
Reviewed changes
Copilot reviewed 39 out of 39 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/integration/platform/ocnos/README.md | How to run the OcNOS integration smoke test and prerequisites. |
| tests/integration/platform/ocnos/ospf-bgp.yml | Minimal OcNOS OSPFv2 + iBGP smoke topology and rationale notes. |
| netsim/validate/ospf/ocnos.py | OcNOS OSPFv2/OSPFv3 validator (CLI text parsing). |
| netsim/validate/ocnos.py | Top-level OcNOS validation plugin re-exporting per-module validators. |
| netsim/validate/isis/ocnos.py | OcNOS IS-IS validator (CLI text parsing). |
| netsim/validate/bgp/ocnos.py | OcNOS BGP validator (CLI text parsing). |
| netsim/extra/vrrp/version/ocnos.j2 | No-op template to satisfy plugin lookup (VRRP version handled elsewhere). |
| netsim/extra/tunnel/gre/ocnos.j2 | OcNOS GRE tunnel configuration template. |
| netsim/extra/ospf/areas/ocnos.j2 | OcNOS ospf.areas plugin template (stub/NSSA/ranges). |
| netsim/extra/evpn/multihoming/ocnos.j2 | OcNOS EVPN multihoming (ESI-LAG) template. |
| netsim/extra/ebgp/multihop/ocnos.j2 | OcNOS eBGP multihop plugin template. |
| netsim/extra/bgp/session/ocnos.j2 | OcNOS BGP session knobs (auth/timers/GTSM). |
| netsim/extra/bgp/policy/ocnos.j2 | OcNOS BGP neighbor route-map attachment (AF-scoped). |
| netsim/devices/ocnos.yml | New ocnos device definition, feature matrix, clab settings, and group_vars. |
| netsim/ansible/templates/vxlan/ocnos.j2 | OcNOS VXLAN template (incl. EVPN-related prerequisites). |
| netsim/ansible/templates/vrf/ocnos.j2 | OcNOS per-VRF routing protocol configuration (OSPF/IS-IS/BGP). |
| netsim/ansible/templates/vlan/ocnos.j2 | OcNOS VLAN customer-bridge switchport configuration. |
| netsim/ansible/templates/stp/ocnos.j2 | OcNOS STP configuration (bridge priority, edge/disable per-port). |
| netsim/ansible/templates/srv6/ocnos.j2 | OcNOS SRv6 configuration (ISIS-only). |
| netsim/ansible/templates/sr/ocnos.j2 | OcNOS MPLS Segment Routing configuration (ISIS-based). |
| netsim/ansible/templates/routing/ocnos.j2 | OcNOS generic routing policy objects + static routes. |
| netsim/ansible/templates/ripv2/ocnos.j2 | OcNOS RIPv2 configuration template. |
| netsim/ansible/templates/ospf/ocnos.j2 | OcNOS OSPFv2 + OSPFv3 configuration template. |
| netsim/ansible/templates/mpls/ocnos.j2 | OcNOS MPLS/LDP + VPNv4 BGP AF template. |
| netsim/ansible/templates/lag/ocnos.j2 | OcNOS LAG member configuration template. |
| netsim/ansible/templates/isis/ocnos.j2 | OcNOS IS-IS configuration template. |
| netsim/ansible/templates/initial/ocnos.j2 | OcNOS base/initial configuration template (system, VRFs, VLAN DB, interfaces). |
| netsim/ansible/templates/gateway/ocnos.j2 | OcNOS gateway (VRRPv2/v3) configuration template. |
| netsim/ansible/templates/evpn/ocnos.j2 | OcNOS EVPN control-plane template (EVPN-VXLAN / EVPN-MPLS). |
| netsim/ansible/templates/dhcp/ocnos.j2 | OcNOS DHCP relay/client configuration template. |
| netsim/ansible/templates/bgp/ocnos.j2 | OcNOS base BGP configuration template. |
| netsim/ansible/templates/bfd/ocnos.j2 | OcNOS BFD per-interface timers template. |
| netsim/ansible/tasks/readiness-check/ocnos.yml | Device readiness check via OcNOS Ansible command module. |
| netsim/ansible/tasks/fetch-config/ocnos.yml | Config collection via OcNOS facts module. |
| netsim/ansible/tasks/deploy-config/ocnos.yml | Config deployment via OcNOS config module (match: none). |
| docs/release/26.07.md | Release notes entries for OcNOS + validation enhancements. |
| docs/platforms.md | Adds OcNOS to the platform support tables. |
| docs/install/ocnos.md | Installation and usage guide for OcNOS (clab + Ansible collection). |
| docs/caveats.md | Adds OcNOS caveats and known limitations. |
| {% if ospf.af.ipv6 is defined %} | ||
| router ipv6 ospf | ||
| {% if ospf.router_id is defined %} | ||
| router-id {{ ospf.router_id }} | ||
| {% endif %} | ||
| ! | ||
| {% endif %} | ||
| {% if loopback.ospf is defined and loopback.ipv6 is defined and loopback.ipv6 is string %} | ||
| interface {{ loopback.ifname | default('lo') }} | ||
| ipv6 router ospf area {{ loopback.ospf.area }} | ||
| ! | ||
| {% endif %} | ||
| {% for l in netlab_interfaces if l.ospf is defined and l.ipv6 is defined and l.ipv6 is string and l.ifname != loopback.ifname|default('lo') %} | ||
| interface {{ l.ifname }} | ||
| ipv6 router ospf area {{ l.ospf.area }} | ||
| {% if l.ospf.network_type is defined %} | ||
| ipv6 ospf network {{ l.ospf.network_type }} | ||
| {% endif %} | ||
| ! | ||
| {% endfor %} |
| interface {{ loopback.ifname | default('lo') }} | ||
| ip router isis {{ isis.instance | default('1') }} | ||
| {% if loopback.ipv6 is defined and loopback.ipv6 is string %} | ||
| ipv6 router isis {{ isis.instance | default('1') }} | ||
| {% endif %} | ||
| ! | ||
| {% endif %} | ||
| {% for l in netlab_interfaces if l.isis is defined and l.ifname != loopback.ifname|default('lo') %} | ||
| interface {{ l.ifname }} | ||
| ip router isis {{ isis.instance | default('1') }} | ||
| {% if l.ipv6 is defined and l.ipv6 is string %} | ||
| ipv6 router isis {{ isis.instance | default('1') }} | ||
| {% endif %} |
Add IP Infusion OcNOS (best-effort) and a general
ansiblevalidation actionCloses #3676.
This PR contributes two things that stand on their own but ship together because the first needs the second:
ansiblevalidation action fornetlab validate, so a device whose CLI cannot be driven non-interactively can still have its state read and asserted.The
ansiblevalidation actionWhy
netlab validatereads device state either by running ashow/execcommand over the node connection, or from an external source (suzieq). Both assume the platform can return command output to a non-interactive caller. Some network OSes only expose their operational data through a vendor Ansible module — their interactive CLI rejects non-interactive command execution — so neither existing path can reach them, and today such a device cannot be validated at all.The
ansibleaction closes that gap. It is a validation data source, a peer ofnetsim/cli/validate/suzieq.py— not a connection method.netsim/cli/connect.pyis unchanged (byte-identical todev); interactivenetlab connectis untouched. As suggested on #3676, it is implemented as a first-class, reusable action rather than a one-off device plugin, so any platform in the same situation can adopt it.How it works
validateentry:ansible_<test>()function and assert on the result invalid_<test>().netsim/cli/validate/ansible.pyruns the module ad-hoc against the node using the netlab-generated inventory, and returns parsed JSON when the command emits it (... | json), otherwise the raw CLI text instdoutfor a text assertion to match.The action is registered everywhere a validation action is expected — the topology schema (
attributes.yml), the augment/validation checks (augment/validate.py), the test and plugin dispatchers — soansible:is accepted and executed like any built-in action, and documented indocs/topology/validate.md.The IP Infusion OcNOS device
A native containerlab device driven by the
ipinfusion.ocnosAnsible collection. Because OcNOS'scmlshhas no non-interactive exec mode, it uses the newansibleaction for state validation (this is the concrete first consumer described above).Module coverage
Configuration templates are provided across the standard module set:
Module-level exceptions and platform quirks (e.g. OSPF NSSA type-7 ranges, GRE tunnel line-protocol on the 7.0 image, and DHCP relay not yet covered end-to-end on the test host) are recorded in
docs/caveats.mdand the per-module support tables rather than silently claimed.State validation
Validators are provided for the modules whose assertions read state directly off the OcNOS device — OSPFv2, OSPFv3, BGP and IS-IS — following the same
ansible_<test>()/valid_<test>()signatures as the FRR/EOS validators. Other modules are exercised by netlab's standard cross-device checks (reachability and neighbor state verified from the peer nodes in each integration topology), which need no device-specific validator.Verification
Verified on real OcNOS containerlab topologies (
vrnetlab/ipinfusion_ocnos:7.0.0-262), with an FRR node on each side of the device under test. The device-side checks below are the ones that exercise the OcNOS validators through theansibleaction:ansibleaction)The direct
ansible:action (no plugin) was additionally confirmed end-to-end against the device.Both the configuration the templates render and the show commands the validators parse were checked against the vendor's OcNOS-SP 7.0 CLI documentation — command forms, and the output columns the validators key on (
show ip/ipv6 ospf neighbor,show ip bgp summary,show clns neighbors,show ip/ipv6 route).Files
ansiblevalidation action (core, device-agnostic)netsim/cli/validate/ansible.py— new validation source (peer ofsuzieq.py)netsim/cli/validate/tests.py,utils.py,plugin.py— dispatch + action registrationnetsim/augment/validate.py,netsim/defaults/attributes.yml— acceptansible:as a first-class validation actiondocs/topology/validate.md,docs/release/26.07.md— documentationOcNOS device
netsim/devices/ocnos.yml— device settings, feature matrix,netlab_validate.ansible_moduleopt-innetsim/ansible/templates/**/ocnos.j2,netsim/extra/**/ocnos.j2— configuration templatesnetsim/validate/{ospf,bgp,isis}/ocnos.py+netsim/validate/ocnos.py— state validatorsnetsim/ansible/tasks/{deploy-config,fetch-config,readiness-check}/ocnos.yml— device tasksdocs/platforms.md,docs/caveats.md,docs/install/ocnos.md— device documentationtests/integration/platform/ocnos/— integration topology and notesSupport level
OcNOS is contributed at best-effort support. I don't expect it to be part of the regular upstream integration runs; the supported-module matrix and its documented exceptions live in
docs/platforms.mdanddocs/caveats.md, and I'm happy to maintain the device and address issues against it.