annet 0.16.8__py3-none-any.whl → 0.16.10__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/fetchers/__init__.py +0 -0
- annet/adapters/fetchers/stub/__init__.py +0 -0
- annet/adapters/fetchers/stub/fetcher.py +19 -0
- annet/adapters/file/__init__.py +0 -0
- annet/adapters/file/provider.py +226 -0
- annet/adapters/netbox/common/manufacturer.py +2 -0
- annet/adapters/netbox/common/models.py +109 -4
- annet/adapters/netbox/v37/storage.py +31 -3
- annet/annlib/netdev/views/hardware.py +31 -0
- annet/bgp_models.py +266 -0
- annet/configs/context.yml +2 -12
- annet/configs/logging.yaml +1 -0
- annet/generators/__init__.py +18 -4
- annet/generators/jsonfragment.py +13 -12
- annet/mesh/__init__.py +16 -0
- annet/mesh/basemodel.py +180 -0
- annet/mesh/device_models.py +62 -0
- annet/mesh/executor.py +248 -0
- annet/mesh/match_args.py +165 -0
- annet/mesh/models_converter.py +84 -0
- annet/mesh/peer_models.py +98 -0
- annet/mesh/registry.py +212 -0
- annet/rulebook/routeros/__init__.py +0 -0
- annet/rulebook/routeros/file.py +5 -0
- annet/storage.py +41 -2
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/METADATA +3 -1
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/RECORD +36 -17
- annet_generators/example/__init__.py +1 -3
- annet_generators/mesh_example/__init__.py +9 -0
- annet_generators/mesh_example/bgp.py +43 -0
- annet_generators/mesh_example/mesh_logic.py +28 -0
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/AUTHORS +0 -0
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/LICENSE +0 -0
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/WHEEL +0 -0
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/entry_points.txt +0 -0
- {annet-0.16.8.dist-info → annet-0.16.10.dist-info}/top_level.txt +0 -0
annet/mesh/registry.py
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Callable, Any
|
|
3
|
+
|
|
4
|
+
from .match_args import MatchExpr, PairMatcher, SingleMatcher
|
|
5
|
+
from .match_args import MatchedArgs
|
|
6
|
+
from .device_models import GlobalOptionsDTO
|
|
7
|
+
from .peer_models import PeerDTO, MeshSession
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DirectPeer(PeerDTO):
|
|
11
|
+
match: MatchedArgs
|
|
12
|
+
device: Any
|
|
13
|
+
ports: list[str]
|
|
14
|
+
|
|
15
|
+
def __init__(self, match: MatchedArgs, device: Any, ports: list[str]) -> None:
|
|
16
|
+
super().__init__()
|
|
17
|
+
self.match = match
|
|
18
|
+
self.device = device
|
|
19
|
+
self.ports = ports
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class IndirectPeer(PeerDTO):
|
|
23
|
+
match: MatchedArgs
|
|
24
|
+
device: Any
|
|
25
|
+
|
|
26
|
+
def __init__(self, match: MatchedArgs, device: Any) -> None:
|
|
27
|
+
super().__init__()
|
|
28
|
+
self.match = match
|
|
29
|
+
self.device = device
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class GlobalOptions(GlobalOptionsDTO):
|
|
33
|
+
match: MatchedArgs
|
|
34
|
+
device: Any
|
|
35
|
+
|
|
36
|
+
def __init__(self, match: MatchedArgs, device: Any) -> None:
|
|
37
|
+
super().__init__()
|
|
38
|
+
self.match = match
|
|
39
|
+
self.device = device
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
GlobalHandler = Callable[[GlobalOptions], None]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class GlobalRule:
|
|
47
|
+
matcher: SingleMatcher
|
|
48
|
+
handler: GlobalHandler
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
DirectHandler = Callable[[DirectPeer, DirectPeer, MeshSession], None]
|
|
52
|
+
IndirectHandler = Callable[[IndirectPeer, IndirectPeer, MeshSession], None]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class DirectRule:
|
|
57
|
+
__slots__ = ("matcher", "handler")
|
|
58
|
+
matcher: PairMatcher
|
|
59
|
+
handler: DirectHandler
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class IndirectRule:
|
|
64
|
+
__slots__ = ("matcher", "handler")
|
|
65
|
+
matcher: PairMatcher
|
|
66
|
+
handler: IndirectHandler
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass
|
|
70
|
+
class MatchedGlobal:
|
|
71
|
+
__slots__ = ("match", "handler")
|
|
72
|
+
match: MatchedArgs
|
|
73
|
+
handler: GlobalHandler
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class MatchedDirectPair:
|
|
78
|
+
__slots__ = ("handler", "direct_order", "name_left", "name_right", "match_left", "match_right")
|
|
79
|
+
handler: DirectHandler
|
|
80
|
+
direct_order: bool
|
|
81
|
+
name_left: str
|
|
82
|
+
name_right: str
|
|
83
|
+
match_left: MatchedArgs
|
|
84
|
+
match_right: MatchedArgs
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass
|
|
88
|
+
class MatchedIndirectPair:
|
|
89
|
+
__slots__ = ("handler", "direct_order", "name_left", "name_right", "match_left", "match_right")
|
|
90
|
+
handler: IndirectHandler
|
|
91
|
+
direct_order: bool
|
|
92
|
+
name_left: str
|
|
93
|
+
name_right: str
|
|
94
|
+
match_left: MatchedArgs
|
|
95
|
+
match_right: MatchedArgs
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class MeshRulesRegistry:
|
|
99
|
+
def __init__(self, match_short_name: bool = False):
|
|
100
|
+
self.direct_rules: list[DirectRule] = []
|
|
101
|
+
self.indirect_rules: list[IndirectRule] = []
|
|
102
|
+
self.global_rules: list[GlobalRule] = []
|
|
103
|
+
self.nested: list[MeshRulesRegistry] = []
|
|
104
|
+
self.match_short_name = match_short_name
|
|
105
|
+
|
|
106
|
+
def _normalize_host(self, host: str) -> str:
|
|
107
|
+
if self.match_short_name:
|
|
108
|
+
return host.split(".", maxsplit=1)[0]
|
|
109
|
+
return host
|
|
110
|
+
|
|
111
|
+
def include(self, nested_registry: "MeshRulesRegistry") -> None:
|
|
112
|
+
self.nested.append(nested_registry)
|
|
113
|
+
|
|
114
|
+
def device(self, peer_mask: str, *match: MatchExpr) -> Callable[[GlobalHandler], GlobalHandler]:
|
|
115
|
+
matcher = SingleMatcher(peer_mask, match)
|
|
116
|
+
|
|
117
|
+
def register(handler: GlobalHandler) -> GlobalHandler:
|
|
118
|
+
self.global_rules.append(GlobalRule(matcher, handler))
|
|
119
|
+
return handler
|
|
120
|
+
|
|
121
|
+
return register
|
|
122
|
+
|
|
123
|
+
def direct(
|
|
124
|
+
self, left_mask: str, right_mask: str, *match: MatchExpr,
|
|
125
|
+
) -> Callable[[DirectHandler], DirectHandler]:
|
|
126
|
+
matcher = PairMatcher(left_mask, right_mask, match)
|
|
127
|
+
|
|
128
|
+
def register(handler: DirectHandler) -> DirectHandler:
|
|
129
|
+
self.direct_rules.append(DirectRule(matcher, handler))
|
|
130
|
+
return handler
|
|
131
|
+
|
|
132
|
+
return register
|
|
133
|
+
|
|
134
|
+
def indirect(
|
|
135
|
+
self, left_mask: str, right_mask: str, *match: MatchExpr,
|
|
136
|
+
) -> Callable[[IndirectHandler], IndirectHandler]:
|
|
137
|
+
matcher = PairMatcher(left_mask, right_mask, match)
|
|
138
|
+
|
|
139
|
+
def register(handler: IndirectHandler) -> IndirectHandler:
|
|
140
|
+
self.indirect_rules.append(IndirectRule(matcher, handler))
|
|
141
|
+
return handler
|
|
142
|
+
|
|
143
|
+
return register
|
|
144
|
+
|
|
145
|
+
def lookup_direct(self, device: str, neighbors: list[str]) -> list[MatchedDirectPair]:
|
|
146
|
+
found = []
|
|
147
|
+
device = self._normalize_host(device)
|
|
148
|
+
for neighbor in neighbors:
|
|
149
|
+
neighbor = self._normalize_host(neighbor)
|
|
150
|
+
for rule in self.direct_rules:
|
|
151
|
+
if args := rule.matcher.match_pair(device, neighbor):
|
|
152
|
+
found.append(MatchedDirectPair(
|
|
153
|
+
handler=rule.handler,
|
|
154
|
+
direct_order=True,
|
|
155
|
+
name_left=device,
|
|
156
|
+
name_right=neighbor,
|
|
157
|
+
match_left=args[0],
|
|
158
|
+
match_right=args[1],
|
|
159
|
+
))
|
|
160
|
+
if args := rule.matcher.match_pair(neighbor, device):
|
|
161
|
+
found.append(MatchedDirectPair(
|
|
162
|
+
handler=rule.handler,
|
|
163
|
+
direct_order=False,
|
|
164
|
+
name_left=neighbor,
|
|
165
|
+
name_right=device,
|
|
166
|
+
match_left=args[0],
|
|
167
|
+
match_right=args[1],
|
|
168
|
+
))
|
|
169
|
+
for registry in self.nested:
|
|
170
|
+
found.extend(registry.lookup_direct(device, neighbors))
|
|
171
|
+
return found
|
|
172
|
+
|
|
173
|
+
def lookup_indirect(self, device: str, devices: list[str]) -> list[MatchedIndirectPair]:
|
|
174
|
+
found = []
|
|
175
|
+
device = self._normalize_host(device)
|
|
176
|
+
for other_device in devices:
|
|
177
|
+
other_device = self._normalize_host(other_device)
|
|
178
|
+
for rule in self.indirect_rules:
|
|
179
|
+
if args := rule.matcher.match_pair(device, other_device):
|
|
180
|
+
found.append(MatchedIndirectPair(
|
|
181
|
+
handler=rule.handler,
|
|
182
|
+
direct_order=True,
|
|
183
|
+
name_left=device,
|
|
184
|
+
name_right=other_device,
|
|
185
|
+
match_left=args[0],
|
|
186
|
+
match_right=args[1],
|
|
187
|
+
))
|
|
188
|
+
if args := rule.matcher.match_pair(other_device, device):
|
|
189
|
+
found.append(MatchedIndirectPair(
|
|
190
|
+
handler=rule.handler,
|
|
191
|
+
direct_order=False,
|
|
192
|
+
name_left=other_device,
|
|
193
|
+
name_right=device,
|
|
194
|
+
match_left=args[0],
|
|
195
|
+
match_right=args[1],
|
|
196
|
+
))
|
|
197
|
+
for registry in self.nested:
|
|
198
|
+
found.extend(registry.lookup_indirect(device, devices))
|
|
199
|
+
return found
|
|
200
|
+
|
|
201
|
+
def lookup_global(self, device: str) -> list[MatchedGlobal]:
|
|
202
|
+
found = []
|
|
203
|
+
device = self._normalize_host(device)
|
|
204
|
+
for rule in self.global_rules:
|
|
205
|
+
if args := rule.matcher.match_one(device):
|
|
206
|
+
found.append(MatchedGlobal(
|
|
207
|
+
handler=rule.handler,
|
|
208
|
+
match=args,
|
|
209
|
+
))
|
|
210
|
+
for registry in self.nested:
|
|
211
|
+
found.extend(registry.lookup_global(device))
|
|
212
|
+
return found
|
|
File without changes
|
annet/storage.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import abc
|
|
2
|
+
from collections.abc import Sequence
|
|
2
3
|
from typing import Any, Iterable, Optional, Type, Union, Protocol, Dict
|
|
3
4
|
from annet.connectors import Connector, get_connector_from_config
|
|
4
5
|
from annet.annlib.netdev.views.hardware import HardwareView
|
|
@@ -48,13 +49,21 @@ class Storage(abc.ABC):
|
|
|
48
49
|
def resolve_fdnds_by_query(self, query: Any):
|
|
49
50
|
pass
|
|
50
51
|
|
|
52
|
+
@abc.abstractmethod
|
|
53
|
+
def resolve_all_fdnds(self) -> list[str]:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
@abc.abstractmethod
|
|
57
|
+
def search_connections(self, device: "Device", neighbor: "Device") -> list[tuple["Interface", "Interface"]]:
|
|
58
|
+
pass
|
|
59
|
+
|
|
51
60
|
@abc.abstractmethod
|
|
52
61
|
def make_devices(
|
|
53
62
|
self,
|
|
54
63
|
query: Any,
|
|
55
64
|
preload_neighbors: bool = False,
|
|
56
|
-
use_mesh: bool = None,
|
|
57
|
-
preload_extra_fields=False,
|
|
65
|
+
use_mesh: Optional[bool] = None,
|
|
66
|
+
preload_extra_fields: bool = False,
|
|
58
67
|
**kwargs,
|
|
59
68
|
):
|
|
60
69
|
pass
|
|
@@ -85,6 +94,17 @@ class Query(abc.ABC):
|
|
|
85
94
|
return False
|
|
86
95
|
|
|
87
96
|
|
|
97
|
+
class Interface(Protocol):
|
|
98
|
+
@property
|
|
99
|
+
@abc.abstractmethod
|
|
100
|
+
def name(self) -> str:
|
|
101
|
+
raise NotImplementedError
|
|
102
|
+
|
|
103
|
+
@abc.abstractmethod
|
|
104
|
+
def add_addr(self, address_mask: str, vrf: Optional[str]) -> None:
|
|
105
|
+
raise NotImplementedError
|
|
106
|
+
|
|
107
|
+
|
|
88
108
|
class Device(Protocol):
|
|
89
109
|
@property
|
|
90
110
|
@abc.abstractmethod
|
|
@@ -124,11 +144,30 @@ class Device(Protocol):
|
|
|
124
144
|
def neighbours_ids(self):
|
|
125
145
|
pass
|
|
126
146
|
|
|
147
|
+
@property
|
|
148
|
+
@abc.abstractmethod
|
|
149
|
+
def neighbours_fqdns(self):
|
|
150
|
+
pass
|
|
151
|
+
|
|
127
152
|
@property
|
|
128
153
|
@abc.abstractmethod
|
|
129
154
|
def breed(self) -> str:
|
|
130
155
|
pass
|
|
131
156
|
|
|
157
|
+
@abc.abstractmethod
|
|
158
|
+
def make_lag(self, lag: int, ports: Sequence[str], lag_min_links: Optional[int]) -> Interface:
|
|
159
|
+
raise NotImplementedError
|
|
160
|
+
|
|
161
|
+
@abc.abstractmethod
|
|
162
|
+
def add_svi(self, svi: int) -> Interface:
|
|
163
|
+
"""Add SVI interface or return existing one"""
|
|
164
|
+
raise NotImplementedError
|
|
165
|
+
|
|
166
|
+
@abc.abstractmethod
|
|
167
|
+
def add_subif(self, interface: str, subif: int) -> Interface:
|
|
168
|
+
"""Add sub interface or return existing one"""
|
|
169
|
+
raise NotImplementedError
|
|
170
|
+
|
|
132
171
|
|
|
133
172
|
def get_storage() -> tuple[StorageProvider, Dict[str, Any]]:
|
|
134
173
|
connectors = storage_connector.get_all()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.10
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -23,4 +23,6 @@ Requires-Dist: aiohttp >=3.8.4
|
|
|
23
23
|
Requires-Dist: yarl >=1.8.2
|
|
24
24
|
Requires-Dist: adaptix ==3.0.0b7
|
|
25
25
|
Requires-Dist: dataclass-rest ==0.4
|
|
26
|
+
Provides-Extra: netbox
|
|
27
|
+
Requires-Dist: annetbox[sync] >=0.1.8 ; extra == 'netbox'
|
|
26
28
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
annet/__init__.py,sha256=k2dq8aOYjkjZszKoOlxEmR49uYoKh-8_HC2K8FeqLwA,2139
|
|
2
2
|
annet/annet.py,sha256=TMdEuM7GJQ4TjRVmuK3bCTZN-21lxjQ9sXqEdILUuBk,725
|
|
3
3
|
annet/argparse.py,sha256=v1MfhjR0B8qahza0WinmXClpR8UiDFhmwDDWtNroJPA,12855
|
|
4
|
+
annet/bgp_models.py,sha256=lV9TW7oPiaiWxD9c5pMIpAnghVIUFK_cTpxNbUUfIaM,8082
|
|
4
5
|
annet/cli.py,sha256=hDpjIr3w47lgQ_CvCQS1SXFDK-SJrf5slbT__5u6GIA,12342
|
|
5
6
|
annet/cli_args.py,sha256=KQlihxSl-Phhq1-9oJDdNSbIllEX55LlPfH6viEKOuw,13483
|
|
6
7
|
annet/connectors.py,sha256=-Lghz3PtWCBU8Ohrp0KKQcmm1AUZtN0EnOaZ6IQgCQI,5105
|
|
@@ -16,25 +17,30 @@ annet/output.py,sha256=BNPzjuhMa7gSJ8ze_1O-Ey0tTxSyhAiwfztZMQwhMzk,7176
|
|
|
16
17
|
annet/parallel.py,sha256=hLkzEht0KhzmzUWDdO4QFYQHzhxs3wPlTA8DxbB2ziw,17160
|
|
17
18
|
annet/patching.py,sha256=nILbY5oJajN0b1j3f0HEJm05H3HVThnWvB7vDVh7UQw,559
|
|
18
19
|
annet/reference.py,sha256=B8mH8VUMcecPnzULiTVb_kTQ7jQrCL7zp4pfIZQa5fk,4035
|
|
19
|
-
annet/storage.py,sha256=
|
|
20
|
+
annet/storage.py,sha256=eAHEvPbRuKDUJdnkzSrHmW_lBJS3Y0g93Y2VJ4qzifQ,3941
|
|
20
21
|
annet/tabparser.py,sha256=N0O7G9DTdmgcBDxz0PH7B_r-Z8FsUkZqm9hTBy3PZFA,969
|
|
21
22
|
annet/text_term_format.py,sha256=CHb6viv45vmYl-SK1A1vyPHGhaEni6jVybBusaQnct8,2813
|
|
22
23
|
annet/tracing.py,sha256=ndpM-au1c88uBBpOuH_z52qWZL773edYozNyys_wA68,4044
|
|
23
24
|
annet/types.py,sha256=f2HwqoKa6AucwFwDMszoouB6m1B8n6VmdjHMktO30Kc,7175
|
|
24
25
|
annet/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
annet/adapters/fetchers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
annet/adapters/fetchers/stub/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
annet/adapters/fetchers/stub/fetcher.py,sha256=bJGNJcvjrxSa4d8gly6NkaRcxoK57zbZhzkW5vq278I,656
|
|
29
|
+
annet/adapters/file/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
annet/adapters/file/provider.py,sha256=Wn3sG2TOI6ZWuRHhPSyg8S0Dnrz5LN3VyuqE6S7r5GM,5930
|
|
25
31
|
annet/adapters/netbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
32
|
annet/adapters/netbox/provider.py,sha256=IIs37QFHuJHxq4A0WfBS4JENk--v3BxqgNPal1Or4Xc,1470
|
|
27
33
|
annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
34
|
annet/adapters/netbox/common/client.py,sha256=-lWZmphD-OPuLIHNKhW_h2bnjrVaiyKYAD_MUPasEbo,2483
|
|
29
|
-
annet/adapters/netbox/common/manufacturer.py,sha256=
|
|
30
|
-
annet/adapters/netbox/common/models.py,sha256=
|
|
35
|
+
annet/adapters/netbox/common/manufacturer.py,sha256=QoTjmuBAg5klOJqeo8HuS2HybIUGsjTkknLkQL_Tiec,1606
|
|
36
|
+
annet/adapters/netbox/common/models.py,sha256=SeWQZV-zvaKvK2YT2Bwf-iapkIs5pr7I7rAI7vlFMB8,6886
|
|
31
37
|
annet/adapters/netbox/common/query.py,sha256=ziUFM7cUEbEIf3k1szTll4aO-OCUa-2Ogxbebi7Tegs,646
|
|
32
38
|
annet/adapters/netbox/common/status_client.py,sha256=W4nTb2yvBlJ2UkWUmUhKQ2PaSQb1shjhHj5ebb4s2s4,591
|
|
33
39
|
annet/adapters/netbox/common/storage_opts.py,sha256=iadgWGMb-rfSp3SnFAw8SH5bMKjwvcAsJ74v_z0CCXQ,507
|
|
34
40
|
annet/adapters/netbox/v24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
41
|
annet/adapters/netbox/v24/storage.py,sha256=THI592VLx3ehixsPZQ1Ko3mYIAZQbnDY-toIziqBbL8,6005
|
|
36
42
|
annet/adapters/netbox/v37/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
annet/adapters/netbox/v37/storage.py,sha256=
|
|
43
|
+
annet/adapters/netbox/v37/storage.py,sha256=Fq72sIHZRXx-lMS_3mzD-thaNNJ_zogaA-aCyXaEn2U,9716
|
|
38
44
|
annet/annlib/__init__.py,sha256=fT1l4xV5fqqg8HPw9HqmZVN2qwS8i6X1aIm2zGDjxKY,252
|
|
39
45
|
annet/annlib/command.py,sha256=uuBddMQphtn8P5MO5kzIa8_QrtMns-k05VeKv1bcAuA,1043
|
|
40
46
|
annet/annlib/diff.py,sha256=MZ6eQAU3cadQp8KaSE6uAYFtcfMDCIe_eNuVROnYkCk,4496
|
|
@@ -52,7 +58,7 @@ annet/annlib/netdev/devdb/__init__.py,sha256=aKYjjLbJebdKBjnGDpVLQdSqrV2JL24spGm
|
|
|
52
58
|
annet/annlib/netdev/devdb/data/devdb.json,sha256=Qph7WxZBEbgBqbCFeYu6ZM0qkEBn80WmJEjfJkcaZ-0,5940
|
|
53
59
|
annet/annlib/netdev/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
60
|
annet/annlib/netdev/views/dump.py,sha256=rIlyvnA3uM8bB_7oq1nS2KDxTp6dQh2hz-FbNhYIpOU,4630
|
|
55
|
-
annet/annlib/netdev/views/hardware.py,sha256=
|
|
61
|
+
annet/annlib/netdev/views/hardware.py,sha256=3JCZLH7deIHhCguwPJTUX-WDvWjG_xt6BdSEZSO6zkQ,4226
|
|
56
62
|
annet/annlib/rbparser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
63
|
annet/annlib/rbparser/acl.py,sha256=RR8yPt6t96_IiyuKVbeZ-3x32cyhBAT2wC1y99oWBO8,3931
|
|
58
64
|
annet/annlib/rbparser/deploying.py,sha256=ACT8QNhDAhJx3ZKuGh2nYBOrpdka2qEKuLDxvQAGKLk,1649
|
|
@@ -62,19 +68,27 @@ annet/annlib/rbparser/syntax.py,sha256=iZ7Y-4QQBw4L3UtjEh54qisiRDhobl7HZxFNdP8mi
|
|
|
62
68
|
annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
69
|
annet/annlib/rulebook/common.py,sha256=Kd9Xout0xC6ZZDnyaORx0W-1kSM-gTgjQbp1iIXWxic,16489
|
|
64
70
|
annet/api/__init__.py,sha256=7EB3d89kGXKf4Huw7cqyOULTGC9ydL4sHiVw8K0Aeqg,33722
|
|
65
|
-
annet/configs/context.yml,sha256=
|
|
66
|
-
annet/configs/logging.yaml,sha256=
|
|
67
|
-
annet/generators/__init__.py,sha256=
|
|
71
|
+
annet/configs/context.yml,sha256=mzJF3K9lM-Fvj9oFOZrDEjQHWJ4W5t96ewMeeWbKDAY,224
|
|
72
|
+
annet/configs/logging.yaml,sha256=EUagfir99QqA73Scc3k7sfQccbU3E1SvEQdyhLFtCl4,997
|
|
73
|
+
annet/generators/__init__.py,sha256=rVHHDTPKHPZsml1eNEAj3o-8RweFTN8J7LX3tKMXdIY,16402
|
|
68
74
|
annet/generators/base.py,sha256=rgQLcQBPZm4ecbKmRhVOpBR-GFJAiVfdb_y5f2-LUR8,3670
|
|
69
75
|
annet/generators/entire.py,sha256=7WySkVaXNT3ZAiHcQ0JUKdlhGJAN8cNUxF6c7ilYnO8,2928
|
|
70
76
|
annet/generators/exceptions.py,sha256=GPXTBgn2xZ3Ev_bdOPlfCLGRC1kQHe_dEq88S-uyi5s,151
|
|
71
|
-
annet/generators/jsonfragment.py,sha256=
|
|
77
|
+
annet/generators/jsonfragment.py,sha256=_jcEjfX9hIiEXSbOPbDAx2WvBkTGMRNrJmluUtIE8C4,4107
|
|
72
78
|
annet/generators/partial.py,sha256=XI01KDA--XwjSEU33SOQCCJZRXFq5boRz1uJA8lVA1g,3502
|
|
73
79
|
annet/generators/perf.py,sha256=K72ivUuXbNXrsHrLeKWhGmczGYWsB7kUDdDzqOX6j3c,2370
|
|
74
80
|
annet/generators/ref.py,sha256=QVdeL8po1D0kBsVLOpCjFR81D8yNTk-kaQj5WUM4hng,438
|
|
75
81
|
annet/generators/result.py,sha256=zMAvGOYQU803bGy6datZduHLgrEqK2Zba_Jcf9Qn9p0,4976
|
|
76
82
|
annet/generators/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
83
|
annet/generators/common/initial.py,sha256=qYBxXFhyOPy34cxc6hsIXseod-lYCmmbuNHpM0uteY0,1244
|
|
84
|
+
annet/mesh/__init__.py,sha256=_Ho7ZwPuEZ7wsOu_oG0avvPzQVn8g-A0w2fqZ42Gf30,369
|
|
85
|
+
annet/mesh/basemodel.py,sha256=bBBx1wu3ftENgf_4PGCV-SkEcxH3tFekvoointT3894,4739
|
|
86
|
+
annet/mesh/device_models.py,sha256=m3S2IUW7dH0drAop3imwuTk27X93c8lLC2ot8S6rA5Y,2068
|
|
87
|
+
annet/mesh/executor.py,sha256=KoFrDd-6XsN2IO-AnLKYiKYebMmN6KpbUVq8AWXUYVE,10926
|
|
88
|
+
annet/mesh/match_args.py,sha256=CR3kdIV9NGtyk9E2JbcOQ3TRuYEryTWP3m2yCo2VCWg,5751
|
|
89
|
+
annet/mesh/models_converter.py,sha256=EdAQIkE-AfdCqMuzVQEdsG5lQdsaAwmqNqq9b8GRnGQ,2888
|
|
90
|
+
annet/mesh/peer_models.py,sha256=sHny5nvLTWY2gqrq-SzZJ-lzEa90E_RCuBoiLb-Rub8,2129
|
|
91
|
+
annet/mesh/registry.py,sha256=N2QyfyH0Qt73l16CO8VRKIBKHscBntEfS-j9B4xs-ys,6906
|
|
78
92
|
annet/rulebook/__init__.py,sha256=14IpOfTbeJtre7JKrfXVYiH0qAXsUSOL7AatUFmSQs0,3847
|
|
79
93
|
annet/rulebook/common.py,sha256=zK1s2c5lc5HQbIlMUQ4HARQudXSgOYiZ_Sxc2I_tHqg,721
|
|
80
94
|
annet/rulebook/deploying.py,sha256=XV0XQvc3YvwM8SOgOQlc-fCW4bnjQg_1CTZkTwMp14A,2972
|
|
@@ -100,6 +114,8 @@ annet/rulebook/juniper/__init__.py,sha256=WByFrqKCdr-ORCme2AURQGnYbN66t3omB3-9dW
|
|
|
100
114
|
annet/rulebook/nexus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
115
|
annet/rulebook/nexus/iface.py,sha256=aeog9iSGT2zZ78tsGlrRcfgfOv7yW3jLwryXqdeplRw,2923
|
|
102
116
|
annet/rulebook/ribbon/__init__.py,sha256=TRbkQVvk0-HxkUQW9-LmiG6XIfTZ-8t3SiaDemNCzK4,347
|
|
117
|
+
annet/rulebook/routeros/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
118
|
+
annet/rulebook/routeros/file.py,sha256=zK7RwBk1YaVoDSFSg1u7Pt8u0Fk3nhhu27aJRngemwc,137
|
|
103
119
|
annet/rulebook/texts/arista.deploy,sha256=OS9eFyJpEPztcOHkBwajw_RTJfTT7ivaMHfx4_HXaUg,792
|
|
104
120
|
annet/rulebook/texts/arista.order,sha256=TKy3S56tIypwfVaw0akK1sXGatCpLVwpB4Jvq-dIu90,1457
|
|
105
121
|
annet/rulebook/texts/arista.rul,sha256=HUYiN55s8Y6Wrd5q1Awe7-o5BYBh7gIxthUC5NvrfJI,786
|
|
@@ -131,12 +147,15 @@ annet/rulebook/texts/ribbon.rul,sha256=609LyLTDCtXPVQNAzqS-VEyCpW3byHP8TCMJLFMn5
|
|
|
131
147
|
annet/rulebook/texts/routeros.order,sha256=M71uy_hf0KAjLNS3zZY3uih4m2xLUcu26FEoVVjC6k0,905
|
|
132
148
|
annet/rulebook/texts/routeros.rul,sha256=ipfxjj0mjFef6IsUlupqx4BY_Je_OUb8u_U1019O1DE,1203
|
|
133
149
|
annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
134
|
-
annet_generators/example/__init__.py,sha256=
|
|
150
|
+
annet_generators/example/__init__.py,sha256=1z030I00c9KeqW0ntkT1IRLYKD5LZAHYjiNHrOLen1Q,221
|
|
135
151
|
annet_generators/example/lldp.py,sha256=24bGvShxbio-JxUdaehyPRu31LhH9YwSwFDrWVRn6yo,2100
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
annet-0.16.
|
|
140
|
-
annet-0.16.
|
|
141
|
-
annet-0.16.
|
|
142
|
-
annet-0.16.
|
|
152
|
+
annet_generators/mesh_example/__init__.py,sha256=NfNWgXn1TNiWI6A5tmU6Y-4QV2i33td0Qs3re0MNNMo,218
|
|
153
|
+
annet_generators/mesh_example/bgp.py,sha256=ck--yU_lUdAX9DWaaVQ-C29eQN-EGf1gEpOTBxmMnWA,1317
|
|
154
|
+
annet_generators/mesh_example/mesh_logic.py,sha256=5Wt17LPt-EWe126IFAdaQQGWIOR3mxTJjAMUY8K0c0w,971
|
|
155
|
+
annet-0.16.10.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
|
|
156
|
+
annet-0.16.10.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
|
|
157
|
+
annet-0.16.10.dist-info/METADATA,sha256=nS_AbW4YJ7cjneZlyiKTA1CsSPnk1VcOLfi_KkMipdU,776
|
|
158
|
+
annet-0.16.10.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
159
|
+
annet-0.16.10.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
|
|
160
|
+
annet-0.16.10.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
|
|
161
|
+
annet-0.16.10.dist-info/RECORD,,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from annet.adapters.netbox.common.models import NetboxDevice
|
|
4
|
+
from annet.generators import PartialGenerator, BaseGenerator
|
|
5
|
+
from annet.mesh import MeshExecutor
|
|
6
|
+
from annet.storage import Storage
|
|
7
|
+
from .mesh_logic import registry
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Bgp(PartialGenerator):
|
|
11
|
+
TAGS = ["mgmt", "bgp"]
|
|
12
|
+
|
|
13
|
+
def acl_huawei(self, device):
|
|
14
|
+
return """
|
|
15
|
+
bgp
|
|
16
|
+
peer
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def run_huawei(self, device: NetboxDevice):
|
|
20
|
+
executor = MeshExecutor(registry, device.storage)
|
|
21
|
+
res = executor.execute_for(device)
|
|
22
|
+
yield f"bgp {res.global_options.local_as}"
|
|
23
|
+
for peer in res.peers:
|
|
24
|
+
if peer.group_name:
|
|
25
|
+
yield f" peer {peer.addr} {peer.group_name}"
|
|
26
|
+
if peer.remote_as is not None:
|
|
27
|
+
yield f" peer {peer.addr} remote-as {peer.remote_as}"
|
|
28
|
+
|
|
29
|
+
for group in res.global_options.groups:
|
|
30
|
+
yield f" peer {group.name} remote-as {group.remote_as}"
|
|
31
|
+
for interface in device.interfaces:
|
|
32
|
+
print(
|
|
33
|
+
interface.name,
|
|
34
|
+
interface.lag_min_links,
|
|
35
|
+
interface.lag.name if interface.lag else None,
|
|
36
|
+
interface.ip_addresses,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_generators(store: Storage) -> List[BaseGenerator]:
|
|
41
|
+
return [
|
|
42
|
+
Bgp(store),
|
|
43
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from annet.mesh import Right, MeshRulesRegistry, GlobalOptions, MeshSession, DirectPeer
|
|
2
|
+
|
|
3
|
+
registry = MeshRulesRegistry()
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@registry.device("{name:.*}")
|
|
7
|
+
def device_handler(global_opts: GlobalOptions):
|
|
8
|
+
global_opts.local_as = 12345
|
|
9
|
+
global_opts.groups["GROP_NAME"].remote_as = 11111
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@registry.direct("{name:.*}", "m9-sgw{x}.{domain:.*}")
|
|
13
|
+
def direct_handler(device: DirectPeer, neighbor: DirectPeer, session: MeshSession):
|
|
14
|
+
session.asnum = 12345
|
|
15
|
+
device.addr = "192.168.1.254"
|
|
16
|
+
neighbor.addr = f"192.168.1.{neighbor.match.x}"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@registry.direct("{name:.*}", "m9-sgw{x}.{domain:.*}", Right.x.in_([0, 1]))
|
|
20
|
+
def direct_handler2(device: DirectPeer, neighbor: DirectPeer, session: MeshSession):
|
|
21
|
+
session.asnum = 12345
|
|
22
|
+
device.addr = "192.168.1.254/24"
|
|
23
|
+
device.lag = 1
|
|
24
|
+
device.lag_links_min = neighbor.match.x
|
|
25
|
+
device.subif = 100
|
|
26
|
+
neighbor.families = {"ipv4_unicast"}
|
|
27
|
+
neighbor.group_name = "GROUP_NAME"
|
|
28
|
+
neighbor.addr = "192.168.1.200/24"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|