Merge branch 'main' into feat/apt-proxy-verify
driver / standard (pull_request) Successful in 13s
driver / lint (pull_request) Successful in 1m24s
driver / types (pull_request) Successful in 44s
driver / test (3.10) (pull_request) Successful in 50s
driver / test (3.11) (pull_request) Successful in 48s
driver / test (3.12) (pull_request) Successful in 48s
driver / test (3.13) (pull_request) Successful in 41s
driver / lowest (pull_request) Successful in 24s
driver / security (pull_request) Successful in 46s
driver / build (pull_request) Successful in 23s
CI / driver (pull_request) Successful in 7m2s
driver / publish (pull_request) Skipped
driver / standard (pull_request) Successful in 13s
driver / lint (pull_request) Successful in 1m24s
driver / types (pull_request) Successful in 44s
driver / test (3.10) (pull_request) Successful in 50s
driver / test (3.11) (pull_request) Successful in 48s
driver / test (3.12) (pull_request) Successful in 48s
driver / test (3.13) (pull_request) Successful in 41s
driver / lowest (pull_request) Successful in 24s
driver / security (pull_request) Successful in 46s
driver / build (pull_request) Successful in 23s
CI / driver (pull_request) Successful in 7m2s
driver / publish (pull_request) Skipped
The NAPALM driver standard landed on main (#52, 4.21.1). apt_proxy follows it: builtin generics, strict mypy, complexity 10 at most (parse_apt_proxy, same_proxy_url and the comment-out step split into helpers), 100 % covered. Its TypedDicts live in apt_proxy.py, since models.py is over 1000 lines and may not grow. Version 4.22.0 with its CHANGELOG section.
This commit is contained in:
commit
a07ced2df6
83 files changed
+1698
-1284
No files matched your search
@@ -6,14 +6,14 @@ Instead of inheriting directly from `napalm.base.NetworkDriver`, a driver can in
|
||||
|
||||
```python
|
||||
# without napalm-device-types
|
||||
class OpenWrtDriver(NetworkDriver):
|
||||
...
|
||||
class OpenWrtDriver(NetworkDriver): ...
|
||||
|
||||
|
||||
# with napalm-device-types
|
||||
from napalm_device_types import AccessPointDriver
|
||||
|
||||
class OpenWrtDriver(AccessPointDriver):
|
||||
...
|
||||
|
||||
class OpenWrtDriver(AccessPointDriver): ...
|
||||
```
|
||||
|
||||
## Why?
|
||||
@@ -29,8 +29,9 @@ OpenMediaVault box is a NAS built on Debian. So a driver inherits **one role bas
|
||||
role its device fills**, and **the order it lists them in is the ranking**:
|
||||
|
||||
```python
|
||||
class QnapQtsDriver(StorageDriver, HypervisorDriver, LinuxDriver):
|
||||
... # primary_role_of(...) == "storage"
|
||||
class QnapQtsDriver(
|
||||
StorageDriver, HypervisorDriver, LinuxDriver
|
||||
): ... # primary_role_of(...) == "storage"
|
||||
```
|
||||
|
||||
`roles_of(cls)`, `role_keys_of(cls)` and `primary_role_of(cls)` read that back. Nothing
|
||||
@@ -54,10 +55,12 @@ host OS's load; it has no `HealthMetricsMixin` (SNMP) and no command channel.
|
||||
```python
|
||||
class StorageDriver(DeviceTypeDriver):
|
||||
"""Contract, not code."""
|
||||
|
||||
ROLE: str = "storage"
|
||||
TYPE_LABEL: str = "Storage"
|
||||
|
||||
if TYPE_CHECKING: # nothing exists at runtime
|
||||
if TYPE_CHECKING: # nothing exists at runtime
|
||||
|
||||
def get_disks(self) -> List[PhysicalDiskDict]: ...
|
||||
```
|
||||
|
||||
@@ -321,20 +324,27 @@ generic data shapes belong here. Only the actual device communication belongs in
|
||||
**Worked example — firewall rule diff/apply** (`FirewallRuleMixin`, in `FirewallDriver`):
|
||||
|
||||
```python
|
||||
class FirewallRuleMixin: # mixed into FirewallDriver
|
||||
class FirewallRuleMixin: # mixed into FirewallDriver
|
||||
# Declared only — every driver implements its own device communication.
|
||||
if TYPE_CHECKING:
|
||||
|
||||
def get_firewall_rules(self) -> List[FirewallRuleDict]: ...
|
||||
def apply_firewall_rule(self, rule: FirewallRuleDict, *, uuid: Optional[str] = None) -> Dict[str, Any]: ...
|
||||
def apply_firewall_rule(
|
||||
self, rule: FirewallRuleDict, *, uuid: Optional[str] = None
|
||||
) -> Dict[str, Any]: ...
|
||||
def commit_firewall_rules(self) -> Dict[str, Any]: ...
|
||||
|
||||
# Concrete — the matching/comparison/orchestration algorithm is identical
|
||||
# for every firewall vendor, so it lives here once.
|
||||
def diff_firewall_rules(self, desired: List[FirewallRuleDict]) -> FirewallRuleDiffDict:
|
||||
... # matches self.get_firewall_rules() against `desired` by description
|
||||
def diff_firewall_rules(
|
||||
self, desired: List[FirewallRuleDict]
|
||||
) -> (
|
||||
FirewallRuleDiffDict
|
||||
): ... # matches self.get_firewall_rules() against `desired` by description
|
||||
|
||||
def apply_firewall_ruleset(self, desired: List[FirewallRuleDict]):
|
||||
... # computes the diff, calls apply_firewall_rule() per change, commits
|
||||
def apply_firewall_ruleset(
|
||||
self, desired: List[FirewallRuleDict]
|
||||
): ... # computes the diff, calls apply_firewall_rule() per change, commits
|
||||
```
|
||||
|
||||
The same split applies to `DhcpServerMixin`: `get_dhcp_reservations`/
|
||||
@@ -430,8 +440,8 @@ HTTP_FINGERPRINT = [
|
||||
```python
|
||||
from napalm_device_types import AccessPointDriver
|
||||
|
||||
class OpenWrtDriver(AccessPointDriver):
|
||||
|
||||
class OpenWrtDriver(AccessPointDriver):
|
||||
def get_wireless_clients(self):
|
||||
# return List[WirelessClientDict]
|
||||
...
|
||||
@@ -446,8 +456,8 @@ class OpenWrtDriver(AccessPointDriver):
|
||||
```python
|
||||
from napalm_device_types import SwitchDriver
|
||||
|
||||
class CiscoIOSDriver(SwitchDriver):
|
||||
|
||||
class CiscoIOSDriver(SwitchDriver):
|
||||
def get_spanning_tree(self):
|
||||
# return Dict[str, SpanningTreeDict]
|
||||
...
|
||||
@@ -462,8 +472,8 @@ class CiscoIOSDriver(SwitchDriver):
|
||||
```python
|
||||
from napalm_device_types import FirewallDriver
|
||||
|
||||
class PfSenseDriver(FirewallDriver):
|
||||
|
||||
class PfSenseDriver(FirewallDriver):
|
||||
def get_nat_translations(self):
|
||||
# return List[NATTranslationDict]
|
||||
...
|
||||
@@ -483,14 +493,13 @@ class PfSenseDriver(FirewallDriver):
|
||||
```python
|
||||
from napalm_device_types import HypervisorDriver
|
||||
|
||||
class ProxmoxDriver(HypervisorDriver):
|
||||
|
||||
class ProxmoxDriver(HypervisorDriver):
|
||||
def get_vms(self):
|
||||
# return List[VMDict]
|
||||
...
|
||||
|
||||
def create_vm_snapshot(self, name, snapshot, description="", include_memory=False):
|
||||
...
|
||||
def create_vm_snapshot(self, name, snapshot, description="", include_memory=False): ...
|
||||
|
||||
def get_vm_cpu_types(self):
|
||||
# optional — return List[VMCpuTypeDict]: the CPU models a new VM may get
|
||||
@@ -514,8 +523,8 @@ unpacked; both are the same for every hypervisor.
|
||||
```python
|
||||
from napalm_device_types import OSDriver
|
||||
|
||||
class LinuxDriver(OSDriver):
|
||||
|
||||
class LinuxDriver(OSDriver):
|
||||
def get_packages(self):
|
||||
# return List[PackageDict]
|
||||
...
|
||||
@@ -542,8 +551,8 @@ class LinuxDriver(OSDriver):
|
||||
```python
|
||||
from napalm_device_types import StorageDriver
|
||||
|
||||
class TrueNASDriver(StorageDriver):
|
||||
|
||||
class TrueNASDriver(StorageDriver):
|
||||
def get_disks(self):
|
||||
# return List[PhysicalDiskDict]
|
||||
...
|
||||
@@ -569,7 +578,7 @@ from napalm_device_types.models import (
|
||||
## Development
|
||||
|
||||
```bash
|
||||
git clone https://github.com/chrismanivong/napalm-device-types.git
|
||||
git clone https://git.netork.io/NAPALM/napalm-device-types.git
|
||||
cd napalm-device-types
|
||||
pip install -e ".[dev]"
|
||||
```
|
||||
@@ -582,10 +591,15 @@ mypy napalm_device_types
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b feature/router-driver`)
|
||||
3. Implement your changes
|
||||
4. Open a Pull Request
|
||||
This package follows the
|
||||
[NAPALM driver standard](https://git.netork.io/NAPALM/driver-standard/src/branch/main/STANDARDS.md):
|
||||
test first, ruff and strict mypy, Conventional Commits, one pull request per change
|
||||
against `main`. CI checks what a tool can check:
|
||||
|
||||
```bash
|
||||
pip install "napalm-standard @ git+https://git.netork.io/NAPALM/driver-standard.git"
|
||||
napalm-standard check && napalm-standard ratchet
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Reference in new issue
Block a user