Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
96 changes: 96 additions & 0 deletions plugins/module_utils/endpoints/v1/manage/manage_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
(POST /api/v1/manage/fabrics/{fabric_name}/switches/{switch_sn}/interfaces)
- `EpManageInterfacesPut` - Update a specific interface
(PUT /api/v1/manage/fabrics/{fabric_name}/switches/{switch_sn}/interfaces/{interface_name})
- `EpManageInterfacesDelete` - Delete a virtual interface (loopback, SVI); not supported for physical ethernet
(DELETE /api/v1/manage/fabrics/{fabric_name}/switches/{switch_sn}/interfaces/{interface_name})
- `EpManageInterfacesDeploy` - Deploy interface configurations
(POST /api/v1/manage/fabrics/{fabric_name}/interfaceActions/deploy)
- `EpManageInterfacesNormalize` - Reset physical interface configurations to default
(POST /api/v1/manage/fabrics/{fabric_name}/interfaceActions/normalize)
- `EpManageInterfacesRemove` - Bulk delete interfaces
(POST /api/v1/manage/fabrics/{fabric_name}/interfaceActions/remove)
"""
Expand Down Expand Up @@ -238,6 +242,46 @@ def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.PUT


class EpManageInterfacesDelete(_EpManageInterfacesBase):
"""
# Summary

Delete a specific interface configuration.

- Path: `/api/v1/manage/fabrics/{fabric_name}/switches/{switch_sn}/interfaces/{interface_name}`
- Verb: DELETE

This endpoint works for virtual interfaces (loopback, SVI) only. For physical ethernet interfaces, the API returns
HTTP 500 ("Interface cannot be deleted!!!").

To reset physical interfaces to their default state, see `EpManageInterfacesNormalize` and set the payload to an
appropriate default config (for example `module_utils/models/interfaces/interface_default_config.py`).

## Raises

### ValueError

- Via inherited `path` property if `fabric_name`, `switch_sn`, or `interface_name` is not set.
"""

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

@property
def verb(self) -> HttpVerbEnum:
"""
# Summary

Return `HttpVerbEnum.DELETE`.

## Raises

None
"""
return HttpVerbEnum.DELETE


class EpManageInterfacesDeploy(FabricNameMixin, NDEndpointBaseModel):
"""
# Summary
Expand Down Expand Up @@ -290,6 +334,58 @@ def verb(self) -> HttpVerbEnum:
return HttpVerbEnum.POST


class EpManageInterfacesNormalize(FabricNameMixin, NDEndpointBaseModel):
"""
# Summary

Normalize interface configurations on switches.

- Path: `/api/v1/manage/fabrics/{fabric_name}/interfaceActions/normalize`
- Verb: POST
- Body: `{"interfaceType": "ethernet", "configData": {...}, "switchInterfaces": [{"interfaceName": "...", "switchId": "..."}]}`

## Raises

### ValueError

- Via `path` property if `fabric_name` is not set.
"""

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

@property
def path(self) -> str:
"""
# Summary

Build the normalize endpoint path.

## Raises

### ValueError

- If `fabric_name` is not set before accessing `path`.
"""
if self.fabric_name is None:
raise ValueError(f"{type(self).__name__}.path: fabric_name must be set before accessing path.")
return BasePath.path("fabrics", self.fabric_name, "interfaceActions", "normalize")

@property
def verb(self) -> HttpVerbEnum:
"""
# Summary

Return `HttpVerbEnum.POST`.

## Raises

None
"""
return HttpVerbEnum.POST


class EpManageInterfacesRemove(FabricNameMixin, NDEndpointBaseModel):
"""
# Summary
Expand Down
135 changes: 135 additions & 0 deletions plugins/module_utils/models/interfaces/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Copyright: (c) 2026, Allen Robel (@allenrobel)

# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

"""
# Summary

Shared enum definitions for ethernet interface models.

These enums are derived from ND config templates (e.g. `int_access_host`, `int_trunk_host`) and constrain policy
fields across multiple interface types. Each enum's member values match the API's expected strings exactly.
"""

from __future__ import annotations

from enum import Enum


class AccessHostPolicyTypeEnum(str, Enum):
"""
# Summary

Policy type for access host interfaces.
"""

ACCESS_HOST = "accessHost"


class BpduFilterEnum(str, Enum):
"""
# Summary

Spanning-tree BPDU filter settings.
"""

ENABLE = "enable"
DISABLE = "disable"
DEFAULT = "default"


class BpduGuardEnum(str, Enum):
"""
# Summary

Spanning-tree BPDU guard settings.
"""

ENABLE = "enable"
DISABLE = "disable"
DEFAULT = "default"


class DuplexModeEnum(str, Enum):
"""
# Summary

Port duplex mode settings.
"""

AUTO = "auto"
FULL = "full"
HALF = "half"


class FecEnum(str, Enum):
"""
# Summary

Forward error correction (FEC) mode.
"""

AUTO = "auto"
FC_FEC = "fcFec"
OFF = "off"
RS_CONS16 = "rsCons16"
RS_FEC = "rsFec"
RS_IEEE = "rsIEEE"


class LinkTypeEnum(str, Enum):
"""
# Summary

Spanning-tree link type.
"""

AUTO = "auto"
POINT_TO_POINT = "pointToPoint"
SHARED = "shared"


class MtuEnum(str, Enum):
"""
# Summary

Interface MTU setting.
"""

DEFAULT = "default"
JUMBO = "jumbo"


class SpeedEnum(str, Enum):
"""
# Summary

Interface speed setting.
"""

AUTO = "auto"
TEN_MB = "10Mb"
HUNDRED_MB = "100Mb"
ONE_GB = "1Gb"
TWO_POINT_FIVE_GB = "2.5Gb"
FIVE_GB = "5Gb"
TEN_GB = "10Gb"
TWENTY_FIVE_GB = "25Gb"
FORTY_GB = "40Gb"
FIFTY_GB = "50Gb"
HUNDRED_GB = "100Gb"
TWO_HUNDRED_GB = "200Gb"
FOUR_HUNDRED_GB = "400Gb"
EIGHT_HUNDRED_GB = "800Gb"


class StormControlActionEnum(str, Enum):
"""
# Summary

Storm control action on threshold violation.
"""

SHUTDOWN = "shutdown"
TRAP = "trap"
DEFAULT = "default"
Loading