Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5c8b04d
[ignore] Add generic logger facility through the Log class and loggin…
allenrobel Mar 2, 2026
756bdcc
[ignore] Add Endpoints framework for ND API v1 (#186)
allenrobel Mar 11, 2026
f5b1655
[ignore] Add RestSend framework, enums, and shared unit test infrastr…
allenrobel Mar 12, 2026
06633f6
[ignore] Fix broken imports after nd42_rest_send restructuring
allenrobel Mar 13, 2026
1c3b3c6
[minor_change] Add nd_local_user as a new network resource module for…
gmicol Aug 19, 2025
c70a93f
[ignore] First Pydantic implementation: Add Pydantic Models for nd_lo…
gmicol Jan 15, 2026
267e2a8
[ignore] Second Pydantic Implementation: Create a NDBaseModel to be i…
gmicol Jan 20, 2026
9b6bebd
[ignore] Pydantic Models: Modify and Clean both local_user.py and bas…
gmicol Jan 22, 2026
019c8e3
[ignore] Pydantic ND base models and local_user models: Final proposi…
gmicol Jan 23, 2026
427f33f
[ignore] Pydantic ND Config Collection: Final proposition of core des…
gmicol Jan 23, 2026
6fe3bbf
[ignore] Pydantic Base ND Network Resource Module: Final proposition …
gmicol Jan 23, 2026
0b36b2d
[ignore] Modify nd_local_user based on Pydantic implementation and ch…
gmicol Jan 23, 2026
e37636f
[ignore] Add api_endpoints for configuring endpoints and orchestrator…
gmicol Feb 17, 2026
fcde8c9
[ignore] Modifiy models/local_user to take full advantage of Pydantic…
gmicol Feb 18, 2026
5cf2a48
[ignore] Adapt the Network Resource Module architecture for ND to sma…
gmicol Feb 24, 2026
6c411bc
[ignore] Default to none and update condition for regarding in mod…
gmicol Feb 25, 2026
8ed627c
[ignore] Add choice for when no identifier is needed. Add quick com…
gmicol Feb 26, 2026
1ddd995
[ignore] Complete orchestrators/base.py by making simple CRUD operati…
gmicol Feb 26, 2026
aa99bbf
[ignore] Fix and in nd_config_collections.py. Move to utils.py.
gmicol Feb 26, 2026
04c73ff
[ignore] Rename NDNetworkResourceModule to NDStateMachine. Add file f…
gmicol Feb 26, 2026
85c36e8
[ignore] Make a small change to NDModule request function.
gmicol Feb 26, 2026
034b49f
[ignore] Modify nd_state_machine to work with orchestrators/models/ap…
gmicol Mar 2, 2026
b6ddee4
[ignore] Add proper path dependencies and Ran black formatting.
gmicol Mar 3, 2026
1d96db1
[ignore] Clean code for sanity purposes (except Pydantic import checks.
gmicol Mar 3, 2026
5d1f52f
[ignore] Restructure api_endpoints folder into endpoints -> v1. Fix s…
gmicol Mar 3, 2026
039103e
[ignore] Remove NDModule inheritence from NDStateMachine. Add first i…
gmicol Mar 3, 2026
c1774d1
[ignore] Rename NDBaseSmartEndpoint to NDBaseEndpoint. Fix importatio…
gmicol Mar 3, 2026
872b5f4
[ignore] Replace all pydantic imports with pydantic_compat. Fix sanit…
gmicol Mar 4, 2026
24c0686
[ignore] Add NDOutput class. Modify NDStateMachine and nd_local_user …
gmicol Mar 6, 2026
dedc958
[ignore] Update NDOutput class. Remove all fail_json dependencies in …
gmicol Mar 10, 2026
2d472d9
[ignore] Fix serialization of model with minimal changes to base.py …
gmicol Mar 11, 2026
de81d56
[ignore] Complete nd_local_user integration test for creation and upd…
gmicol Mar 11, 2026
401deed
[ignore] Finish integration test file for nd_local_user module. Remov…
gmicol Mar 12, 2026
a325955
[ignore] Fix sanity issues by enhancing pydantic_compat.py. Fix Black…
gmicol Mar 12, 2026
ea06769
[ignore] Remove all TODO comments.
gmicol Mar 12, 2026
47af5f4
[ignore] Update endpoints to match latest nd42_integration branch. Up…
gmicol Mar 12, 2026
2f6de8a
[ignore] Update pydantic_compat.py to support extra Pydantic methods …
gmicol Mar 12, 2026
79dc000
[ignore] Remove Python 2.7 compatibilities.
gmicol Mar 17, 2026
2c7ec78
[ignore] Fix comments and docstrings. made and static methods for …
gmicol Mar 17, 2026
7142c43
[ignore] Slightly modify Exceptions handling in NDStateMachine. Remov…
gmicol Mar 18, 2026
bc5cfb0
[ignore] Rename aaa_local_users.py to infra_aaa_local_users.py. Move …
gmicol Mar 18, 2026
ed33a5a
[ignore] Update integration tests for nd_local_user module.
gmicol Mar 19, 2026
a859d13
[ignore] Revert local users endpoints filename to aaa_local_users.py.
gmicol Mar 19, 2026
96a492d
[ignore] Change in NDStateMachine initialization to take advantage o…
gmicol Mar 19, 2026
4c593df
[ignore] Remove ValidationError import from nd_state_machine.py.
gmicol Mar 19, 2026
f3a0eff
[ignore] Add function to nd_local_user module. Slighty fix Documenta…
gmicol Mar 24, 2026
a8073b6
[ignore] Make NDBaseOrchestrator a Generic class.
gmicol Mar 24, 2026
3c54a5c
[ignore] Enable CI unit tests
samiib Mar 17, 2026
0af63e6
[ignore] Add pydantic to requirements.txt
samiib Mar 23, 2026
e0476f8
merge develop
mtarking Apr 2, 2026
932a186
temp update to pr branch list for ci
mtarking Apr 2, 2026
85523e3
[minor_change] Addition of module for ND 4.2 Links comprising manage …
shrsr Apr 6, 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
6 changes: 3 additions & 3 deletions .github/workflows/ansible-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
branches:
- develop
- main
- nd42_integration
# schedule:
# # * is a special character in YAML so you have to quote this string
# - cron: '0 6 * * *'
Expand Down Expand Up @@ -199,9 +200,8 @@ jobs:

units:
name: Unit Tests
if: false # No unit tests yet
needs:
- ansible-galaxy-importer
- ansible-test
runs-on: ubuntu-latest
strategy: *ansible_strategy

Expand Down Expand Up @@ -242,7 +242,7 @@ jobs:
name: Integration Tests
if: false # No integration tests for now
needs:
# - units
- units
- ansible-test
runs-on: ubuntu-latest
strategy: *ansible_strategy
Expand Down
Empty file.
Empty file.
149 changes: 149 additions & 0 deletions plugins/module_utils/common/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Copyright: (c) 2026, Allen Robel (@arobel) <arobel@cisco.com>
# Copyright: (c) 2026, Gaspard Micol (@gmicol) <gmicol@cisco.com>

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

Exception classes for the cisco.nd Ansible collection.
"""

# isort: off
# fmt: off
from __future__ import (absolute_import, division, print_function)
from __future__ import annotations
# fmt: on
# isort: on

from typing import Any, Optional

from ansible_collections.cisco.nd.plugins.module_utils.common.pydantic_compat import (
BaseModel,
ConfigDict,
)


class NDErrorData(BaseModel):
"""
# Summary

Pydantic model for structured error data from NDModule requests.

This model provides type-safe error information that can be serialized
to a dict for use with Ansible's fail_json.

## Attributes

- msg: Human-readable error message (required)
- status: HTTP status code as integer (optional)
- request_payload: Request payload that was sent (optional)
- response_payload: Response payload from controller (optional)
- raw: Raw response content for non-JSON responses (optional)

## Raises

- None
"""

model_config = ConfigDict(extra="forbid")

msg: str
status: Optional[int] = None
request_payload: Optional[dict[str, Any]] = None
response_payload: Optional[dict[str, Any]] = None
raw: Optional[Any] = None


class NDModuleError(Exception):
"""
# Summary

Exception raised by NDModule when a request fails.

This exception wraps an NDErrorData Pydantic model, providing structured
error information that can be used by callers to build appropriate error
responses (e.g., Ansible fail_json).

## Usage Example

```python
try:
data = nd.request("/api/v1/endpoint", HttpVerbEnum.POST, payload)
except NDModuleError as e:
print(f"Error: {e.msg}")
print(f"Status: {e.status}")
if e.response_payload:
print(f"Response: {e.response_payload}")
# Use to_dict() for fail_json
module.fail_json(**e.to_dict())
```

## Raises

- None
"""

# pylint: disable=too-many-arguments
def __init__(
self,
msg: str,
status: Optional[int] = None,
request_payload: Optional[dict[str, Any]] = None,
response_payload: Optional[dict[str, Any]] = None,
raw: Optional[Any] = None,
) -> None:
self.error_data = NDErrorData(
msg=msg,
status=status,
request_payload=request_payload,
response_payload=response_payload,
raw=raw,
)
super().__init__(msg)

@property
def msg(self) -> str:
"""Human-readable error message."""
return self.error_data.msg

@property
def status(self) -> Optional[int]:
"""HTTP status code."""
return self.error_data.status

@property
def request_payload(self) -> Optional[dict[str, Any]]:
"""Request payload that was sent."""
return self.error_data.request_payload

@property
def response_payload(self) -> Optional[dict[str, Any]]:
"""Response payload from controller."""
return self.error_data.response_payload

@property
def raw(self) -> Optional[Any]:
"""Raw response content for non-JSON responses."""
return self.error_data.raw

def to_dict(self) -> dict[str, Any]:
"""
# Summary

Convert exception attributes to a dict for use with fail_json.

Returns a dict containing only non-None attributes.

## Raises

- None
"""
return self.error_data.model_dump(exclude_none=True)


class NDStateMachineError(Exception):
"""
Raised when NDStateMachine is failing.
"""

pass
Loading
Loading