Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4b23dc6
Rename/Removal of obsolete files
sivakasi-cisco Mar 11, 2026
2009104
Aligning with ND Orchestrator style layering
sivakasi-cisco Mar 11, 2026
0463c9c
Integration tests related changes
sivakasi-cisco Mar 11, 2026
d2221bd
Intermediate changes
sivakasi-cisco Mar 12, 2026
fd65180
Integ test fixes
sivakasi-cisco Mar 12, 2026
b884924
Aligning with the latest modularisation
sivakasi-cisco Mar 13, 2026
096b570
Integ test fixes
sivakasi-cisco Mar 13, 2026
4acfe7d
Interim changes
sivakasi-cisco Mar 13, 2026
5d5d600
Fragmenting the module.
sivakasi-cisco Mar 13, 2026
c4c1acc
Interim changes to test with on ND output extraction changes in VPC
sivakasi-cisco Mar 18, 2026
e989d28
Changes to relocate files under models
sivakasi-cisco Mar 18, 2026
848d9e1
Interim changes to move across folders
sivakasi-cisco Mar 18, 2026
bbe1d16
Renamed ep names and corresponding imports, info on paths
sivakasi-cisco Mar 18, 2026
f68e921
Interim changes
sivakasi-cisco Mar 18, 2026
60f3f03
Adhereing to a common standard
sivakasi-cisco Mar 19, 2026
77dbe08
Interim changes
sivakasi-cisco Mar 19, 2026
096f5c4
Addressing review comments and other few
sivakasi-cisco Mar 23, 2026
1ac7373
Fine tuning the comments
sivakasi-cisco Mar 24, 2026
e136ce5
Intermediate fixes
sivakasi-cisco Mar 25, 2026
623c765
Intermediate fix removing suppress_previous
sivakasi-cisco Mar 25, 2026
58ae918
Intermediate fixes
sivakasi-cisco Mar 25, 2026
e1f7831
UT and small corrections in IT
sivakasi-cisco Mar 27, 2026
6eb9872
Changes made for
sivakasi-cisco Mar 31, 2026
d83ac06
Setting up deploy to be true by default, use_virtual_peer_link to fal…
sivakasi-cisco Apr 1, 2026
ea76635
path changes and NDBaseModel and NDNestedModel direct usage
sivakasi-cisco Apr 2, 2026
4494b18
Changes in manage_vpc_pair files and corresponding imports
sivakasi-cisco Apr 2, 2026
d34f24f
Reducing the timers - now having only api_timeout, query_timeout, ref…
sivakasi-cisco Apr 2, 2026
7f60b67
Renaming api_timeout to vpc_put_timeout. setting up the query_timeout…
sivakasi-cisco Apr 2, 2026
11aec5d
Modifying refresh_after_apply with an inversion of suppress_verification
sivakasi-cisco Apr 2, 2026
9e9c96e
Timer changes, pending variables changes
sivakasi-cisco Apr 2, 2026
46cb16c
getting sync status for deploy
sivakasi-cisco Apr 2, 2026
d04ffe5
Few sanity fixes and cleanups
sivakasi-cisco Apr 7, 2026
1bb5ecd
Fixing sanity failures
sivakasi-cisco Apr 7, 2026
39463a3
Addressing the review comments to\
sivakasi-cisco Apr 7, 2026
98fb931
Instead of re-exporting with __init__, it is made empty as per guidel…
sivakasi-cisco Apr 7, 2026
2846275
Fixing sanity failures
sivakasi-cisco Apr 7, 2026
854ac2d
Fixture for Deploy skip issue
sivakasi-cisco Apr 7, 2026
49de324
Integ test changes for sanity and checks
sivakasi-cisco Apr 7, 2026
979e17a
Added/addressed the list of items below
sivakasi-cisco Apr 9, 2026
7da587f
Integ test changes
sivakasi-cisco Apr 9, 2026
f49e382
Missed files from changes of base branch
sivakasi-cisco Apr 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
362 changes: 362 additions & 0 deletions plugins/action/tests/integration/nd_vpc_pair_validate.py

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions plugins/module_utils/endpoints/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,48 @@ class VrfNameMixin(BaseModel):
"""Mixin for endpoints that require vrf_name parameter."""

vrf_name: Optional[str] = Field(default=None, min_length=1, max_length=64, description="VRF name")


class SwitchIdMixin(BaseModel):
"""Mixin for endpoints that require switch_id parameter."""

switch_id: Optional[str] = Field(default=None, min_length=1, description="Switch serial number")


class PeerSwitchIdMixin(BaseModel):
"""Mixin for endpoints that require peer_switch_id parameter."""

peer_switch_id: Optional[str] = Field(default=None, min_length=1, description="Peer switch serial number")


class UseVirtualPeerLinkMixin(BaseModel):
"""Mixin for endpoints that require use_virtual_peer_link parameter."""

use_virtual_peer_link: Optional[bool] = Field(
default=False,
description="Indicates whether a virtual peer link is present",
)


class FromClusterMixin(BaseModel):
"""Mixin for endpoints that support fromCluster query parameter."""

from_cluster: Optional[str] = Field(default=None, description="Optional cluster name")


class TicketIdMixin(BaseModel):
"""Mixin for endpoints that support ticketId query parameter."""

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


class ComponentTypeMixin(BaseModel):
"""Mixin for endpoints that require componentType query parameter."""

component_type: Optional[str] = Field(default=None, description="Component type for filtering response")


class ViewMixin(BaseModel):
"""Mixin for endpoints that support view parameter."""

view: Optional[str] = Field(default=None, description="Optional view type for filtering results")
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2026, Sivakami Sivaraman sivakasi@cisco.com
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

from typing import Literal

from ansible_collections.cisco.nd.plugins.module_utils.common.pydantic_compat import (
ConfigDict,
Field,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.base import (
NDEndpointBaseModel,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.mixins import (
FabricNameMixin,
FromClusterMixin,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.v1.manage.base_path import (
BasePath,
)
from ansible_collections.cisco.nd.plugins.module_utils.enums import HttpVerbEnum

# API path covered by this file:
# /api/v1/manage/fabrics/{fabricName}/actions/configSave
COMMON_CONFIG = ConfigDict(validate_assignment=True)


class EpFabricConfigSavePost(
FabricNameMixin,
FromClusterMixin,
NDEndpointBaseModel,
):
"""
POST /api/v1/manage/fabrics/{fabricName}/actions/configSave
"""

model_config = COMMON_CONFIG
api_version: Literal["v1"] = Field(default="v1")
min_controller_version: str = Field(default="3.0.0")
class_name: Literal["EpFabricConfigSavePost"] = Field(default="EpFabricConfigSavePost")

@property
def path(self) -> str:
if self.fabric_name is None:
raise ValueError("fabric_name is required")
return BasePath.path("fabrics", self.fabric_name, "actions", "configSave")

@property
def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.POST
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2026, Sivakami Sivaraman sivakasi@cisco.com
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

from typing import Literal

from ansible_collections.cisco.nd.plugins.module_utils.common.pydantic_compat import (
ConfigDict,
Field,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.base import (
NDEndpointBaseModel,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.mixins import (
FabricNameMixin,
FromClusterMixin,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.v1.manage.base_path import (
BasePath,
)
from ansible_collections.cisco.nd.plugins.module_utils.enums import HttpVerbEnum

# API path covered by this file:
# /api/v1/manage/fabrics/{fabricName}/actions/deploy
COMMON_CONFIG = ConfigDict(validate_assignment=True)


class EpFabricDeployPost(
FabricNameMixin,
FromClusterMixin,
NDEndpointBaseModel,
):
"""
POST /api/v1/manage/fabrics/{fabricName}/actions/deploy
"""

model_config = COMMON_CONFIG
api_version: Literal["v1"] = Field(default="v1")
min_controller_version: str = Field(default="3.0.0")
class_name: Literal["EpFabricDeployPost"] = Field(default="EpFabricDeployPost")

@property
def path(self) -> str:
if self.fabric_name is None:
raise ValueError("fabric_name is required")
return BasePath.path("fabrics", self.fabric_name, "actions", "deploy")

@property
def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.POST
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2026, Sivakami Sivaraman sivakasi@cisco.com
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

from typing import Literal

from ansible_collections.cisco.nd.plugins.module_utils.common.pydantic_compat import (
ConfigDict,
Field,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.base import (
NDEndpointBaseModel,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.mixins import (
FabricNameMixin,
FromClusterMixin,
ViewMixin,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.query_params import (
CompositeQueryParams,
EndpointQueryParams,
LuceneQueryParams,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.v1.manage.base_path import (
BasePath,
)
from ansible_collections.cisco.nd.plugins.module_utils.enums import HttpVerbEnum

# API path covered by this file:
# /api/v1/manage/fabrics/{fabricName}/switches
COMMON_CONFIG = ConfigDict(validate_assignment=True)


class FabricSwitchesEndpointParams(FromClusterMixin, ViewMixin, EndpointQueryParams):
"""Endpoint-specific query parameters for fabric switches endpoint."""


class EpFabricSwitchesGet(
FabricNameMixin,
NDEndpointBaseModel,
):
"""
GET /api/v1/manage/fabrics/{fabricName}/switches
"""

model_config = COMMON_CONFIG
api_version: Literal["v1"] = Field(default="v1")
min_controller_version: str = Field(default="3.0.0")
class_name: Literal["EpFabricSwitchesGet"] = Field(default="EpFabricSwitchesGet")
endpoint_params: FabricSwitchesEndpointParams = Field(default_factory=FabricSwitchesEndpointParams, description="Endpoint-specific query parameters")
lucene_params: LuceneQueryParams = Field(default_factory=LuceneQueryParams, description="Lucene query parameters")

@property
def path(self) -> str:
if self.fabric_name is None:
raise ValueError("fabric_name is required")
base_path = BasePath.path("fabrics", self.fabric_name, "switches")
query_params = CompositeQueryParams().add(self.endpoint_params).add(self.lucene_params)
query_string = query_params.to_query_string()
if query_string:
return f"{base_path}?{query_string}"
return base_path

@property
def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.GET
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2026, Sivakami Sivaraman sivakasi@cisco.com
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

from typing import Literal

from ansible_collections.cisco.nd.plugins.module_utils.common.pydantic_compat import (
Field,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.base import (
NDEndpointBaseModel,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.mixins import (
FabricNameMixin,
FromClusterMixin,
SwitchIdMixin,
TicketIdMixin,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.query_params import (
EndpointQueryParams,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.v1.manage.base_path import (
BasePath,
)
from ansible_collections.cisco.nd.plugins.module_utils.enums import HttpVerbEnum

# API path covered by this file:
# /api/v1/manage/fabrics/{fabricName}/switches/{switchId}/vpcPair


class _EpVpcPairBase(
FabricNameMixin,
SwitchIdMixin,
NDEndpointBaseModel,
):
@property
def path(self) -> str:
if self.fabric_name is None or self.switch_id is None:
raise ValueError("fabric_name and switch_id are required")
base_path = BasePath.path(
"fabrics",
self.fabric_name,
"switches",
self.switch_id,
"vpcPair",
)
query_string = self.endpoint_params.to_query_string()
if query_string:
return f"{base_path}?{query_string}"
return base_path


class VpcPairGetEndpointParams(FromClusterMixin, EndpointQueryParams):
"""Endpoint-specific query parameters for vPC pair GET endpoint."""


class VpcPairPutEndpointParams(VpcPairGetEndpointParams, TicketIdMixin):
"""Endpoint-specific query parameters for vPC pair PUT endpoint."""


class EpVpcPairGet(_EpVpcPairBase):
"""
GET /api/v1/manage/fabrics/{fabricName}/switches/{switchId}/vpcPair
"""

class_name: Literal["EpVpcPairGet"] = Field(default="EpVpcPairGet", frozen=True, description="Class name for backward compatibility")
endpoint_params: VpcPairGetEndpointParams = Field(default_factory=VpcPairGetEndpointParams, description="Endpoint-specific query parameters")

@property
def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.GET


class EpVpcPairPut(_EpVpcPairBase):
"""
PUT /api/v1/manage/fabrics/{fabricName}/switches/{switchId}/vpcPair
"""

class_name: Literal["EpVpcPairPut"] = Field(default="EpVpcPairPut", frozen=True, description="Class name for backward compatibility")
endpoint_params: VpcPairPutEndpointParams = Field(default_factory=VpcPairPutEndpointParams, description="Endpoint-specific query parameters")

@property
def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.PUT
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2026, Sivakami Sivaraman sivakasi@cisco.com
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

from typing import Literal

from ansible_collections.cisco.nd.plugins.module_utils.common.pydantic_compat import (
Field,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.base import (
NDEndpointBaseModel,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.mixins import (
FabricNameMixin,
FromClusterMixin,
SwitchIdMixin,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.query_params import (
EndpointQueryParams,
)
from ansible_collections.cisco.nd.plugins.module_utils.endpoints.v1.manage.base_path import (
BasePath,
)
from ansible_collections.cisco.nd.plugins.module_utils.enums import HttpVerbEnum

# API path covered by this file:
# /api/v1/manage/fabrics/{fabricName}/switches/{switchId}/vpcPairConsistency


class VpcPairConsistencyEndpointParams(FromClusterMixin, EndpointQueryParams):
"""Endpoint-specific query parameters for vPC pair consistency endpoint."""


class EpVpcPairConsistencyGet(
FabricNameMixin,
SwitchIdMixin,
NDEndpointBaseModel,
):
"""
GET /api/v1/manage/fabrics/{fabricName}/switches/{switchId}/vpcPairConsistency
"""

class_name: Literal["EpVpcPairConsistencyGet"] = Field(default="EpVpcPairConsistencyGet", frozen=True, description="Class name for backward compatibility")
endpoint_params: VpcPairConsistencyEndpointParams = Field(
default_factory=VpcPairConsistencyEndpointParams, description="Endpoint-specific query parameters"
)

@property
def path(self) -> str:
if self.fabric_name is None or self.switch_id is None:
raise ValueError("fabric_name and switch_id are required")
base_path = BasePath.path(
"fabrics",
self.fabric_name,
"switches",
self.switch_id,
"vpcPairConsistency",
)
query_string = self.endpoint_params.to_query_string()
if query_string:
return f"{base_path}?{query_string}"
return base_path

@property
def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.GET
Loading
Loading