nd_maintenance_mode#284
Open
allenrobel wants to merge 2 commits into
Open
Conversation
bff5d88 to
921294d
Compare
277a298 to
fb922d2
Compare
Wraps POST /api/v1/manage/fabrics/{fabric_name}/switchActions/changeSystemMode
to set switches in a fabric to `normal` or `maintenance` mode. The endpoint is
action-shaped (one POST mutates a batch of switches with a single mode), and
the module adapts it to NDStateMachine's CRUD-shaped driver via an
identifier_strategy="singleton" model and a config-dict-to-list wrap in main().
Idempotency reads `additionalData.intendedSystemMode` per switch and only POSTs
switches whose intent differs from the request. Any switch currently in
`migration` mode triggers a hard-fail with the remediation instruction to run
'Recalculate and Deploy' in the ND UI before retrying. The 207 response body is
inspected per-item; any failed entry surfaces as a RuntimeError naming the
offending switches by IP.
State support: `merged` only. `gathered` will be added when the underlying
NDStateMachine/NDOutput support lands; query_all already produces the per-switch
snapshot it will need.
TODO(4.2.1) markers flag two ND wire/schema divergences observed on ND 4.2.1.10:
the GET switch response nests systemMode under `additionalData` rather than at
the top level the OpenAPI schema documents, and the aggregator
`additionalData.systemMode` returns "inconsistent" (a value not in the OpenAPI
enum) between an intent change and a deploy.
- New endpoint module manage_fabrics_switch_actions.py with
ChangeSystemModeEndpointParams and EpManageFabricsSwitchActionsChangeSystemModePost
- EpManageSwitchesGet added to manage_switches.py for the per-switch GET
used by the query_all fan-out
- Pydantic feature model MaintenanceModeModel + MaintenanceModeSwitchModel
with custom per-switch get_diff
- MaintenanceModeOrchestrator inheriting NDBaseInterfaceOrchestrator for
FabricContext plumbing and switch IP resolution
- 43 unit tests with 93-97% coverage on the new modules
- Integration target with YAML-anchored single-switch, multi-switch,
partial-mismatch, negative, and check_mode scenarios; verified live on
ND 4.2.1.10 / SITE1
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verified against the live ND OpenAPI spec at /api/v1/manage/openAPISpec (Nexus Dashboard Manage v1 1.1.411): the wire shape we read in `_fetch_switch_modes` matches the spec exactly. The `switchData` schema declares `additionalData` as a $ref to `additionalType` (a `oneOf` discriminated by `usage`), and the non-ACI variant `additionalSwitchData` documents `systemMode`, `intendedSystemMode`, and `discoveredSystemMode` with enums that include "inconsistent", "waiting", and "notApplicable". The earlier TODO marker was based on a stale snapshot of the spec served by the local OpenAPI MCP server (1.1.209). There is no workaround here — we are reading the fields exactly as documented. Replaced the marker with a plain comment explaining the design choice (compare against `intendedSystemMode`, not the `systemMode` aggregator) so future maintainers understand the idempotency rationale without thinking we owe a removal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fb922d2 to
0bb6a39
Compare
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)
Proposed Changes
Add
cisco.nd.nd_maintenance_mode, a new Ansible module that sets the system mode (normalormaintenance) of switches in a fabric viaPOST /api/v1/manage/fabrics/{fabric_name}/switchActions/changeSystemMode.The endpoint is action-shaped — one POST mutates a batch of switches with a single mode. The module adapts that to
NDStateMachine's CRUD-shaped driver via anidentifier_strategy="singleton"model and aconfig-dict-to-list wrap inmain(). Idempotency readsadditionalData.intendedSystemModeper switch and only POSTs switches whose intent differs from the request. Any switch currently inmigrationmode triggers a hard-fail with a remediation message asking the operator to run 'Recalculate and Deploy' in the ND UI before retrying. The 207 response body is inspected per-item; any failed entry surfaces as aRuntimeErrornaming the offending switches by IP.State support is
mergedonly for now. The collection-widequerystate is retired;gatheredwill be added once the underlyingNDStateMachine/NDOutputframework support lands (the orchestrator'squery_allalready produces the per-switch snapshot it will need).Two
TODO(4.2.1)workaround markers flag observed ND wire/schema divergences:GET /fabrics/{f}/switches/{sid}nestssystemModeunderadditionalData, not at the top level the OpenAPI schema documents.additionalData.systemModereturns"inconsistent"(a value not in the OpenAPI enum) between an intent change and a deploy, so idempotency must compare againstintendedSystemMode, notsystemMode.New / modified files:
plugins/modules/nd_maintenance_mode.py— module entry point (DOCUMENTATION / EXAMPLES / argspec /main()).plugins/module_utils/orchestrators/maintenance_mode.py—MaintenanceModeOrchestratorinheritingNDBaseInterfaceOrchestratorforFabricContextplumbing.plugins/module_utils/models/maintenance_mode/{__init__.py, maintenance_mode.py}— singleton model + per-switchget_diff.plugins/module_utils/endpoints/v1/manage/manage_fabrics_switch_actions.py— new endpoint module forchangeSystemMode.plugins/module_utils/endpoints/v1/manage/manage_switches.py— addedEpManageSwitchesGetfor the per-switch GET used by thequery_allfan-out.nd_maintenance_modewith YAML-anchored single-switch, multi-switch, partial-mismatch, negative, andcheck_modescenarios.Test Notes
source env && python -m pytest tests/unit/module_utils/— 485/485 pass (442 prior + 43 new, zero regressions). Coverage: orchestrator 93%, model 97%, endpoint 97%.black,isort,pylint,mypyall clean againstpyproject.toml.pylint9.97/10 on tests, 9.75/10 on production.yamllintclean on integration target.ok=40 changed=13 failed=0 ignored=2, where the twoignoredare the expected-failure negative tests). Lab state verified back tointendedSystemMode=normalfor all test switches after the run.switch_ip, negative fabric, check_mode) all green prior to writing the integration target.radiusauth domain on this lab is effectively read-only on SITE1/SITE2; live tests use-e ansible_httpapi_login_domain=local. Documented in the integration target'smain.yaml.Cisco Nexus Dashboard Version
4.2.1
Related ND API Resource Category
Checklist
Note: stacked PR — base is
nd_interface_loopback(per.stack.maintenance_mode.json:develop -> nd_interface_loopback -> nd_maintenance_mode).🤖 Generated with Claude Code