annet 3.5.1__py3-none-any.whl → 3.6.1__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.
- 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/annlib/command.py +3 -1
- annet/cli_args.py +1 -1
- annet/hardware.py +3 -3
- annet/rpl_generators/policy.py +1 -1
- annet/rulebook/juniper/iface.py +39 -0
- annet/rulebook/texts/juniper.rul +2 -0
- {annet-3.5.1.dist-info → annet-3.6.1.dist-info}/METADATA +2 -2
- {annet-3.5.1.dist-info → annet-3.6.1.dist-info}/RECORD +23 -22
- {annet-3.5.1.dist-info → annet-3.6.1.dist-info}/WHEEL +1 -1
- {annet-3.5.1.dist-info → annet-3.6.1.dist-info}/entry_points.txt +0 -0
- {annet-3.5.1.dist-info → annet-3.6.1.dist-info}/licenses/AUTHORS +0 -0
- {annet-3.5.1.dist-info → annet-3.6.1.dist-info}/licenses/LICENSE +0 -0
- {annet-3.5.1.dist-info → annet-3.6.1.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/annlib/command.py
CHANGED
|
@@ -17,7 +17,7 @@ class Question:
|
|
|
17
17
|
|
|
18
18
|
@dataclass
|
|
19
19
|
class Command:
|
|
20
|
-
cmd: str
|
|
20
|
+
cmd: str | bytes
|
|
21
21
|
questions: Optional[List[Question]] = None
|
|
22
22
|
exc_handler: Optional[List[Question]] = None
|
|
23
23
|
timeout: Optional[int] = None # total timeout
|
|
@@ -26,6 +26,8 @@ class Command:
|
|
|
26
26
|
suppress_eof: bool = False
|
|
27
27
|
|
|
28
28
|
def __str__(self) -> str:
|
|
29
|
+
if isinstance(self.cmd, bytes):
|
|
30
|
+
return self.cmd.decode("utf-8")
|
|
29
31
|
return self.cmd
|
|
30
32
|
|
|
31
33
|
|
annet/cli_args.py
CHANGED
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
|
|
annet/rpl_generators/policy.py
CHANGED
|
@@ -1048,7 +1048,7 @@ class RoutingPolicyGenerator(PartialGenerator, ABC):
|
|
|
1048
1048
|
yield "delete", "extcommunity", "rt", "all"
|
|
1049
1049
|
added.extend(action.value.replaced)
|
|
1050
1050
|
|
|
1051
|
-
|
|
1051
|
+
added.extend(action.value.added)
|
|
1052
1052
|
for member_name in added:
|
|
1053
1053
|
typename = self._iosxr_community_type_str(communities[member_name].type)
|
|
1054
1054
|
yield "set", "extcommunity", typename, member_name, "additive"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import ipaddress
|
|
2
|
+
from annet.annlib.types import Op
|
|
3
|
+
from annet.rulebook import common
|
|
4
|
+
from annet.rulebook.common import DiffItem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def ipv6_addr(old, new, diff_pre, _pops):
|
|
8
|
+
"""
|
|
9
|
+
Приводим все ipv6-адреса в объекты IPv6Interface и далее сравниваем
|
|
10
|
+
"""
|
|
11
|
+
address_new_line = [a for a in map(_parse_ipv6, new) if a]
|
|
12
|
+
address_old_line = [a for a in map(_parse_ipv6, old) if a]
|
|
13
|
+
|
|
14
|
+
ret = []
|
|
15
|
+
for item in common.default_diff(old, new, diff_pre, _pops):
|
|
16
|
+
# Проверяем адрес помеченный под снос на наличии в новом списке
|
|
17
|
+
if item.op == Op.REMOVED and _parse_ipv6(item.row) in address_new_line:
|
|
18
|
+
result_item = DiffItem(Op.AFFECTED, item.row, item.children, item.diff_pre)
|
|
19
|
+
# Проверяем адрес помеченный для добавления на наличии в старом списке
|
|
20
|
+
elif item.op == Op.ADDED and _parse_ipv6(item.row) in address_old_line:
|
|
21
|
+
result_item = None
|
|
22
|
+
# Остальное без изменений
|
|
23
|
+
else:
|
|
24
|
+
result_item = item
|
|
25
|
+
if result_item:
|
|
26
|
+
ret.append(result_item)
|
|
27
|
+
return ret
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _parse_ipv6(row):
|
|
31
|
+
"""
|
|
32
|
+
Парсит IPv6-интерфейс из строки, предполагая, что адрес находится на втором месте.
|
|
33
|
+
Возвращает объект IPv6Interface или None.
|
|
34
|
+
"""
|
|
35
|
+
if row:
|
|
36
|
+
parts = row.split()
|
|
37
|
+
if len(parts) > 1:
|
|
38
|
+
return ipaddress.IPv6Interface(parts[1])
|
|
39
|
+
return None
|
annet/rulebook/texts/juniper.rul
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.1
|
|
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
|
|
@@ -3,7 +3,7 @@ annet/annet.py,sha256=vyQ__n5hkjub3aWO8tksHPoUSbTeK97MyMcR_U8_BSU,1016
|
|
|
3
3
|
annet/argparse.py,sha256=v1MfhjR0B8qahza0WinmXClpR8UiDFhmwDDWtNroJPA,12855
|
|
4
4
|
annet/bgp_models.py,sha256=n29UBUbmeO7xdY0hyMi1VxkVmeSEZH8ZzYPfZmG3U7w,12502
|
|
5
5
|
annet/cli.py,sha256=shq3hHzrTxFL3x1_zTOR43QHo0JYs8QSwyOvGtL86Co,12733
|
|
6
|
-
annet/cli_args.py,sha256=
|
|
6
|
+
annet/cli_args.py,sha256=d0WuGiZfe42-nMvurX1bOb3iUMg0TSK-hxk8J1THxSY,13728
|
|
7
7
|
annet/connectors.py,sha256=aoiDVLPizx8CW2p8SAwGCzyO_WW8H9xc2aujbGC4bDg,4882
|
|
8
8
|
annet/deploy.py,sha256=ZTZcomYm2KJkKMyG6XzZaAMPr-Tduwcv67BhsoLARkY,7673
|
|
9
9
|
annet/deploy_ui.py,sha256=XsN1i7E9cNp1SAf1YBwhEBuwN91MvlNMSrLhnQrumA8,28672
|
|
@@ -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,28 +31,28 @@ 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
|
-
annet/annlib/command.py,sha256=
|
|
55
|
+
annet/annlib/command.py,sha256=GsgzQ8oFiHFan1Tfyo340rWgfhyU4_sCKJGhBm2jG6Y,1258
|
|
56
56
|
annet/annlib/diff.py,sha256=MZ6eQAU3cadQp8KaSE6uAYFtcfMDCIe_eNuVROnYkCk,4496
|
|
57
57
|
annet/annlib/errors.py,sha256=jBcSFzY6Vj-FxR__vqjFm-87AwYQ0xHuAopTirii5AU,287
|
|
58
58
|
annet/annlib/filter_acl.py,sha256=ZJvNpSwE5MzJS_sKLenQpZgTuM-IrngwcbukQRq90do,7195
|
|
@@ -113,7 +113,7 @@ annet/rpl_generators/community.py,sha256=vvjBupVrMn3B2OFDLXxgUq0QQBpp5TWdlJOAYpU
|
|
|
113
113
|
annet/rpl_generators/cumulus_frr.py,sha256=eABVCpn4ru_BFQJDcPZZEi1EL1cBwfNhtC1mDmC6BwA,21548
|
|
114
114
|
annet/rpl_generators/entities.py,sha256=uO78iG2zHAGra5DqzpfnBgoc6slHEc6wDLvlnoySvJc,3750
|
|
115
115
|
annet/rpl_generators/execute.py,sha256=wS6e6fwcPWywsHB0gBMqZ17eF0s4YOBgDgwPB_cr5Rw,431
|
|
116
|
-
annet/rpl_generators/policy.py,sha256=
|
|
116
|
+
annet/rpl_generators/policy.py,sha256=8ScDUy4zBd-358Bbkd1FZ3EpGsbLzgu6JbjfOzGMDtQ,52341
|
|
117
117
|
annet/rpl_generators/prefix_lists.py,sha256=sxTPeOJufwogguuhjjMbrGSgW3wm2HNboX9tN3qLitU,6910
|
|
118
118
|
annet/rpl_generators/rd.py,sha256=-l0Dy-t1lIFCLLIzRb_okwU1jxr_kNEds92FyoVS7qs,1999
|
|
119
119
|
annet/rulebook/__init__.py,sha256=AmcqrLYaoU1-sO2vmtjWZbzsZ44_w7nXncoEVa_hpyk,3997
|
|
@@ -142,6 +142,7 @@ annet/rulebook/huawei/iface.py,sha256=DvLtQ7tfbDQWFmIYV4lxfih13Tdrt24L4-ZS29mCku
|
|
|
142
142
|
annet/rulebook/huawei/misc.py,sha256=Rpwhtm42IgcueDq4K6VOzN2qORoIDYh42Jb7iWL8AII,14424
|
|
143
143
|
annet/rulebook/huawei/vlandb.py,sha256=B4BEUhZetjsNNhIJOp9cXtJSAYKMOgQucO8oAxSkRI0,4658
|
|
144
144
|
annet/rulebook/juniper/__init__.py,sha256=3LVrE0eXVRkEiVDTLGt0mhPjOY9MEUbx8NRY-7zPZcc,5377
|
|
145
|
+
annet/rulebook/juniper/iface.py,sha256=zs0Mz-Hd9F3L_99vjUbXV2FGAkUphbrbTyUpNhISiHI,1613
|
|
145
146
|
annet/rulebook/nexus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
146
147
|
annet/rulebook/nexus/iface.py,sha256=aeog9iSGT2zZ78tsGlrRcfgfOv7yW3jLwryXqdeplRw,2923
|
|
147
148
|
annet/rulebook/routeros/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -165,7 +166,7 @@ annet/rulebook/texts/iosxr.deploy,sha256=Hu0NkcGv3f1CWUrnbzI3eQOPXJxtH4NNOPRV68I
|
|
|
165
166
|
annet/rulebook/texts/iosxr.order,sha256=gUp6XHwzqkDsArCUAwtx3rR1qlGfYsHy2vP9oZN2oDk,1922
|
|
166
167
|
annet/rulebook/texts/iosxr.rul,sha256=MhIoIbOrfqisbyprZLy86DvO4rl6LtPESFnDU9nQUY0,2974
|
|
167
168
|
annet/rulebook/texts/juniper.order,sha256=PpxmcCgeaeP3TyYe3BWvtb24MKYV_BujjCH3HD4lsc8,256
|
|
168
|
-
annet/rulebook/texts/juniper.rul,sha256=
|
|
169
|
+
annet/rulebook/texts/juniper.rul,sha256=wwYGDycZNvQBWxYmxMcOb9rAskidBL-G4ewXhrhX-cQ,2825
|
|
169
170
|
annet/rulebook/texts/nexus.deploy,sha256=9YNAQEw7aQxtYZJbE-dMD6qJrTzs_G92Ifrx3Ft4Wn4,1120
|
|
170
171
|
annet/rulebook/texts/nexus.order,sha256=AZMKCD5Zf_mBOlE36aMDvO4w5rdbepTz1Dsyv7xP9Qs,1834
|
|
171
172
|
annet/rulebook/texts/nexus.rul,sha256=veixbi_ztbX6OMV_WjdkgpEXa47yDxOkPE0YQ6r4wqs,2558
|
|
@@ -199,8 +200,8 @@ annet/vendors/library/optixtrans.py,sha256=VdME69Ca4HAEgoaKN21fZxnmmsqqaxOe_HZja
|
|
|
199
200
|
annet/vendors/library/pc.py,sha256=vfv31_NPi7M-4AUDL89UcpawK2E6xvCpELA209cd1ho,1086
|
|
200
201
|
annet/vendors/library/ribbon.py,sha256=DDOBq-_-FL9dCxqXs2inEWZ-pvw-dJ-A-prA7cKMhec,1216
|
|
201
202
|
annet/vendors/library/routeros.py,sha256=iQa7m_4wjuvcgBOI9gyZwlw1BvzJfOkvUbyoEk-NI9I,1254
|
|
202
|
-
annet-3.
|
|
203
|
-
annet-3.
|
|
203
|
+
annet-3.6.1.dist-info/licenses/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
|
|
204
|
+
annet-3.6.1.dist-info/licenses/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
|
|
204
205
|
annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
205
206
|
annet_generators/example/__init__.py,sha256=OJ77uj8axc-FIyIu_Xdcnzmde3oQW5mk5qbODkhuVc8,355
|
|
206
207
|
annet_generators/example/hostname.py,sha256=RloLzNVetEoWPLITzfJ13Nk3CC0yi-cZB1RTd6dnuhI,2541
|
|
@@ -213,8 +214,8 @@ annet_generators/rpl_example/generator.py,sha256=EWah19gOH8G-QyNyWqxCqdRi0BK7GbM
|
|
|
213
214
|
annet_generators/rpl_example/items.py,sha256=HPgxScDvSqJPdz0c2SppDrH82DZYC4zUaniQwcWmh4A,1176
|
|
214
215
|
annet_generators/rpl_example/mesh.py,sha256=z_WgfDZZ4xnyh3cSf75igyH09hGvtexEVwy1gCD_DzA,288
|
|
215
216
|
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.
|
|
217
|
+
annet-3.6.1.dist-info/METADATA,sha256=St6o6lXk9azF8fYHOzbNWyhD_XgCMT6TGkMqYtHQTnE,815
|
|
218
|
+
annet-3.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
219
|
+
annet-3.6.1.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
|
|
220
|
+
annet-3.6.1.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
|
|
221
|
+
annet-3.6.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|