Skip to content

Ansible ND 4.X | WIP | ND Manage Switches Module + Pydantic Models + Smart Endpoints#198

Open
AKDRG wants to merge 5 commits intoCiscoDevNet:nd42_integrationfrom
AKDRG:switch_int_pr
Open

Ansible ND 4.X | WIP | ND Manage Switches Module + Pydantic Models + Smart Endpoints#198
AKDRG wants to merge 5 commits intoCiscoDevNet:nd42_integrationfrom
AKDRG:switch_int_pr

Conversation

@AKDRG
Copy link

@AKDRG AKDRG commented Mar 11, 2026

This PR introduces the initial implementation of ND Manage switch lifecycle support in the cisco.nd collection.
It adds a new switch management resource layer, endpoint wrappers, Pydantic model hierarchy, utility helpers.

What’s Included

  1. New switch lifecycle resource implementation

Added a full resource engine in plugins/module_utils/nd_switch_resources.py
Implements state handling for:

  • query
  • merged
  • overridden
  • deleted
  • POAP flows (bootstrap, pre-provision, serial swap)
  • RMA flow

Adds structured operation sequencing:

  • discovery
  • add/remove
  • role updates
  • credentials save
  • wait-for-manageability
  • save/deploy finalize
  1. ND Manage endpoint layer

Added endpoint models under plugins/module_utils/endpoints/v1/nd_manage_switches:

  • manage_credentials.py
  • manage_fabric_bootstrap.py
  • manage_fabric_config.py
  • manage_fabric_discovery.py
  • manage_fabric_switch_actions.py
  • manage_fabric_switches.py
  1. Pydantic model framework and nd_manage_switches models

Added shared model base and nested infrastructure:

  • plugins/module_utils/models/base.py
  • plugins/module_utils/models/nested.py
  • Added nd_manage_switches model package and exports:
  • bootstrap, config, discovery, preprovision, rma, switch_actions, switch_data, enums, validators
  • package-level init re-exports for consistent imports

Added model consolidation in:
plugins/module_utils/models/nd_manage_switches/summary_models.py

  1. Utilities for lifecycle orchestration
    Added helpers in plugins/module_utils/utils/nd_manage_switches:
  • bootstrap_utils.py
  • fabric_utils.py
  • payload_utils.py
  • switch_helpers.py
  • switch_wait_utils.py
  • exceptions.py

These utilities centralize grouping, payload shaping, wait/retry logic, and fabric operations.

ticket_id: Optional[str] = Field(default=None, min_length=1, description="Change control ticket ID")


class _V1ManageCredentialsSwitchesBase(BaseModel):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see V1 prepended to the class name, where in Gaspard PR and the clusterhealth classes this is not the case should those be removed?

Suggested change
class _V1ManageCredentialsSwitchesBase(BaseModel):
class _ManageCredentialsSwitchesBase(BaseModel):

This is a generic comment that would apply to all the classes you have defined.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment applies to other endpoints

ticket_id: Optional[str] = Field(default=None, min_length=1, description="Change control ticket ID")


class _V1ManageCredentialsSwitchesBase(BaseModel):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be NDEndpointBaseModel?

Suggested change
class _V1ManageCredentialsSwitchesBase(BaseModel):
class _V1ManageCredentialsSwitchesBase(NDEndpointBaseModel):

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment applies to other endpoints

```
"""

ticket_id: Optional[str] = Field(default=None, min_length=1, description="Change control ticket ID")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to not have a Mixin class for ticket_id?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment applies to other endpoints

Comment on lines +124 to +125
api_version: Literal["v1"] = Field(default="v1", description="ND API version for this endpoint")
min_controller_version: str = Field(default="3.0.0", description="Minimum ND version supporting this endpoint")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined in NDEndpointBaseModel, so I think it could be removed when NDEndpointBaseModel is used.

Comment on lines +127 to +129
class_name: Literal["V1ManageCredentialsSwitchesPost"] = Field(
default="V1ManageCredentialsSwitchesPost", description="Class name for backward compatibility"
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be frozen=true?

Suggested change
class_name: Literal["V1ManageCredentialsSwitchesPost"] = Field(
default="V1ManageCredentialsSwitchesPost", description="Class name for backward compatibility"
)
class_name: Literal["V1ManageCredentialsSwitchesPost"] = Field(
default="V1ManageCredentialsSwitchesPost", frozen=True, description="Class name for backward compatibility"
)

)

# Common config for basic validation
COMMON_CONFIG = ConfigDict(validate_assignment=True)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this constant defined here and only used one time in _V1ManageFabricBootstrapBase?


- max: Maximum number of results to return (optional)
- offset: Pagination offset (optional)
- filter: Lucene filter expression (optional)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do some of the endpoint params include filter? What is this used for?

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.

2 participants