annet 3.5.1__py3-none-any.whl → 3.6.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.
Potentially problematic release.
This version of annet might be problematic. Click here for more details.
- annet/adapters/netbox/common/adapter.py +30 -3
- annet/adapters/netbox/common/manufacturer.py +15 -14
- annet/adapters/netbox/common/models.py +51 -7
- annet/adapters/netbox/common/storage_base.py +23 -3
- annet/adapters/netbox/v37/models.py +19 -3
- annet/adapters/netbox/v37/storage.py +36 -4
- annet/adapters/netbox/v41/models.py +20 -14
- annet/adapters/netbox/v41/storage.py +38 -4
- annet/adapters/netbox/v42/models.py +6 -4
- annet/adapters/netbox/v42/storage.py +38 -3
- annet/hardware.py +3 -3
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/METADATA +2 -2
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/RECORD +18 -18
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/WHEEL +1 -1
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/entry_points.txt +0 -0
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/licenses/AUTHORS +0 -0
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/licenses/LICENSE +0 -0
- {annet-3.5.1.dist-info → annet-3.6.0.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
from abc import abstractmethod, ABC
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Generic, TypeVar
|
|
3
3
|
|
|
4
4
|
from annet.annlib.netdev.views.hardware import HardwareView
|
|
5
5
|
from .manufacturer import get_breed, get_hw
|
|
6
|
-
from .models import NetboxDevice, Interface, IpAddress, Prefix
|
|
6
|
+
from .models import NetboxDevice, Interface, IpAddress, Prefix, \
|
|
7
|
+
FHRPGroupAssignment, FHRPGroup
|
|
7
8
|
|
|
8
9
|
NetboxDeviceT = TypeVar("NetboxDeviceT", bound=NetboxDevice)
|
|
9
10
|
InterfaceT = TypeVar("InterfaceT", bound=Interface)
|
|
10
11
|
IpAddressT = TypeVar("IpAddressT", bound=IpAddress)
|
|
11
12
|
PrefixT = TypeVar("PrefixT", bound=Prefix)
|
|
13
|
+
FHRPGroupT = TypeVar("FHRPGroupT", bound=FHRPGroup)
|
|
14
|
+
FHRPGroupAssignmentT = TypeVar(
|
|
15
|
+
"FHRPGroupAssignmentT", bound=FHRPGroupAssignment,
|
|
16
|
+
)
|
|
12
17
|
|
|
13
18
|
|
|
14
19
|
def get_device_breed(device: NetboxDeviceT) -> str:
|
|
@@ -30,7 +35,17 @@ def get_device_hw(device: NetboxDeviceT) -> HardwareView:
|
|
|
30
35
|
return HardwareView("", "")
|
|
31
36
|
|
|
32
37
|
|
|
33
|
-
class NetboxAdapter(
|
|
38
|
+
class NetboxAdapter(
|
|
39
|
+
ABC,
|
|
40
|
+
Generic[
|
|
41
|
+
NetboxDeviceT,
|
|
42
|
+
InterfaceT,
|
|
43
|
+
IpAddressT,
|
|
44
|
+
PrefixT,
|
|
45
|
+
FHRPGroupT,
|
|
46
|
+
FHRPGroupAssignmentT,
|
|
47
|
+
],
|
|
48
|
+
):
|
|
34
49
|
@abstractmethod
|
|
35
50
|
def list_all_fqdns(self) -> list[str]:
|
|
36
51
|
raise NotImplementedError()
|
|
@@ -58,3 +73,15 @@ class NetboxAdapter(ABC, Generic[NetboxDeviceT, InterfaceT, IpAddressT, PrefixT]
|
|
|
58
73
|
@abstractmethod
|
|
59
74
|
def list_ipprefixes(self, prefixes: list[str]) -> list[PrefixT]:
|
|
60
75
|
raise NotImplementedError()
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def list_fhrp_group_assignments(
|
|
79
|
+
self, iface_ids: list[int],
|
|
80
|
+
) -> list[FHRPGroupAssignmentT]:
|
|
81
|
+
raise NotImplementedError()
|
|
82
|
+
|
|
83
|
+
@abstractmethod
|
|
84
|
+
def list_fhrp_groups(
|
|
85
|
+
self, ids: list[int],
|
|
86
|
+
) -> list[FHRPGroupT]:
|
|
87
|
+
raise NotImplementedError()
|
|
@@ -14,30 +14,31 @@ def get_hw(manufacturer: str, model: str, platform_name: str):
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def get_breed(manufacturer: str, model: str):
|
|
17
|
-
|
|
17
|
+
hw = get_hw(manufacturer, model, "")
|
|
18
|
+
if hw.Huawei.CE:
|
|
18
19
|
return "vrp85"
|
|
19
|
-
elif
|
|
20
|
+
elif hw.Huawei.NE:
|
|
20
21
|
return "vrp85"
|
|
21
|
-
elif
|
|
22
|
+
elif hw.Huawei:
|
|
22
23
|
return "vrp55"
|
|
23
|
-
elif
|
|
24
|
+
elif hw.H3C:
|
|
24
25
|
return "h3c"
|
|
25
|
-
elif
|
|
26
|
+
elif hw.PC.NVIDIA or hw.PC.Mellanox:
|
|
26
27
|
return "cuml2"
|
|
27
|
-
elif
|
|
28
|
+
elif hw.Juniper:
|
|
28
29
|
return "jun10"
|
|
29
|
-
elif
|
|
30
|
+
elif hw.Cisco.Nexus:
|
|
31
|
+
return "nxos"
|
|
32
|
+
elif hw.Cisco:
|
|
30
33
|
return "ios12"
|
|
31
|
-
elif
|
|
32
|
-
return "adva8"
|
|
33
|
-
elif manufacturer == "Arista":
|
|
34
|
+
elif hw.Arista:
|
|
34
35
|
return "eos4"
|
|
35
|
-
elif
|
|
36
|
+
elif hw.B4com:
|
|
36
37
|
return "bcom-os"
|
|
37
|
-
elif
|
|
38
|
+
elif hw.RouterOS:
|
|
38
39
|
return "routeros"
|
|
39
|
-
elif
|
|
40
|
+
elif hw.PC.Moxa or hw.PC.Nebius:
|
|
40
41
|
return "moxa"
|
|
41
|
-
elif
|
|
42
|
+
elif hw.PC:
|
|
42
43
|
return "pc"
|
|
43
44
|
return ""
|
|
@@ -49,7 +49,6 @@ class DeviceIp(DumpableView):
|
|
|
49
49
|
id: int
|
|
50
50
|
display: str
|
|
51
51
|
address: str
|
|
52
|
-
family: int
|
|
53
52
|
|
|
54
53
|
@property
|
|
55
54
|
def _dump__list_key(self):
|
|
@@ -131,8 +130,49 @@ def vrf_object(vrf: str | None) -> Entity | None:
|
|
|
131
130
|
_IpAddressT = TypeVar("_IpAddressT", bound=IpAddress)
|
|
132
131
|
|
|
133
132
|
|
|
133
|
+
_DeviceIPT = TypeVar("_DeviceIPT", bound=DeviceIp)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@dataclass
|
|
137
|
+
class FHRPGroup(Generic[_DeviceIPT]):
|
|
138
|
+
id: int
|
|
139
|
+
group_id: int
|
|
140
|
+
display: str
|
|
141
|
+
protocol: str
|
|
142
|
+
description: str
|
|
143
|
+
|
|
144
|
+
name: str
|
|
145
|
+
auth_type: str | None
|
|
146
|
+
auth_key: str
|
|
147
|
+
tags: list[EntityWithSlug]
|
|
148
|
+
custom_fields: dict[str, Any]
|
|
149
|
+
ip_addresses: list[_DeviceIPT]
|
|
150
|
+
comments: str | None = None
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
_FHRPGroupT = TypeVar("_FHRPGroupT", bound=FHRPGroup)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@dataclass
|
|
157
|
+
class FHRPGroupAssignment(Generic[_FHRPGroupT]):
|
|
158
|
+
id: int
|
|
159
|
+
display: str
|
|
160
|
+
priority: int
|
|
161
|
+
group: _FHRPGroupT
|
|
162
|
+
fhrp_group_id: int
|
|
163
|
+
|
|
164
|
+
interface_type: str | None
|
|
165
|
+
interface_id: int | None
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
_FHRPGroupAssignmentT = TypeVar(
|
|
169
|
+
"_FHRPGroupAssignmentT",
|
|
170
|
+
bound=FHRPGroupAssignment,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
134
174
|
@dataclass
|
|
135
|
-
class Interface(Entity, Generic[_IpAddressT]):
|
|
175
|
+
class Interface(Entity, Generic[_IpAddressT, _FHRPGroupAssignmentT]):
|
|
136
176
|
device: Entity
|
|
137
177
|
enabled: bool
|
|
138
178
|
description: str
|
|
@@ -143,13 +183,17 @@ class Interface(Entity, Generic[_IpAddressT]):
|
|
|
143
183
|
tagged_vlans: Optional[List[InterfaceVlan]]
|
|
144
184
|
tags: List[EntityWithSlug] = field(default_factory=list)
|
|
145
185
|
display: str = ""
|
|
146
|
-
ip_addresses: List[_IpAddressT] = field(default_factory=list)
|
|
147
186
|
vrf: Optional[Entity] = None
|
|
148
187
|
mtu: int | None = None
|
|
149
188
|
lag: Entity | None = None
|
|
150
189
|
lag_min_links: int | None = None
|
|
151
190
|
speed: int | None = None
|
|
152
191
|
|
|
192
|
+
ip_addresses: List[_IpAddressT] = field(default_factory=list)
|
|
193
|
+
count_ipaddresses: int = 0
|
|
194
|
+
fhrp_groups: List[_FHRPGroupAssignmentT] = field(default_factory=list)
|
|
195
|
+
count_fhrp_groups: int = 0
|
|
196
|
+
|
|
153
197
|
def add_addr(self, address_mask: str, vrf: str | None) -> None:
|
|
154
198
|
addr = ip_interface(address_mask)
|
|
155
199
|
|
|
@@ -183,7 +227,7 @@ _InterfaceT = TypeVar("_InterfaceT", bound=Interface)
|
|
|
183
227
|
|
|
184
228
|
|
|
185
229
|
@dataclass
|
|
186
|
-
class NetboxDevice(Entity, Generic[_InterfaceT]):
|
|
230
|
+
class NetboxDevice(Entity, Generic[_InterfaceT, _DeviceIPT]):
|
|
187
231
|
url: str
|
|
188
232
|
storage: Storage
|
|
189
233
|
|
|
@@ -199,9 +243,9 @@ class NetboxDevice(Entity, Generic[_InterfaceT]):
|
|
|
199
243
|
position: Optional[float]
|
|
200
244
|
face: Optional[Label]
|
|
201
245
|
status: Label
|
|
202
|
-
primary_ip: Optional[
|
|
203
|
-
primary_ip4: Optional[
|
|
204
|
-
primary_ip6: Optional[
|
|
246
|
+
primary_ip: Optional[_DeviceIPT]
|
|
247
|
+
primary_ip4: Optional[_DeviceIPT]
|
|
248
|
+
primary_ip6: Optional[_DeviceIPT]
|
|
205
249
|
tags: List[EntityWithSlug]
|
|
206
250
|
custom_fields: Dict[str, Any]
|
|
207
251
|
created: datetime
|
|
@@ -9,13 +9,19 @@ from annet.adapters.netbox.common.query import NetboxQuery, FIELD_VALUE_SEPARATO
|
|
|
9
9
|
from annet.adapters.netbox.common.storage_opts import NetboxStorageOpts
|
|
10
10
|
from annet.storage import Storage
|
|
11
11
|
from .adapter import NetboxAdapter
|
|
12
|
-
from .models import
|
|
12
|
+
from .models import (
|
|
13
|
+
IpAddress, Interface, NetboxDevice, Prefix, FHRPGroup, FHRPGroupAssignment,
|
|
14
|
+
)
|
|
13
15
|
|
|
14
16
|
logger = getLogger(__name__)
|
|
15
17
|
NetboxDeviceT = TypeVar("NetboxDeviceT", bound=NetboxDevice)
|
|
16
18
|
InterfaceT = TypeVar("InterfaceT", bound=Interface)
|
|
17
19
|
IpAddressT = TypeVar("IpAddressT", bound=IpAddress)
|
|
18
20
|
PrefixT = TypeVar("PrefixT", bound=Prefix)
|
|
21
|
+
FHRPGroupT = TypeVar("FHRPGroupT", bound=FHRPGroup)
|
|
22
|
+
FHRPGroupAssignmentT = TypeVar(
|
|
23
|
+
"FHRPGroupAssignmentT", bound=FHRPGroupAssignment,
|
|
24
|
+
)
|
|
19
25
|
|
|
20
26
|
|
|
21
27
|
class BaseNetboxStorage(
|
|
@@ -25,6 +31,8 @@ class BaseNetboxStorage(
|
|
|
25
31
|
InterfaceT,
|
|
26
32
|
IpAddressT,
|
|
27
33
|
PrefixT,
|
|
34
|
+
FHRPGroupT,
|
|
35
|
+
FHRPGroupAssignmentT,
|
|
28
36
|
],
|
|
29
37
|
):
|
|
30
38
|
"""
|
|
@@ -58,7 +66,7 @@ class BaseNetboxStorage(
|
|
|
58
66
|
token: str,
|
|
59
67
|
ssl_context: Optional[ssl.SSLContext],
|
|
60
68
|
threads: int,
|
|
61
|
-
) -> NetboxAdapter[NetboxDeviceT, InterfaceT, IpAddressT, PrefixT]:
|
|
69
|
+
) -> NetboxAdapter[NetboxDeviceT, InterfaceT, IpAddressT, PrefixT, FHRPGroupT, FHRPGroupAssignmentT]:
|
|
62
70
|
raise NotImplementedError()
|
|
63
71
|
|
|
64
72
|
def __enter__(self):
|
|
@@ -129,10 +137,22 @@ class BaseNetboxStorage(
|
|
|
129
137
|
interfaces = self.netbox.list_interfaces_by_devices(list(device_mapping))
|
|
130
138
|
for interface in interfaces:
|
|
131
139
|
device_mapping[interface.device.id].interfaces.append(interface)
|
|
140
|
+
self._fill_interface_fhrp_groups(interfaces)
|
|
132
141
|
self._fill_interface_ipaddress(interfaces)
|
|
133
142
|
|
|
143
|
+
def _fill_interface_fhrp_groups(self, interfaces: list[InterfaceT]) -> None:
|
|
144
|
+
interface_mapping = {i.id: i for i in interfaces if i.count_fhrp_groups}
|
|
145
|
+
assignments = self.netbox.list_fhrp_group_assignments(list(interface_mapping))
|
|
146
|
+
group_ids = {r.fhrp_group_id for r in assignments}
|
|
147
|
+
groups = {
|
|
148
|
+
g.id: g for g in self.netbox.list_fhrp_groups(list(group_ids))
|
|
149
|
+
}
|
|
150
|
+
for assignment in assignments:
|
|
151
|
+
assignment.group = groups[assignment.fhrp_group_id]
|
|
152
|
+
interface_mapping[assignment.interface_id].fhrp_groups.append(assignment)
|
|
153
|
+
|
|
134
154
|
def _fill_interface_ipaddress(self, interfaces: list[InterfaceT]) -> None:
|
|
135
|
-
interface_mapping = {i.id: i for i in interfaces}
|
|
155
|
+
interface_mapping = {i.id: i for i in interfaces if i.count_ipaddresses}
|
|
136
156
|
ips = self.netbox.list_ipaddr_by_ifaces(list(interface_mapping))
|
|
137
157
|
for ip in ips:
|
|
138
158
|
interface_mapping[ip.assigned_object_id].ip_addresses.append(ip)
|
|
@@ -3,10 +3,16 @@ from datetime import datetime, timezone
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
from annet.adapters.netbox.common.models import (
|
|
6
|
-
IpAddress, NetboxDevice, Entity, Prefix, InterfaceType, Interface,
|
|
6
|
+
IpAddress, NetboxDevice, Entity, Prefix, InterfaceType, Interface,
|
|
7
|
+
IpFamily, Label, FHRPGroupAssignment, DeviceIp, FHRPGroup,
|
|
7
8
|
)
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class DeviceIpV37(DeviceIp):
|
|
13
|
+
family: int
|
|
14
|
+
|
|
15
|
+
|
|
10
16
|
@dataclass
|
|
11
17
|
class PrefixV37(Prefix):
|
|
12
18
|
site: Optional[Entity] = None
|
|
@@ -18,7 +24,17 @@ class IpAddressV37(IpAddress[PrefixV37]):
|
|
|
18
24
|
|
|
19
25
|
|
|
20
26
|
@dataclass
|
|
21
|
-
class
|
|
27
|
+
class FHRPGroupV37(FHRPGroup[DeviceIpV37]):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class FHRPGroupAssignmentV37(FHRPGroupAssignment[FHRPGroupV37]):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class InterfaceV37(Interface[IpAddressV37, FHRPGroupAssignmentV37]):
|
|
22
38
|
def _add_new_addr(self, address_mask: str, vrf: Entity | None, family: IpFamily) -> None:
|
|
23
39
|
self.ip_addresses.append(IpAddressV37(
|
|
24
40
|
id=0,
|
|
@@ -36,7 +52,7 @@ class InterfaceV37(Interface[IpAddressV37]):
|
|
|
36
52
|
|
|
37
53
|
|
|
38
54
|
@dataclass
|
|
39
|
-
class NetboxDeviceV37(NetboxDevice[InterfaceV37]):
|
|
55
|
+
class NetboxDeviceV37(NetboxDevice[InterfaceV37, DeviceIpV37]):
|
|
40
56
|
device_role: Entity
|
|
41
57
|
|
|
42
58
|
def __hash__(self):
|
|
@@ -7,10 +7,15 @@ from annetbox.v37 import models as api_models, client_sync
|
|
|
7
7
|
from annet.adapters.netbox.common.adapter import NetboxAdapter, get_device_breed, get_device_hw
|
|
8
8
|
from annet.adapters.netbox.common.storage_base import BaseNetboxStorage
|
|
9
9
|
from annet.storage import Storage
|
|
10
|
-
from .models import
|
|
10
|
+
from .models import (
|
|
11
|
+
IpAddressV37, NetboxDeviceV37, InterfaceV37, PrefixV37,
|
|
12
|
+
FHRPGroupAssignmentV37, FHRPGroupV37,
|
|
13
|
+
)
|
|
11
14
|
|
|
12
15
|
|
|
13
|
-
class NetboxV37Adapter(NetboxAdapter[
|
|
16
|
+
class NetboxV37Adapter(NetboxAdapter[
|
|
17
|
+
NetboxDeviceV37, InterfaceV37, IpAddressV37, PrefixV37, FHRPGroupV37, FHRPGroupAssignmentV37,
|
|
18
|
+
]):
|
|
14
19
|
def __init__(
|
|
15
20
|
self,
|
|
16
21
|
storage: Storage,
|
|
@@ -37,6 +42,7 @@ class NetboxV37Adapter(NetboxAdapter[NetboxDeviceV37, InterfaceV37, IpAddressV37
|
|
|
37
42
|
list[InterfaceV37],
|
|
38
43
|
recipe=[
|
|
39
44
|
link_constant(P[InterfaceV37].ip_addresses, factory=list),
|
|
45
|
+
link_constant(P[InterfaceV37].fhrp_groups, factory=list),
|
|
40
46
|
link_constant(P[InterfaceV37].lag_min_links, value=None),
|
|
41
47
|
]
|
|
42
48
|
)
|
|
@@ -51,6 +57,18 @@ class NetboxV37Adapter(NetboxAdapter[NetboxDeviceV37, InterfaceV37, IpAddressV37
|
|
|
51
57
|
list[api_models.Prefix],
|
|
52
58
|
list[PrefixV37],
|
|
53
59
|
)
|
|
60
|
+
self.convert_fhrp_group_assignments = get_converter(
|
|
61
|
+
list[api_models.FHRPGroupAssignmentBrief],
|
|
62
|
+
list[FHRPGroupAssignmentV37],
|
|
63
|
+
recipe=[
|
|
64
|
+
link_constant(P[FHRPGroupAssignmentV37].group, value=None),
|
|
65
|
+
link_function(lambda model: model.group.id, P[FHRPGroupAssignmentV37].fhrp_group_id),
|
|
66
|
+
]
|
|
67
|
+
)
|
|
68
|
+
self.convert_fhrp_groups = get_converter(
|
|
69
|
+
list[api_models.FHRPGroup],
|
|
70
|
+
list[FHRPGroupV37],
|
|
71
|
+
)
|
|
54
72
|
|
|
55
73
|
def list_all_fqdns(self) -> list[str]:
|
|
56
74
|
return [
|
|
@@ -79,13 +97,27 @@ class NetboxV37Adapter(NetboxAdapter[NetboxDeviceV37, InterfaceV37, IpAddressV37
|
|
|
79
97
|
def list_ipprefixes(self, prefixes: list[str]) -> list[PrefixV37]:
|
|
80
98
|
return self.convert_ip_prefixes(self.netbox.ipam_all_prefixes(prefix=prefixes).results)
|
|
81
99
|
|
|
100
|
+
def list_fhrp_group_assignments(
|
|
101
|
+
self, iface_ids: list[int],
|
|
102
|
+
) -> list[FHRPGroupAssignmentV37]:
|
|
103
|
+
raw_assignments = self.netbox.ipam_all_fhrp_group_assignments_by_interface(
|
|
104
|
+
interface_id=iface_ids,
|
|
105
|
+
)
|
|
106
|
+
return self.convert_fhrp_group_assignments(raw_assignments.results)
|
|
107
|
+
|
|
108
|
+
def list_fhrp_groups(self, ids: list[int]) -> list[FHRPGroupV37]:
|
|
109
|
+
raw_groups = self.netbox.ipam_all_fhrp_groups_by_id(id=list(ids))
|
|
110
|
+
return self.convert_fhrp_groups(raw_groups.results)
|
|
111
|
+
|
|
82
112
|
|
|
83
|
-
class NetboxStorageV37(BaseNetboxStorage[
|
|
113
|
+
class NetboxStorageV37(BaseNetboxStorage[
|
|
114
|
+
NetboxDeviceV37, InterfaceV37, IpAddressV37, PrefixV37, FHRPGroupV37, FHRPGroupAssignmentV37,
|
|
115
|
+
]):
|
|
84
116
|
def _init_adapter(
|
|
85
117
|
self,
|
|
86
118
|
url: str,
|
|
87
119
|
token: str,
|
|
88
120
|
ssl_context: ssl.SSLContext | None,
|
|
89
121
|
threads: int,
|
|
90
|
-
) -> NetboxAdapter[NetboxDeviceV37, InterfaceV37, IpAddressV37, PrefixV37]:
|
|
122
|
+
) -> NetboxAdapter[NetboxDeviceV37, InterfaceV37, IpAddressV37, PrefixV37, FHRPGroupV37, FHRPGroupAssignmentV37]:
|
|
91
123
|
return NetboxV37Adapter(self, url, token, ssl_context, threads)
|
|
@@ -2,7 +2,9 @@ from dataclasses import dataclass
|
|
|
2
2
|
from typing import Optional
|
|
3
3
|
import warnings
|
|
4
4
|
from datetime import datetime, timezone
|
|
5
|
-
from annet.adapters.netbox.common.models import Entity, Interface,
|
|
5
|
+
from annet.adapters.netbox.common.models import Entity, Interface, \
|
|
6
|
+
InterfaceType, IpAddress, Label, NetboxDevice, DeviceIp, IpFamily, Prefix, \
|
|
7
|
+
FHRPGroupAssignment, FHRPGroup
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
@dataclass
|
|
@@ -16,7 +18,22 @@ class IpAddressV41(IpAddress[PrefixV41]):
|
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
@dataclass
|
|
19
|
-
class
|
|
21
|
+
class DeviceIpV41(DeviceIp):
|
|
22
|
+
family: IpFamily
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class FHRPGroupV41(FHRPGroup[DeviceIpV41]):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class FHRPGroupAssignmentV41(FHRPGroupAssignment[FHRPGroupV41]):
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class InterfaceV41(Interface[IpAddressV41, FHRPGroupAssignmentV41]):
|
|
20
37
|
def _add_new_addr(self, address_mask: str, vrf: Entity | None, family: IpFamily) -> None:
|
|
21
38
|
self.ip_addresses.append(IpAddressV41(
|
|
22
39
|
id=0,
|
|
@@ -34,19 +51,8 @@ class InterfaceV41(Interface[IpAddressV41]):
|
|
|
34
51
|
|
|
35
52
|
|
|
36
53
|
@dataclass
|
|
37
|
-
class DeviceIpV41
|
|
38
|
-
id: int
|
|
39
|
-
display: str
|
|
40
|
-
address: str
|
|
41
|
-
family: IpFamily
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@dataclass
|
|
45
|
-
class NetboxDeviceV41(NetboxDevice[InterfaceV41]):
|
|
54
|
+
class NetboxDeviceV41(NetboxDevice[InterfaceV41, DeviceIpV41]):
|
|
46
55
|
role: Entity
|
|
47
|
-
primary_ip: Optional[DeviceIpV41]
|
|
48
|
-
primary_ip4: Optional[DeviceIpV41]
|
|
49
|
-
primary_ip6: Optional[DeviceIpV41]
|
|
50
56
|
|
|
51
57
|
@property
|
|
52
58
|
def device_role(self):
|
|
@@ -6,11 +6,17 @@ from annetbox.v41 import models as api_models
|
|
|
6
6
|
|
|
7
7
|
from annet.adapters.netbox.common.adapter import NetboxAdapter, get_device_breed, get_device_hw
|
|
8
8
|
from annet.adapters.netbox.common.storage_base import BaseNetboxStorage
|
|
9
|
-
from annet.adapters.netbox.v41.models import
|
|
9
|
+
from annet.adapters.netbox.v41.models import (
|
|
10
|
+
InterfaceV41, IpAddressV41, NetboxDeviceV41, PrefixV41,
|
|
11
|
+
FHRPGroupV41, FHRPGroupAssignmentV41,
|
|
12
|
+
)
|
|
10
13
|
from annet.storage import Storage
|
|
11
14
|
|
|
12
15
|
|
|
13
|
-
class NetboxV41Adapter(NetboxAdapter[
|
|
16
|
+
class NetboxV41Adapter(NetboxAdapter[
|
|
17
|
+
NetboxDeviceV41, InterfaceV41, IpAddressV41, PrefixV41,
|
|
18
|
+
FHRPGroupV41, FHRPGroupAssignmentV41
|
|
19
|
+
]):
|
|
14
20
|
def __init__(
|
|
15
21
|
self,
|
|
16
22
|
storage: Storage,
|
|
@@ -37,6 +43,7 @@ class NetboxV41Adapter(NetboxAdapter[NetboxDeviceV41, InterfaceV41, IpAddressV41
|
|
|
37
43
|
list[InterfaceV41],
|
|
38
44
|
recipe=[
|
|
39
45
|
link_constant(P[InterfaceV41].ip_addresses, factory=list),
|
|
46
|
+
link_constant(P[InterfaceV41].fhrp_groups, factory=list),
|
|
40
47
|
link_constant(P[InterfaceV41].lag_min_links, value=None),
|
|
41
48
|
]
|
|
42
49
|
)
|
|
@@ -51,6 +58,18 @@ class NetboxV41Adapter(NetboxAdapter[NetboxDeviceV41, InterfaceV41, IpAddressV41
|
|
|
51
58
|
list[api_models.Prefix],
|
|
52
59
|
list[PrefixV41],
|
|
53
60
|
)
|
|
61
|
+
self.convert_fhrp_group_assignments = get_converter(
|
|
62
|
+
list[api_models.FHRPGroupAssignmentBrief],
|
|
63
|
+
list[FHRPGroupAssignmentV41],
|
|
64
|
+
recipe=[
|
|
65
|
+
link_constant(P[FHRPGroupAssignmentV41].group, value=None),
|
|
66
|
+
link_function(lambda model: model.group.id, P[FHRPGroupAssignmentV41].fhrp_group_id),
|
|
67
|
+
]
|
|
68
|
+
)
|
|
69
|
+
self.convert_fhrp_groups = get_converter(
|
|
70
|
+
list[api_models.FHRPGroup],
|
|
71
|
+
list[FHRPGroupV41],
|
|
72
|
+
)
|
|
54
73
|
|
|
55
74
|
def list_all_fqdns(self) -> list[str]:
|
|
56
75
|
return [
|
|
@@ -79,13 +98,28 @@ class NetboxV41Adapter(NetboxAdapter[NetboxDeviceV41, InterfaceV41, IpAddressV41
|
|
|
79
98
|
def list_ipprefixes(self, prefixes: list[str]) -> list[PrefixV41]:
|
|
80
99
|
return self.convert_ip_prefixes(self.netbox.ipam_all_prefixes(prefix=prefixes).results)
|
|
81
100
|
|
|
101
|
+
def list_fhrp_group_assignments(
|
|
102
|
+
self, iface_ids: list[int],
|
|
103
|
+
) -> list[FHRPGroupAssignmentV41]:
|
|
104
|
+
raw_assignments = self.netbox.ipam_all_fhrp_group_assignments_by_interface(
|
|
105
|
+
interface_id=iface_ids,
|
|
106
|
+
)
|
|
107
|
+
return self.convert_fhrp_group_assignments(raw_assignments.results)
|
|
108
|
+
|
|
109
|
+
def list_fhrp_groups(self, ids: list[int]) -> list[FHRPGroupV41]:
|
|
110
|
+
raw_groups = self.netbox.ipam_all_fhrp_groups_by_id(id=list(ids))
|
|
111
|
+
return self.convert_fhrp_groups(raw_groups.results)
|
|
112
|
+
|
|
82
113
|
|
|
83
|
-
class NetboxStorageV41(BaseNetboxStorage[
|
|
114
|
+
class NetboxStorageV41(BaseNetboxStorage[
|
|
115
|
+
NetboxDeviceV41, InterfaceV41, IpAddressV41, PrefixV41,
|
|
116
|
+
FHRPGroupV41, FHRPGroupAssignmentV41
|
|
117
|
+
]):
|
|
84
118
|
def _init_adapter(
|
|
85
119
|
self,
|
|
86
120
|
url: str,
|
|
87
121
|
token: str,
|
|
88
122
|
ssl_context: ssl.SSLContext | None,
|
|
89
123
|
threads: int,
|
|
90
|
-
) -> NetboxAdapter[NetboxDeviceV41, InterfaceV41, IpAddressV41, PrefixV41]:
|
|
124
|
+
) -> NetboxAdapter[NetboxDeviceV41, InterfaceV41, IpAddressV41, PrefixV41, FHRPGroupV41, FHRPGroupAssignmentV41]:
|
|
91
125
|
return NetboxV41Adapter(self, url, token, ssl_context, threads)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from datetime import datetime, timezone
|
|
3
3
|
from typing import Optional
|
|
4
|
-
from annet.adapters.netbox.common.models import InterfaceType, IpFamily, Label,
|
|
5
|
-
|
|
4
|
+
from annet.adapters.netbox.common.models import InterfaceType, IpFamily, Label, \
|
|
5
|
+
Prefix, Entity, Interface, IpAddress
|
|
6
|
+
from annet.adapters.netbox.v41.models import InterfaceV41, IpAddressV41, \
|
|
7
|
+
NetboxDeviceV41, FHRPGroupAssignmentV41
|
|
6
8
|
import annetbox.v42.models
|
|
7
9
|
|
|
8
10
|
|
|
@@ -19,12 +21,12 @@ class PrefixV42(Prefix):
|
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
@dataclass
|
|
22
|
-
class IpAddressV42(
|
|
24
|
+
class IpAddressV42(IpAddress[PrefixV42]):
|
|
23
25
|
prefix: Optional[PrefixV42] = None
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
@dataclass
|
|
27
|
-
class InterfaceV42(
|
|
29
|
+
class InterfaceV42(Interface[IpAddressV42, FHRPGroupAssignmentV41]):
|
|
28
30
|
def _add_new_addr(self, address_mask: str, vrf: Entity | None, family: IpFamily) -> None:
|
|
29
31
|
self.ip_addresses.append(IpAddressV42(
|
|
30
32
|
id=0,
|
|
@@ -9,11 +9,15 @@ from annetbox.v42 import models as api_models
|
|
|
9
9
|
from annet.adapters.netbox.common.adapter import NetboxAdapter, get_device_breed, get_device_hw
|
|
10
10
|
from annet.adapters.netbox.common.storage_base import BaseNetboxStorage
|
|
11
11
|
from annet.adapters.netbox.common.storage_opts import NetboxStorageOpts
|
|
12
|
+
from annet.adapters.netbox.v41.models import FHRPGroupAssignmentV41, FHRPGroupV41
|
|
12
13
|
from annet.adapters.netbox.v42.models import InterfaceV42, NetboxDeviceV42, PrefixV42, IpAddressV42, Vlan, Vrf
|
|
13
14
|
from annet.storage import Storage
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
class NetboxV42Adapter(NetboxAdapter[
|
|
17
|
+
class NetboxV42Adapter(NetboxAdapter[
|
|
18
|
+
NetboxDeviceV42, InterfaceV42, IpAddressV42, PrefixV42,
|
|
19
|
+
FHRPGroupV41, FHRPGroupAssignmentV41,
|
|
20
|
+
]):
|
|
17
21
|
def __init__(
|
|
18
22
|
self,
|
|
19
23
|
storage: Storage,
|
|
@@ -40,6 +44,7 @@ class NetboxV42Adapter(NetboxAdapter[NetboxDeviceV42, InterfaceV42, IpAddressV42
|
|
|
40
44
|
list[InterfaceV42],
|
|
41
45
|
recipe=[
|
|
42
46
|
link_constant(P[InterfaceV42].ip_addresses, factory=list),
|
|
47
|
+
link_constant(P[InterfaceV42].fhrp_groups, factory=list),
|
|
43
48
|
link_constant(P[InterfaceV42].lag_min_links, value=None),
|
|
44
49
|
]
|
|
45
50
|
)
|
|
@@ -54,6 +59,18 @@ class NetboxV42Adapter(NetboxAdapter[NetboxDeviceV42, InterfaceV42, IpAddressV42
|
|
|
54
59
|
list[api_models.Prefix],
|
|
55
60
|
list[PrefixV42],
|
|
56
61
|
)
|
|
62
|
+
self.convert_fhrp_group_assignments = get_converter(
|
|
63
|
+
list[api_models.FHRPGroupAssignmentBrief],
|
|
64
|
+
list[FHRPGroupAssignmentV41],
|
|
65
|
+
recipe=[
|
|
66
|
+
link_constant(P[FHRPGroupAssignmentV41].group, value=None),
|
|
67
|
+
link_function(lambda model: model.group.id, P[FHRPGroupAssignmentV41].fhrp_group_id),
|
|
68
|
+
]
|
|
69
|
+
)
|
|
70
|
+
self.convert_fhrp_groups = get_converter(
|
|
71
|
+
list[api_models.FHRPGroup],
|
|
72
|
+
list[FHRPGroupV41],
|
|
73
|
+
)
|
|
57
74
|
|
|
58
75
|
def list_all_fqdns(self) -> list[str]:
|
|
59
76
|
return [
|
|
@@ -88,8 +105,23 @@ class NetboxV42Adapter(NetboxAdapter[NetboxDeviceV42, InterfaceV42, IpAddressV42
|
|
|
88
105
|
def list_all_vlans(self) -> list[Vlan]:
|
|
89
106
|
return self.netbox.ipam_all_vlans().results
|
|
90
107
|
|
|
108
|
+
def list_fhrp_group_assignments(
|
|
109
|
+
self, iface_ids: list[int],
|
|
110
|
+
) -> list[FHRPGroupAssignmentV41]:
|
|
111
|
+
raw_assignments = self.netbox.ipam_all_fhrp_group_assignments_by_interface(
|
|
112
|
+
interface_id=iface_ids,
|
|
113
|
+
)
|
|
114
|
+
return self.convert_fhrp_group_assignments(raw_assignments.results)
|
|
115
|
+
|
|
116
|
+
def list_fhrp_groups(self, ids: list[int]) -> list[FHRPGroupV41]:
|
|
117
|
+
raw_groups = self.netbox.ipam_all_fhrp_groups_by_id(id=list(ids))
|
|
118
|
+
return self.convert_fhrp_groups(raw_groups.results)
|
|
119
|
+
|
|
91
120
|
|
|
92
|
-
class NetboxStorageV42(BaseNetboxStorage[
|
|
121
|
+
class NetboxStorageV42(BaseNetboxStorage[
|
|
122
|
+
NetboxDeviceV42, InterfaceV42, IpAddressV42, PrefixV42,
|
|
123
|
+
FHRPGroupV41, FHRPGroupAssignmentV41,
|
|
124
|
+
]):
|
|
93
125
|
netbox: NetboxV42Adapter
|
|
94
126
|
|
|
95
127
|
def __init__(self, opts: Optional[NetboxStorageOpts] = None):
|
|
@@ -103,7 +135,10 @@ class NetboxStorageV42(BaseNetboxStorage[NetboxDeviceV42, InterfaceV42, IpAddres
|
|
|
103
135
|
token: str,
|
|
104
136
|
ssl_context: ssl.SSLContext | None,
|
|
105
137
|
threads: int,
|
|
106
|
-
) -> NetboxAdapter[
|
|
138
|
+
) -> NetboxAdapter[
|
|
139
|
+
NetboxDeviceV42, InterfaceV42, IpAddressV42, PrefixV42,
|
|
140
|
+
FHRPGroupV41, FHRPGroupAssignmentV41,
|
|
141
|
+
]:
|
|
107
142
|
return NetboxV42Adapter(self, url, token, ssl_context, threads)
|
|
108
143
|
|
|
109
144
|
def resolve_all_vlans(self) -> list[Vlan]:
|
annet/hardware.py
CHANGED
|
@@ -6,7 +6,7 @@ from annet.vendors import registry_connector
|
|
|
6
6
|
from annet.connectors import Connector
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class _HardwareConnector(Connector["
|
|
9
|
+
class _HardwareConnector(Connector["HardwareProvider"]):
|
|
10
10
|
name = "Hardware"
|
|
11
11
|
ep_name = "hardware"
|
|
12
12
|
ep_by_group_only = "annet.connectors.hardware"
|
|
@@ -15,7 +15,7 @@ class _HardwareConnector(Connector["HarwareProvider"]):
|
|
|
15
15
|
hardware_connector = _HardwareConnector()
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class
|
|
18
|
+
class HardwareProvider(abc.ABC):
|
|
19
19
|
@abc.abstractmethod
|
|
20
20
|
def make_hw(self, hw_model: str, sw_version: str) -> Any:
|
|
21
21
|
pass
|
|
@@ -29,7 +29,7 @@ class HarwareProvider(abc.ABC):
|
|
|
29
29
|
pass
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
class AnnetHardwareProvider(
|
|
32
|
+
class AnnetHardwareProvider(HardwareProvider):
|
|
33
33
|
def make_hw(self, hw_model: str, sw_version: str) -> HardwareView:
|
|
34
34
|
return HardwareView(hw_model, sw_version)
|
|
35
35
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.0
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -21,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
|
|
|
21
21
|
Requires-Dist: adaptix==3.0.0b7
|
|
22
22
|
Requires-Dist: dataclass-rest==0.4
|
|
23
23
|
Provides-Extra: netbox
|
|
24
|
-
Requires-Dist: annetbox[sync]>=0.
|
|
24
|
+
Requires-Dist: annetbox[sync]>=0.6.0; extra == "netbox"
|
|
25
25
|
Dynamic: home-page
|
|
26
26
|
Dynamic: license
|
|
27
27
|
Dynamic: license-file
|
|
@@ -11,7 +11,7 @@ annet/diff.py,sha256=kD_2kxz5wc2TP10xj-BHs6IPq1yNKkXxIco8czjeC6M,9497
|
|
|
11
11
|
annet/executor.py,sha256=INlWAZFLpHurg8GTXclbSzaeSIXgZo4ccmcRulQqr88,5130
|
|
12
12
|
annet/filtering.py,sha256=ZtqxPsKdV9reZoRxtQyBg22BqyMqd-2SotYcxZ-68AQ,903
|
|
13
13
|
annet/gen.py,sha256=j6SUrhEbfVQJrF2pOuWQaaBABwABk8cYzOln78jJ320,31956
|
|
14
|
-
annet/hardware.py,sha256=
|
|
14
|
+
annet/hardware.py,sha256=O2uadehcavZ10ssPr-db3XYHK8cpbG7C7XFkO-I6r_s,1161
|
|
15
15
|
annet/implicit.py,sha256=i6UxQAQESXWlIBohNuFQuSEgvdsydRzyBu1r7nrR2F4,6083
|
|
16
16
|
annet/lib.py,sha256=4N4X6jCCrig5rk7Ua4AofrV9zK9jhzkBq57fLsfBJjw,4812
|
|
17
17
|
annet/output.py,sha256=se8EpyNS9f9kPOlOaAV0ht4DjzDoBr8F2UafiezLPYw,7743
|
|
@@ -31,26 +31,26 @@ annet/adapters/file/provider.py,sha256=3hNt0QQg46SVymLQ4Bh9G4VNYyhnB7gV5yu5OiIJp
|
|
|
31
31
|
annet/adapters/netbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
32
|
annet/adapters/netbox/provider.py,sha256=SrxW_uBLvMTqtRiYXreL6RrZK4MpxVguF2ITnYOnVHU,2226
|
|
33
33
|
annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
-
annet/adapters/netbox/common/adapter.py,sha256
|
|
34
|
+
annet/adapters/netbox/common/adapter.py,sha256=L9xFMcYk7E7w6MH8N0qdg8h-CSP4nZzrOMFlw0_33EU,2600
|
|
35
35
|
annet/adapters/netbox/common/client.py,sha256=PaxHG4W9H8_uunIwMBNYkLq4eQJYoO6p6gY-ciQs7Nc,2563
|
|
36
|
-
annet/adapters/netbox/common/manufacturer.py,sha256=
|
|
37
|
-
annet/adapters/netbox/common/models.py,sha256=
|
|
36
|
+
annet/adapters/netbox/common/manufacturer.py,sha256=9jTfzwx5XmETrjSbIJu_FhNaByaUbGQE787c5rBor-4,1137
|
|
37
|
+
annet/adapters/netbox/common/models.py,sha256=dC2jej8t6XR-AY8K_qzbYRq46Urvqefp_x1O-uAy4hk,8910
|
|
38
38
|
annet/adapters/netbox/common/query.py,sha256=kbNQSZwkjFeDArHwA8INHUauxCxYElXtNh58pZipWdo,1867
|
|
39
39
|
annet/adapters/netbox/common/status_client.py,sha256=POaqiQJ0jPcqUQH-X_fWHVnKB7TBYveNriaT0eNTlfI,769
|
|
40
|
-
annet/adapters/netbox/common/storage_base.py,sha256=
|
|
40
|
+
annet/adapters/netbox/common/storage_base.py,sha256=GVF30gV4X828MPhUOZ3HsNhWvYp0J5k6LoRFd2UOk7c,9712
|
|
41
41
|
annet/adapters/netbox/common/storage_opts.py,sha256=wfv1spElomwgVYMCgGth3SWVF0RsRgtUgq9GpFL9hJs,1520
|
|
42
42
|
annet/adapters/netbox/v24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
annet/adapters/netbox/v24/models.py,sha256=RH2ooUPHOtHT0q1ZQE7v23FgmcsGenzzSgJyft13o1k,7605
|
|
44
44
|
annet/adapters/netbox/v24/storage.py,sha256=zptzrW4aZUv_exuGw0DqQPm_kXZR3DwL4zRHYL6twTk,6219
|
|
45
45
|
annet/adapters/netbox/v37/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
-
annet/adapters/netbox/v37/models.py,sha256=
|
|
47
|
-
annet/adapters/netbox/v37/storage.py,sha256=
|
|
46
|
+
annet/adapters/netbox/v37/models.py,sha256=um19-ZHC700a7vpUiW8XMwBjxPcRe1StuchAxA3wZjY,1907
|
|
47
|
+
annet/adapters/netbox/v37/storage.py,sha256=XBYuDvNWngofXf7Kiy-V-AyGXfIszP8UQyf1N0Obq5c,5041
|
|
48
48
|
annet/adapters/netbox/v41/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
-
annet/adapters/netbox/v41/models.py,sha256=
|
|
50
|
-
annet/adapters/netbox/v41/storage.py,sha256=
|
|
49
|
+
annet/adapters/netbox/v41/models.py,sha256=iZUP0ca3t-hF_DBBJsp1JOlZEJk4CJkWsB4NxPJtrpA,2140
|
|
50
|
+
annet/adapters/netbox/v41/storage.py,sha256=kK_oyWNa_Ha2vSk66ca4Uxq9OZsep3y2XsRWrLp_L-Q,5095
|
|
51
51
|
annet/adapters/netbox/v42/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
|
-
annet/adapters/netbox/v42/models.py,sha256=
|
|
53
|
-
annet/adapters/netbox/v42/storage.py,sha256=
|
|
52
|
+
annet/adapters/netbox/v42/models.py,sha256=t8UaSfzl_8ri10VoIK1TSwjL8VRmMpJYQeS3AH01VSs,2021
|
|
53
|
+
annet/adapters/netbox/v42/storage.py,sha256=zScnvOqjPuS39vwXcE-QDkCUosBr-nafDdgFA4jzioY,6022
|
|
54
54
|
annet/annlib/__init__.py,sha256=fT1l4xV5fqqg8HPw9HqmZVN2qwS8i6X1aIm2zGDjxKY,252
|
|
55
55
|
annet/annlib/command.py,sha256=SUoMAmzo7AurMWyAiJNETdcHiwyGQe1YG9f7ZCc1gWQ,1166
|
|
56
56
|
annet/annlib/diff.py,sha256=MZ6eQAU3cadQp8KaSE6uAYFtcfMDCIe_eNuVROnYkCk,4496
|
|
@@ -199,8 +199,8 @@ annet/vendors/library/optixtrans.py,sha256=VdME69Ca4HAEgoaKN21fZxnmmsqqaxOe_HZja
|
|
|
199
199
|
annet/vendors/library/pc.py,sha256=vfv31_NPi7M-4AUDL89UcpawK2E6xvCpELA209cd1ho,1086
|
|
200
200
|
annet/vendors/library/ribbon.py,sha256=DDOBq-_-FL9dCxqXs2inEWZ-pvw-dJ-A-prA7cKMhec,1216
|
|
201
201
|
annet/vendors/library/routeros.py,sha256=iQa7m_4wjuvcgBOI9gyZwlw1BvzJfOkvUbyoEk-NI9I,1254
|
|
202
|
-
annet-3.
|
|
203
|
-
annet-3.
|
|
202
|
+
annet-3.6.0.dist-info/licenses/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
|
|
203
|
+
annet-3.6.0.dist-info/licenses/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
|
|
204
204
|
annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
205
205
|
annet_generators/example/__init__.py,sha256=OJ77uj8axc-FIyIu_Xdcnzmde3oQW5mk5qbODkhuVc8,355
|
|
206
206
|
annet_generators/example/hostname.py,sha256=RloLzNVetEoWPLITzfJ13Nk3CC0yi-cZB1RTd6dnuhI,2541
|
|
@@ -213,8 +213,8 @@ annet_generators/rpl_example/generator.py,sha256=EWah19gOH8G-QyNyWqxCqdRi0BK7GbM
|
|
|
213
213
|
annet_generators/rpl_example/items.py,sha256=HPgxScDvSqJPdz0c2SppDrH82DZYC4zUaniQwcWmh4A,1176
|
|
214
214
|
annet_generators/rpl_example/mesh.py,sha256=z_WgfDZZ4xnyh3cSf75igyH09hGvtexEVwy1gCD_DzA,288
|
|
215
215
|
annet_generators/rpl_example/route_policy.py,sha256=z6nPb0VDeQtKD1NIg9sFvmUxBD5tVs2frfNIuKdM-5c,2318
|
|
216
|
-
annet-3.
|
|
217
|
-
annet-3.
|
|
218
|
-
annet-3.
|
|
219
|
-
annet-3.
|
|
220
|
-
annet-3.
|
|
216
|
+
annet-3.6.0.dist-info/METADATA,sha256=Lz9Yyo82ATgIm12jnzzT1Ez4XVmRLuyl93IoBKNDlL8,815
|
|
217
|
+
annet-3.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
218
|
+
annet-3.6.0.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
|
|
219
|
+
annet-3.6.0.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
|
|
220
|
+
annet-3.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|