nd_interface_svi#268
Open
allenrobel wants to merge 14 commits into
Open
Conversation
63772b4 to
4ef3a29
Compare
fbf7e94 to
891a211
Compare
4ef3a29 to
c053c9d
Compare
f8b2223 to
9c7b61e
Compare
c053c9d to
bba7fdc
Compare
9c7b61e to
28978eb
Compare
bba7fdc to
a92738c
Compare
35265ae to
bc7600c
Compare
e1fd3d9 to
8c985eb
Compare
a9bf5c3 to
a16b20c
Compare
51c80e3 to
a4883ab
Compare
a16b20c to
d8d3870
Compare
a4883ab to
00a6c91
Compare
d8d3870 to
56fa96c
Compare
00a6c91 to
260d942
Compare
56fa96c to
ac41b4b
Compare
260d942 to
bb9848e
Compare
ac41b4b to
e80a7f8
Compare
bb9848e to
58456b0
Compare
724ba60 to
567f385
Compare
9b24cd6 to
8ec3ef3
Compare
567f385 to
61e8706
Compare
8ec3ef3 to
e6949f0
Compare
61e8706 to
b115f74
Compare
e6949f0 to
95f4db2
Compare
b115f74 to
3961059
Compare
95f4db2 to
27e39ba
Compare
3961059 to
915bdc3
Compare
27e39ba to
6e3e071
Compare
915bdc3 to
5539d87
Compare
6e3e071 to
345742c
Compare
5539d87 to
2e6c252
Compare
345742c to
c7c4320
Compare
2e6c252 to
c8a68ac
Compare
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
Demonstrates the alternative to the structured hsrp_* fields: a raw NX-OS hierarchical config block (preempt, priority, authentication, track) applied through the extra_config literal-block scalar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each SVI is L3 with its own IP/VRF/HSRP identity, so the previous ethernet-style fan-out (vlan_ids: [333, 334, 335] sharing one config_data block) silently produced duplicate-IP-in-same-VRF configurations. Replace with one config item per interface_name, matching the wire payload. - Remove expand_config() from the module entry point; argument spec now requires interface_name (str) directly. - Update DOCUMENTATION, EXAMPLES, and unit-test argspec assertion. - Split test vars (svi_334_335, svi_337_338) into per-VLAN entries with unique IPs; replace cleanup_vlan_ids list-of-int with cleanup_config list-of-dict. - Update merged/replaced/overridden/deleted/hsrp_dhcp/setup integration tasks to use interface_name; rename "fan-out" tests to "multi-SVI". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
validate_for_mutation reads freeze status from cached fabric_summary (see fabric_context.py:166), so query_all no longer issues a separate GET to /deploymentFreeze. The extra _freeze response was being consumed by the switches request, returning a payload without the "switches" key, so switch_map ended up empty and query_all returned []. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
interface_type, mode, and network_os_type were exposed as user options but had no real choice for this module - they are fixed by scope (svi / managed / nx-os) and only served to mirror the ND payload shape. Removing them from get_argument_spec() collapses the user-visible config to switch_ip + interface_name + the policy fields, with no documentation burden or invalid-value footguns. The fields stay in the Pydantic model with hardcoded defaults so to_payload() / from_response() keep working; their types are narrowed to Literal["svi"] / Literal["managed"] / Literal["nx-os"] so a stray API value would surface as a validation error instead of silently round- tripping. policy_type was already locked to SviPolicyTypeEnum.SVI. Mirrors the loopback treatment in 56a45a8. Also fixes a pre-existing YAML-parse bug in the existing notes block: "C(policyType: vpcBackupSvi)" had a colon inside the C() macro that broke yaml.safe_load on the DOCUMENTATION string. Reformatted to put the field name outside C() and only the value inside, matching the loopback note style. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
interface_type, mode, network_os_type, and policy_type are scope-fixed
for this module ("svi"/"managed"/"nx-os"/SviPolicyTypeEnum.SVI). The
Literal annotations plus NDBaseModel's validate_assignment=True already
block reassignment to a wrong value, but frozen=True also blocks
no-op reassignment to the same value, which more accurately expresses
the "hardcoded scaffolding" intent and protects against accidental
mutations that happen to round-trip the current value.
Pydantic uses construction (not assignment) for model_validate,
from_response, and model_copy(update=...), so frozen=True does not
interfere with the API round-trip or the merge/replaced/overridden
state-machine flows.
Reviewer-recommended pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue(s)
N/A — new interface module in the interface module roadmap series.
Proposed Changes
Adds
nd_interface_svito manage SVI (switched virtual interface) configurations on Cisco Nexus Dashboard via the Manage Interfaces API.plugins/module_utils/models/interfaces/svi_interface.py—SviInterfaceModelplus nestedSviPolicyModel,SviNetworkOSModel,SviConfigDataModel,SviOperDataModel. Composite identifier(switch_ip, interface_name)whereinterface_nameis normalized to lowercasevlan<id>.plugins/module_utils/orchestrators/svi_interface.py—SviInterfaceOrchestratorinheriting fromNDBaseInterfaceOrchestrator(not the ethernet base; SVIs have no port-channel concerns and support real DELETE viainterfaceActions/remove+interfaceActions/deploy).plugins/modules/nd_interface_svi.py— module entry point withvlan_ids: [333, 334]expansion to per-VLAN config items.plugins/module_utils/models/interfaces/enums.py— addsSviPolicyTypeEnum.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:
from_response()stripshsrpVersion. ND's GET returnshsrpVersion: 1(integer) as a server-side default even when HSRP is unconfigured; re-emitting that on PUT — as either int1or string"1"— triggers a generic 500 ("unexpected error during policy execution").hsrpGroup: 1round-trips fine, so onlyhsrpVersionis 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, switchLE1at192.168.12.151, VLANs 333/334/335).tests/unit/.../test_svi_interface*.py(commit434b221).tests/integration/targets/nd_interface_svi/(commitf8b2223).description+policyType) — server merges.oper_datapopulated.changed: falsewith empty diff.interfaceActions/remove(204) followed byinterfaceActions/deployconfirmed via post-delete check_mode query (before: []).Cisco Nexus Dashboard Version
4.2
Related ND API Resource Category
Checklist
nd_interface_ethernet_trunk_host; rebase will follow that branch's merge to develop)