devaci 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- devaci/__init__.py +20 -0
- devaci/cobra/__init__.py +93 -0
- devaci/cobra/base.py +28 -0
- devaci/cobra/builders.py +1886 -0
- devaci/cobra/registry.py +24 -0
- devaci/console.py +34 -0
- devaci/data.py +81 -0
- devaci/deploy.py +320 -0
- devaci/exceptions.py +23 -0
- devaci/filters.py +103 -0
- devaci/jinja.py +42 -0
- devaci/py.typed +0 -0
- devaci/results.py +71 -0
- devaci-0.1.0.dist-info/METADATA +110 -0
- devaci-0.1.0.dist-info/RECORD +17 -0
- devaci-0.1.0.dist-info/WHEEL +4 -0
- devaci-0.1.0.dist-info/licenses/LICENSE +21 -0
devaci/results.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Result data classes for devaci."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _timestamp() -> str:
|
|
12
|
+
return datetime.now().strftime("%d/%m/%Y-%H:%M:%S")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class Result:
|
|
17
|
+
"""Base result shared by all devaci phases."""
|
|
18
|
+
|
|
19
|
+
success: bool = False
|
|
20
|
+
log: list[str] = field(default_factory=list)
|
|
21
|
+
date: str = field(default_factory=_timestamp)
|
|
22
|
+
|
|
23
|
+
def to_dict(self) -> dict[str, Any]:
|
|
24
|
+
return {"date": self.date, "success": self.success, "log": self.log}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class JinjaResult(Result):
|
|
29
|
+
"""Result of a Jinja template render."""
|
|
30
|
+
|
|
31
|
+
output: Any = None
|
|
32
|
+
|
|
33
|
+
def to_dict(self) -> dict[str, Any]:
|
|
34
|
+
data = super().to_dict()
|
|
35
|
+
data["output"] = self.output
|
|
36
|
+
return data
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class CobraResult(Result):
|
|
41
|
+
"""Result of building the Cobra configuration."""
|
|
42
|
+
|
|
43
|
+
config: Any = None
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def xml(self) -> str | None:
|
|
47
|
+
return self.config.xmldata if self.config is not None else None
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def json(self) -> Any:
|
|
51
|
+
return json.loads(self.config.data) if self.config is not None else None
|
|
52
|
+
|
|
53
|
+
def to_dict(self) -> dict[str, Any]:
|
|
54
|
+
data = super().to_dict()
|
|
55
|
+
data["json"] = self.json
|
|
56
|
+
data["xml"] = self.xml
|
|
57
|
+
return data
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass(frozen=True)
|
|
61
|
+
class DeployResult(Result):
|
|
62
|
+
"""Result of deploying a single template."""
|
|
63
|
+
|
|
64
|
+
path: str = "/"
|
|
65
|
+
name: str = "template"
|
|
66
|
+
|
|
67
|
+
def to_dict(self) -> dict[str, Any]:
|
|
68
|
+
data = super().to_dict()
|
|
69
|
+
data["path"] = self.path
|
|
70
|
+
data["name"] = self.name
|
|
71
|
+
return data
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: devaci
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python library that generates Cisco ACI configuration and optionally pushes it to an APIC controller via Cisco's official Cobra SDK.
|
|
5
|
+
Project-URL: Homepage, https://github.com/cocuni80/devaci
|
|
6
|
+
Project-URL: Repository, https://github.com/cocuni80/devaci
|
|
7
|
+
Project-URL: Issues, https://github.com/cocuni80/devaci/issues
|
|
8
|
+
Author: Jorge Riveros
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: aci,apic,cisco,cobra,networking,sdn
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: System :: Networking
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: jinja2>=3.1.6
|
|
24
|
+
Requires-Dist: openpyxl>=3.1.5
|
|
25
|
+
Requires-Dist: pandas>=2.3.3
|
|
26
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
27
|
+
Requires-Dist: rich>=15.0.0
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# devaci
|
|
31
|
+
|
|
32
|
+
Python library that generates Cisco ACI configuration and optionally pushes it to an APIC controller via Cisco's official Cobra SDK.
|
|
33
|
+
|
|
34
|
+
## Structure
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
devaci/
|
|
38
|
+
├── LICENSE
|
|
39
|
+
├── README.md
|
|
40
|
+
├── pyproject.toml
|
|
41
|
+
├── pyrightconfig.json
|
|
42
|
+
├── uv.lock
|
|
43
|
+
├── src/
|
|
44
|
+
│ └── devaci/
|
|
45
|
+
│ ├── __init__.py # public API
|
|
46
|
+
│ ├── console.py # logging + rich console
|
|
47
|
+
│ ├── data.py # xlsx/csv loading and filtering
|
|
48
|
+
│ ├── deploy.py # DeployClass orchestrator
|
|
49
|
+
│ ├── exceptions.py
|
|
50
|
+
│ ├── filters.py # Jinja filters + YAML loader
|
|
51
|
+
│ ├── jinja.py # JinjaRenderer
|
|
52
|
+
│ ├── results.py # result dataclasses
|
|
53
|
+
│ └── cobra/
|
|
54
|
+
│ ├── __init__.py # CobraBuilder
|
|
55
|
+
│ ├── base.py
|
|
56
|
+
│ ├── builders.py # registered ACI object handlers
|
|
57
|
+
│ └── registry.py
|
|
58
|
+
└── tests/
|
|
59
|
+
├── test_cobra.py
|
|
60
|
+
├── test_deploy.py
|
|
61
|
+
├── test_devaci.py
|
|
62
|
+
└── test_outputs.py
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Installation (development)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install uv # if you don't have it yet
|
|
69
|
+
uv sync # creates .venv and installs devaci + dev dependencies
|
|
70
|
+
source .venv/bin/activate
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
To add/remove dependencies:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv add requests # runtime dependency
|
|
77
|
+
uv add --dev httpx # development dependency
|
|
78
|
+
uv remove requests
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## External dependency: Cobra SDK
|
|
82
|
+
|
|
83
|
+
The Cisco ACI Cobra SDK (`acicobra`, `acimodel`, `aciparser`, `acirpc`) is **not on PyPI**.
|
|
84
|
+
Download the `.whl` files from Cisco and place them in the `vendor/` folder (not tracked by git), then:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv pip install vendor/*.whl
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Tests that depend on the Cobra SDK fail if it is not installed.
|
|
91
|
+
|
|
92
|
+
## Tests
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
uv run pytest
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Lint and type checking
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run ruff check .
|
|
102
|
+
uv run mypy src
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Publishing
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uv build
|
|
109
|
+
uv publish
|
|
110
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
devaci/__init__.py,sha256=rAi46Bunx6mSEM88fyEPrv4wet77VqLDJyQKZRPSLHQ,490
|
|
2
|
+
devaci/console.py,sha256=NDRSGURaVLb42EhM4_wPbIotE1Jpx2a9ABVXwu0nTUg,1033
|
|
3
|
+
devaci/data.py,sha256=i7a_Pr5merZ9-mw2spMmXNgzPdMkm61qNH1VMQscODc,2530
|
|
4
|
+
devaci/deploy.py,sha256=tAVtf0UCY0ZGug_ouXWjkIZq9CSUpx_DbPFUTx7rVRM,12511
|
|
5
|
+
devaci/exceptions.py,sha256=SJY7XpcXLLkNPPFYuEonFlT5zQQ6xjvQwBDn6EOvNnw,526
|
|
6
|
+
devaci/filters.py,sha256=wSC1Yq1U0bmDPtxvYOuLqvapBDswyIDQGNScJwOeguE,3267
|
|
7
|
+
devaci/jinja.py,sha256=5vtfE20oINgr1_CuM3zqFuaptCN_opnURGpqLiNfuos,1431
|
|
8
|
+
devaci/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
devaci/results.py,sha256=Zs3QPECXYai3uSoDVPWUdr58L-CcS0cVOPrGhTjKgdc,1699
|
|
10
|
+
devaci/cobra/__init__.py,sha256=JGHXamT9-zJrSnnVWVBixiLYhaDYtE-LquDkdQL53s8,2906
|
|
11
|
+
devaci/cobra/base.py,sha256=dTq0awniJNe-4XAPRedlKH0GnVDC7FQ5fviXkkQeWD8,841
|
|
12
|
+
devaci/cobra/builders.py,sha256=BYwX4lekKUG792ClAw4_rdSk7PkqGL88crcz1TqdoUU,87087
|
|
13
|
+
devaci/cobra/registry.py,sha256=LKh9_sAyakHXo0URP4w5MSP_5UTDEpN06SFV8relmkQ,583
|
|
14
|
+
devaci-0.1.0.dist-info/METADATA,sha256=Nu6qPOPbYyrSEao7dmUkstIV5OFOw2edLmAJm-HgCEk,3174
|
|
15
|
+
devaci-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
16
|
+
devaci-0.1.0.dist-info/licenses/LICENSE,sha256=1sWD1nTI5nS9Jxj6UktuJAEx_OG73nk0tWJBSZx9Mz0,1070
|
|
17
|
+
devaci-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jorge Riveros
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|