Skip to content

nd_interface_svi module#268

Open
allenrobel wants to merge 9 commits intond_interface_ethernet_trunk_hostfrom
nd_interface_svi
Open

nd_interface_svi module#268
allenrobel wants to merge 9 commits intond_interface_ethernet_trunk_hostfrom
nd_interface_svi

Conversation

@allenrobel
Copy link
Copy Markdown
Collaborator

@allenrobel allenrobel commented Apr 27, 2026

Related Issue(s)

N/A — new interface module in the interface module roadmap series.

Proposed Changes

Adds nd_interface_svi to manage SVI (switched virtual interface) configurations on Cisco Nexus Dashboard via the Manage Interfaces API.

  • plugins/module_utils/models/interfaces/svi_interface.pySviInterfaceModel plus nested SviPolicyModel, SviNetworkOSModel, SviConfigDataModel, SviOperDataModel. Composite identifier (switch_ip, interface_name) where interface_name is normalized to lowercase vlan<id>.
  • plugins/module_utils/orchestrators/svi_interface.pySviInterfaceOrchestrator inheriting from NDBaseInterfaceOrchestrator (not the ethernet base; SVIs have no port-channel concerns and support real DELETE via interfaceActions/remove + interfaceActions/deploy).
  • plugins/modules/nd_interface_svi.py — module entry point with vlan_ids: [333, 334] expansion to per-VLAN config items.
  • plugins/module_utils/models/interfaces/enums.py — adds SviPolicyTypeEnum.SVI = "svi".

Phase 1 exposes the policy fields the ND GUI sends on create: admin_state, description, ip/prefix, ipv6/v6prefix, ip_redirects, pim_sparse, pim_dr_priority, hsrp_group, hsrp_version, preempt, advertise_subnet_in_underlay, mtu, extra_config, netflow. OSPF / ISIS / BFD / proper HSRP sub-block modeling deferred to a follow-up release.

One SVI-specific deviation from the loopback / ethernet-access pattern, validated by Bruno testing against a live testbed:

  1. from_response() strips hsrpVersion. ND's GET returns hsrpVersion: 1 (integer) as a server-side default even when HSRP is unconfigured; re-emitting that on PUT — as either int 1 or string "1" — triggers a generic 500 ("unexpected error during policy execution"). hsrpGroup: 1 round-trips fine, so only hsrpVersion is poisoned. Proper HSRP sub-block modeling is deferred to phase 2.

Test Notes

Full create / update / query / idempotency / delete lifecycle verified against an ND 4.2 testbed (fabric_1, switch LE1 at 192.168.12.151, VLANs 333/334/335).

  • Unit tests: tests/unit/.../test_svi_interface*.py (commit 434b221).
  • Integration tests: tests/integration/targets/nd_interface_svi/ (commit f8b2223).
  • POST: 201 with single and multi-VLAN config items.
  • PUT: 200 on partial body (only description + policyType) — server merges.
  • GET: round-trips through model with oper_data populated.
  • Idempotency: second-run reports changed: false with empty diff.
  • DELETE: interfaceActions/remove (204) followed by interfaceActions/deploy confirmed via post-delete check_mode query (before: []).

Cisco Nexus Dashboard Version

4.2

Related ND API Resource Category

  • analyze
  • infra
  • manage
  • onemanage
  • other

Checklist

  • Latest commit is rebased from develop with merge conflicts resolved (this branch is stacked on nd_interface_ethernet_trunk_host; rebase will follow that branch's merge to develop)
  • New or updates to documentation has been made accordingly (module DOCUMENTATION + EXAMPLES populated)
  • Assigned the proper reviewers

@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from 63772b4 to 4ef3a29 Compare April 28, 2026 01:43
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from 4ef3a29 to c053c9d Compare April 28, 2026 20:25
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from c053c9d to bba7fdc Compare April 28, 2026 20:36
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from bba7fdc to a92738c Compare April 29, 2026 18:47
@allenrobel allenrobel force-pushed the nd_interface_svi branch 2 times, most recently from 35265ae to bc7600c Compare April 30, 2026 23:20
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from e1fd3d9 to 8c985eb Compare April 30, 2026 23:20
@allenrobel allenrobel marked this pull request as ready for review May 1, 2026 00:21
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from a9bf5c3 to a16b20c Compare May 4, 2026 03:44
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from a16b20c to d8d3870 Compare May 4, 2026 05:02
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from d8d3870 to 56fa96c Compare May 4, 2026 19:34
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from 56fa96c to ac41b4b Compare May 5, 2026 19:44
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from ac41b4b to e80a7f8 Compare May 5, 2026 20:23
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from e80a7f8 to c48e3fa Compare May 5, 2026 20:37
@allenrobel allenrobel force-pushed the nd_interface_svi branch 3 times, most recently from 28b4f1b to 98f8655 Compare May 5, 2026 22:00
allenrobel and others added 9 commits May 5, 2026 15:41
Manages SVI interfaces (interfaceType: svi, policyType: svi) on Cisco
Nexus Dashboard via the Manage Interfaces API. Mirrors the loopback /
ethernet-access patterns: composite identifier (switch_ip, vlan_ids
expanded to vlan<id>), bulk POST per switch, partial PUT, real DELETE
followed by interfaceActions/deploy.

Phase 1 covers the policy fields the ND GUI sends on create:
admin_state, description, ip/prefix, ipv6/v6prefix, ip_redirects,
pim_sparse, pim_dr_priority, hsrp_group, hsrp_version, preempt,
advertise_subnet_in_underlay, mtu, extra_config, netflow.

Two SVI-specific deviations from the ethernet/loopback pattern:
- description rejects non-ASCII (Cisco backend 500s on UTF-8; bug filed)
- from_response strips hsrpVersion (GET-side server default of int 1
  poisons round-trip on PUT)

OSPF / ISIS / BFD / proper HSRP modeling deferred to phase 2.

Test notes: full create/update/query/idempotency/delete lifecycle
verified manually against ND 4.2 testbed (vlan333/334/335 on LE1 in
fabric_1). Unit tests and integration test target to follow.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Model tests (57): defaults, field aliases, ASCII description validator
(8 parametrized cases), policy_type normalize/serialize, numeric range
validation (16 parametrized cases), description max_length, payload
camelCase serialization, NetworkOS / ConfigData / OperData containers,
interface_name normalization (7 parametrized cases for case + bare-int),
composite identifier, payload exclusion of switch_ip / oper_data,
from_response strip of hsrpVersion (and that hsrpGroup round-trips),
from_response idempotency on caller dict, robustness to missing nested
keys, full from_response/to_payload round trip, from_config equivalence,
argument_spec shape, interface_type default.

Orchestrator tests (12): model_class, bulk-support flags, query_all
filtering by interfaceType=svi AND policyType=svi (rejects ethernet and
underlaySvi), query_all fabric-not-found, query_one, create + deploy
queue, update + deploy queue, delete queues remove + deploy without
immediate API call, remove_pending and deploy_pending issuing the
respective interfaceActions endpoints, create_bulk grouping per switch,
canonical PUT payload shape (policyType discriminator, no switchId /
switchIp / operData / hsrpVersion).

Fixture file follows the existing pattern under fixtures/fixture_data/.
Full unit suite remains green: 567 passed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the inline `description_must_be_ascii` field validator with
the shared `AsciiDescription` Annotated type introduced in
nd_interface_loopback. Behavior identical (same error message, same
rejected character set); test docstring updated to reference the
shared validator path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the trunk_host integration target structure with SVI-specific
adjustments:
- Uses vlan_ids: [333..338] instead of interface_names
- Reserves VLANs 333-338 for the test run; cleanup runs first
- Verifies the client-side ASCII validator rejects non-ASCII before any
  API call (em-dash test)
- DELETE assertions check that the SVI disappears from `after` (true
  delete via interfaceActions/remove + deploy), not "reset to defaults"
  like physical ethernet
- overridden assertions verify removed SVIs are gone (not at defaults)

Files:
- tasks/main.yaml — orchestration with optional logging env
- vars/main.yaml — base + updated SVI configs, cleanup helper
- tasks/merged.yaml — single create, fan-out, multi-config-group,
  idempotency, update + idempotency, fan-out update, ASCII validation,
  deploy: false, large fan-out + idempotency
- tasks/replaced.yaml — single replace + idempotency, fan-out replace
- tasks/overridden.yaml — reduce-set + idempotency, grow-set verifying
  removed SVIs disappear from after
- tasks/deleted.yaml — single delete + idempotency, fan-out delete,
  bulk teardown

Run with:
  ansible-test integration nd_interface_svi

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`FabricContext.validate_for_mutation` now also fetches
`/deploymentFreeze` after the fabric summary, so the orchestrator's
`query_all` consumes one extra response from the queue. Insert a
`deploymentFreeze: false` fixture between the summary and switch list
yields to keep the response generator aligned.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Expand SviPolicyModel to cover the full policyType:svi schema in the ND
Manage API: HSRP block (hsrp/hsrp_vip/hsrp_vipv6/hsrp_group/hsrp_groupv6/
hsrp_version/hsrp_priority/preempt/mac), DHCP relay (3 servers + per-server
VRFs), vrf_interface, routing_tag, netflow_monitor, and netflow_sampler.

Lab-verified the original phase-1 hsrpVersion 500 is fixed in current ND
builds, so SviInterfaceModel.from_response stripping is removed.
hsrp_version is now Literal[1, 2] per the OpenAPI schema (was wrongly typed
str). Fix prefixv6 alias (API rejects v6prefix with 400) and relax mtu
constraint to 68-9216 to match the int_vlan template.

Add a coerce-int-to-string validator for routing_tag to handle ND 4.2's
GET-side type drift (returns int despite OpenAPI declaring string); marked
TODO(ND 4.3) for removal once 4.2 is deprecated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per-policy interface modules (one module = one policyType) must not
expose policy_type as a user-facing argspec option. The
nd_interface_svi module targets the svi policy only, so policy_type
was dead surface area.

The model field already had a hardcoded default
(SviPolicyTypeEnum.SVI); the work here is to remove the user-facing
exposure (argspec entry, DOCUMENTATION block) and the no-op
normalize/serialize helpers that were kept "for symmetry" with
ethernet models.

- Remove policy_type from argspec and DOCUMENTATION
- Drop normalize_policy_type validator and serialize_policy_type
  field serializer (both were already no-ops since the API and
  Ansible names are both "svi")
- Strip policy_type from integration test inputs
- Update unit tests (72/72 pass)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace verbatim-repeated module argument blocks (check / normal / idempotent
runs of the same call) with YAML anchors. Removes a class of typo where one
of the duplicated blocks could drift from its siblings. Applied across all
five SVI task files (merged, replaced, overridden, deleted, hsrp_dhcp).

Anchors are defined at first use within each section to keep them local to
the reader.
Move the top-of-file SETUP block from merged.yaml into a dedicated
tasks/setup.yaml and call it from main.yaml before the state-test blocks.
Includes the post-cleanup DEBUG task alongside the cleanup since both are
file-level observability rather than test-specific.

Intra-test setup that's coupled to specific tests stays inline:
- vlan337 cleanup after the no-deploy test in merged.yaml
- The bulk-cleanup teardown at the bottom of deleted.yaml
- hsrp_dhcp.yaml's local SETUP and TEARDOWN — both are tightly coupled to
  the HSRP/DHCP-relay tests that file owns
@allenrobel allenrobel force-pushed the nd_interface_ethernet_trunk_host branch from 873cd22 to 2d17a39 Compare May 6, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant