annet 0.6__py3-none-any.whl → 0.7__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/__init__.py +0 -0
- annet/adapters/netbox/__init__.py +0 -0
- annet/adapters/netbox/common/__init__.py +0 -0
- annet/adapters/netbox/common/client.py +87 -0
- annet/adapters/netbox/common/manufacturer.py +62 -0
- annet/adapters/netbox/common/models.py +98 -0
- annet/adapters/netbox/common/query.py +23 -0
- annet/adapters/netbox/common/status_client.py +24 -0
- annet/adapters/netbox/common/storage_opts.py +14 -0
- annet/adapters/netbox/provider.py +34 -0
- annet/adapters/netbox/v24/__init__.py +0 -0
- annet/adapters/netbox/v24/api_models.py +72 -0
- annet/adapters/netbox/v24/client.py +59 -0
- annet/adapters/netbox/v24/storage.py +190 -0
- annet/adapters/netbox/v37/__init__.py +0 -0
- annet/adapters/netbox/v37/api_models.py +37 -0
- annet/adapters/netbox/v37/client.py +62 -0
- annet/adapters/netbox/v37/storage.py +143 -0
- annet/api/__init__.py +18 -6
- annet/cli.py +6 -2
- annet/cli_args.py +10 -0
- annet/diff.py +1 -2
- annet/gen.py +6 -2
- annet/generators/__init__.py +7 -9
- annet/output.py +3 -1
- {annet-0.6.dist-info → annet-0.7.dist-info}/METADATA +3 -1
- {annet-0.6.dist-info → annet-0.7.dist-info}/RECORD +32 -16
- {annet-0.6.dist-info → annet-0.7.dist-info}/WHEEL +1 -1
- annet-0.7.dist-info/entry_points.txt +5 -0
- {annet-0.6.dist-info → annet-0.7.dist-info}/top_level.txt +0 -1
- annet-0.6.dist-info/entry_points.txt +0 -6
- annet_nbexport/__init__.py +0 -220
- annet_nbexport/main.py +0 -46
- {annet-0.6.dist-info → annet-0.7.dist-info}/AUTHORS +0 -0
- {annet-0.6.dist-info → annet-0.7.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import List, Optional, Any
|
|
4
|
+
|
|
5
|
+
from annet.adapters.netbox.common.models import (
|
|
6
|
+
Entity, Label, DeviceType, DeviceIp,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class Interface(Entity):
|
|
12
|
+
device: Entity
|
|
13
|
+
enabled: bool
|
|
14
|
+
display: str = "" # added in 3.x
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class Device(Entity):
|
|
19
|
+
display: str # renamed in 3.x from display_name
|
|
20
|
+
device_type: DeviceType
|
|
21
|
+
device_role: Entity
|
|
22
|
+
tenant: Optional[Entity]
|
|
23
|
+
platform: Optional[Entity]
|
|
24
|
+
serial: str
|
|
25
|
+
asset_tag: Optional[str]
|
|
26
|
+
site: Entity
|
|
27
|
+
rack: Optional[Entity]
|
|
28
|
+
position: Optional[float]
|
|
29
|
+
face: Optional[Label]
|
|
30
|
+
status: Label
|
|
31
|
+
primary_ip: Optional[DeviceIp]
|
|
32
|
+
primary_ip4: Optional[DeviceIp]
|
|
33
|
+
primary_ip6: Optional[DeviceIp]
|
|
34
|
+
tags: List[Entity]
|
|
35
|
+
custom_fields: dict[str, Any]
|
|
36
|
+
created: datetime
|
|
37
|
+
last_updated: datetime
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
import dateutil.parser
|
|
5
|
+
from adaptix import Retort, loader
|
|
6
|
+
from dataclass_rest import get
|
|
7
|
+
from dataclass_rest.client_protocol import FactoryProtocol
|
|
8
|
+
|
|
9
|
+
from annet.adapters.netbox.common.client import (
|
|
10
|
+
BaseNetboxClient, collect, PagingResponse,
|
|
11
|
+
)
|
|
12
|
+
from annet.adapters.netbox.common.models import IpAddress
|
|
13
|
+
from .api_models import Device, Interface
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class NetboxV37(BaseNetboxClient):
|
|
17
|
+
def _init_response_body_factory(self) -> FactoryProtocol:
|
|
18
|
+
return Retort(recipe=[
|
|
19
|
+
loader(datetime, dateutil.parser.parse)
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
@get("dcim/interfaces")
|
|
23
|
+
def interfaces(
|
|
24
|
+
self,
|
|
25
|
+
device_id: Optional[List[int]] = None,
|
|
26
|
+
limit: int = 20,
|
|
27
|
+
offset: int = 0,
|
|
28
|
+
) -> PagingResponse[Interface]:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
all_interfaces = collect(interfaces, field="device_id")
|
|
32
|
+
|
|
33
|
+
@get("ipam/ip-addresses")
|
|
34
|
+
def ip_addresses(
|
|
35
|
+
self,
|
|
36
|
+
interface_id: Optional[List[int]] = None,
|
|
37
|
+
limit: int = 20,
|
|
38
|
+
offset: int = 0,
|
|
39
|
+
) -> PagingResponse[IpAddress]:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
all_ip_addresses = collect(ip_addresses, field="interface_id")
|
|
43
|
+
|
|
44
|
+
@get("dcim/devices")
|
|
45
|
+
def devices(
|
|
46
|
+
self,
|
|
47
|
+
name: Optional[List[str]] = None,
|
|
48
|
+
name__ic: Optional[List[str]] = None,
|
|
49
|
+
tag: Optional[List[str]] = None,
|
|
50
|
+
limit: int = 20,
|
|
51
|
+
offset: int = 0,
|
|
52
|
+
) -> PagingResponse[Device]:
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
all_devices = collect(devices)
|
|
56
|
+
|
|
57
|
+
@get("dcim/devices/{device_id}")
|
|
58
|
+
def get_device(
|
|
59
|
+
self,
|
|
60
|
+
device_id: int,
|
|
61
|
+
) -> Device:
|
|
62
|
+
pass
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from logging import getLogger
|
|
2
|
+
from typing import Optional, List
|
|
3
|
+
|
|
4
|
+
from adaptix import P
|
|
5
|
+
from adaptix.conversion import impl_converter, link
|
|
6
|
+
|
|
7
|
+
from annet.adapters.netbox.common import models
|
|
8
|
+
from annet.adapters.netbox.common.manufacturer import (
|
|
9
|
+
is_supported, get_hw, get_breed,
|
|
10
|
+
)
|
|
11
|
+
from annet.adapters.netbox.common.query import NetboxQuery
|
|
12
|
+
from annet.adapters.netbox.common.storage_opts import NetboxStorageOpts
|
|
13
|
+
from annet.annlib.netdev.views.hardware import HardwareView
|
|
14
|
+
from annet.storage import Storage
|
|
15
|
+
from . import api_models
|
|
16
|
+
from .client import NetboxV37
|
|
17
|
+
|
|
18
|
+
logger = getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@impl_converter(recipe=[
|
|
22
|
+
link(P[api_models.Device].name, P[models.NetboxDevice].hostname),
|
|
23
|
+
link(P[api_models.Device].name, P[models.NetboxDevice].fqdn),
|
|
24
|
+
])
|
|
25
|
+
def extend_device_base(
|
|
26
|
+
device: api_models.Device,
|
|
27
|
+
interfaces: List[models.Interface],
|
|
28
|
+
hw: Optional[HardwareView],
|
|
29
|
+
breed: str,
|
|
30
|
+
neighbours_ids: List[int],
|
|
31
|
+
) -> models.NetboxDevice:
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def extend_device(
|
|
36
|
+
device: api_models.Device,
|
|
37
|
+
) -> models.NetboxDevice:
|
|
38
|
+
return extend_device_base(
|
|
39
|
+
device=device,
|
|
40
|
+
interfaces=[],
|
|
41
|
+
breed=get_breed(
|
|
42
|
+
device.device_type.manufacturer.name,
|
|
43
|
+
device.device_type.model,
|
|
44
|
+
),
|
|
45
|
+
hw=get_hw(
|
|
46
|
+
device.device_type.manufacturer.name,
|
|
47
|
+
device.device_type.model,
|
|
48
|
+
),
|
|
49
|
+
neighbours_ids=[],
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@impl_converter
|
|
54
|
+
def extend_interface(
|
|
55
|
+
interface: api_models.Interface, ip_addresses: List[models.IpAddress],
|
|
56
|
+
) -> models.Interface:
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class NetboxStorageV37(Storage):
|
|
61
|
+
def __init__(self, opts: Optional[NetboxStorageOpts] = None):
|
|
62
|
+
self.netbox = NetboxV37(
|
|
63
|
+
url=opts.url,
|
|
64
|
+
token=opts.token,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def __enter__(self):
|
|
68
|
+
return self
|
|
69
|
+
|
|
70
|
+
def __exit__(self, _, __, ___):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def resolve_object_ids_by_query(self, query: NetboxQuery):
|
|
74
|
+
return [
|
|
75
|
+
d.id for d in self._load_devices(query)
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
def resolve_fdnds_by_query(self, query: NetboxQuery):
|
|
79
|
+
return [
|
|
80
|
+
d.name for d in self._load_devices(query)
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
def make_devices(
|
|
84
|
+
self,
|
|
85
|
+
query: NetboxQuery,
|
|
86
|
+
preload_neighbors=False,
|
|
87
|
+
use_mesh=None,
|
|
88
|
+
preload_extra_fields=False,
|
|
89
|
+
**kwargs,
|
|
90
|
+
) -> List[models.NetboxDevice]:
|
|
91
|
+
device_ids = {
|
|
92
|
+
device.id: extend_device(device=device)
|
|
93
|
+
for device in self._load_devices(query)
|
|
94
|
+
}
|
|
95
|
+
if not device_ids:
|
|
96
|
+
return []
|
|
97
|
+
|
|
98
|
+
interfaces = self._load_interfaces(list(device_ids))
|
|
99
|
+
for interface in interfaces:
|
|
100
|
+
device_ids[interface.device.id].interfaces.append(interface)
|
|
101
|
+
return list(device_ids.values())
|
|
102
|
+
|
|
103
|
+
def _load_devices(self, query: NetboxQuery) -> List[api_models.Device]:
|
|
104
|
+
return [
|
|
105
|
+
device
|
|
106
|
+
for device in self.netbox.all_devices(
|
|
107
|
+
name__ic=query.globs,
|
|
108
|
+
).results
|
|
109
|
+
if _match_query(query, device)
|
|
110
|
+
if is_supported(device.device_type.manufacturer.name)
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
def _load_interfaces(self, device_ids: List[int]) -> List[
|
|
114
|
+
models.Interface]:
|
|
115
|
+
interfaces = self.netbox.all_interfaces(device_id=device_ids)
|
|
116
|
+
extended_ifaces = {
|
|
117
|
+
interface.id: extend_interface(interface, [])
|
|
118
|
+
for interface in interfaces.results
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
ips = self.netbox.all_ip_addresses(interface_id=list(extended_ifaces))
|
|
122
|
+
for ip in ips.results:
|
|
123
|
+
extended_ifaces[ip.assigned_object_id].ip_addresses.append(ip)
|
|
124
|
+
return list(extended_ifaces.values())
|
|
125
|
+
|
|
126
|
+
def get_device(
|
|
127
|
+
self, obj_id, preload_neighbors=False, use_mesh=None,
|
|
128
|
+
**kwargs,
|
|
129
|
+
) -> models.NetboxDevice:
|
|
130
|
+
device = self.netbox.get_device(obj_id)
|
|
131
|
+
res = extend_device(device=device)
|
|
132
|
+
res.interfaces = self._load_interfaces([device.id])
|
|
133
|
+
return res
|
|
134
|
+
|
|
135
|
+
def flush_perf(self):
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _match_query(query: NetboxQuery, device_data: api_models.Device) -> bool:
|
|
140
|
+
for subquery in query.globs:
|
|
141
|
+
if subquery.strip() in device_data.name:
|
|
142
|
+
return True
|
|
143
|
+
return False
|
annet/api/__init__.py
CHANGED
|
@@ -188,7 +188,9 @@ def _print_pre_as_diff(pre, show_rules, indent, file=None, _level=0):
|
|
|
188
188
|
def log_host_progress_cb(pool: Parallel, task_result: TaskResult):
|
|
189
189
|
progress_logger = get_logger("progress")
|
|
190
190
|
args = cast(cli_args.QueryOptions, pool.args[0])
|
|
191
|
-
|
|
191
|
+
connector = storage_connector.get()
|
|
192
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
193
|
+
with connector.storage()(storage_opts) as storage:
|
|
192
194
|
hosts = storage.resolve_fdnds_by_query(args.query)
|
|
193
195
|
perc = int(pool.tasks_done / len(hosts) * 100)
|
|
194
196
|
fqdn = hosts[task_result.device_id]
|
|
@@ -210,7 +212,9 @@ def log_host_progress_cb(pool: Parallel, task_result: TaskResult):
|
|
|
210
212
|
# =====
|
|
211
213
|
def gen(args: cli_args.ShowGenOptions):
|
|
212
214
|
""" Сгенерировать конфиг для устройств """
|
|
213
|
-
|
|
215
|
+
connector = storage_connector.get()
|
|
216
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
217
|
+
with connector.storage()(storage_opts) as storage:
|
|
214
218
|
loader = ann_gen.Loader(storage, args)
|
|
215
219
|
stdin = args.stdin(storage=storage, filter_acl=args.filter_acl, config=None)
|
|
216
220
|
|
|
@@ -243,7 +247,9 @@ def _diff_files(old_files, new_files, context=3):
|
|
|
243
247
|
def patch(args: cli_args.ShowPatchOptions):
|
|
244
248
|
""" Сгенерировать патч для устройств """
|
|
245
249
|
global live_configs # pylint: disable=global-statement
|
|
246
|
-
|
|
250
|
+
connector = storage_connector.get()
|
|
251
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
252
|
+
with connector.storage()(storage_opts) as storage:
|
|
247
253
|
loader = ann_gen.Loader(storage, args)
|
|
248
254
|
if args.config == "running":
|
|
249
255
|
fetcher = annet.deploy.fetcher_connector.get()
|
|
@@ -286,7 +292,9 @@ def _patch_worker(device_id, args: cli_args.ShowPatchOptions, stdin, loader: ann
|
|
|
286
292
|
# =====
|
|
287
293
|
def res_diff_patch(device_id, args: cli_args.ShowPatchOptions, stdin, loader: ann_gen.Loader, filterer: filtering.Filterer) -> Iterable[
|
|
288
294
|
Tuple[OldNewResult, Dict, Dict]]:
|
|
289
|
-
|
|
295
|
+
connector = storage_connector.get()
|
|
296
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
297
|
+
with connector.storage()(storage_opts) as storage:
|
|
290
298
|
for res in ann_gen.old_new(
|
|
291
299
|
args,
|
|
292
300
|
storage,
|
|
@@ -314,7 +322,9 @@ def res_diff_patch(device_id, args: cli_args.ShowPatchOptions, stdin, loader: an
|
|
|
314
322
|
|
|
315
323
|
def diff(args: cli_args.DiffOptions, loader: ann_gen.Loader, filterer: filtering.Filterer) -> Mapping[Device, Union[Diff, PCDiff]]:
|
|
316
324
|
ret = {}
|
|
317
|
-
|
|
325
|
+
connector = storage_connector.get()
|
|
326
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
327
|
+
with connector.storage()(storage_opts) as storage:
|
|
318
328
|
for res in ann_gen.old_new(
|
|
319
329
|
args,
|
|
320
330
|
storage,
|
|
@@ -624,7 +634,9 @@ def deploy(args: cli_args.DeployOptions) -> ExitCode:
|
|
|
624
634
|
""" Сгенерировать конфиг для устройств и задеплоить его """
|
|
625
635
|
ret: ExitCode = 0
|
|
626
636
|
deployer = Deployer(args)
|
|
627
|
-
|
|
637
|
+
connector = storage_connector.get()
|
|
638
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
639
|
+
with connector.storage()(storage_opts) as storage:
|
|
628
640
|
global live_configs # pylint: disable=global-statement
|
|
629
641
|
loader = ann_gen.Loader(storage, args)
|
|
630
642
|
filterer = filtering.filterer_connector.get()
|
annet/cli.py
CHANGED
|
@@ -54,7 +54,9 @@ def show_current(args: cli_args.QueryOptions, config, arg_out: cli_args.FileOutO
|
|
|
54
54
|
entire_data = ""
|
|
55
55
|
yield (output_driver.entire_config_dest_path(device, entire_path), entire_data, False)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
connector = storage_connector.get()
|
|
58
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
59
|
+
with connector.storage()(storage_opts) as storage:
|
|
58
60
|
ids = storage.resolve_object_ids_by_query(args.query)
|
|
59
61
|
if not ids:
|
|
60
62
|
get_logger().error("No devices found for %s", args.query)
|
|
@@ -80,7 +82,9 @@ def gen(args: cli_args.ShowGenOptions):
|
|
|
80
82
|
@subcommand(cli_args.ShowDiffOptions)
|
|
81
83
|
def diff(args: cli_args.ShowDiffOptions):
|
|
82
84
|
""" Сгенерировать конфиг для устройств и показать дифф по рулбуку с текущим """
|
|
83
|
-
|
|
85
|
+
connector = storage_connector.get()
|
|
86
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
87
|
+
with connector.storage()(storage_opts) as storage:
|
|
84
88
|
filterer = filtering.filterer_connector.get()
|
|
85
89
|
loader = Loader(storage, args)
|
|
86
90
|
output_driver_connector.get().write_output(
|
annet/cli_args.py
CHANGED
|
@@ -433,6 +433,11 @@ class FileOutOptions(ArgGroup):
|
|
|
433
433
|
no_label = opt_no_label
|
|
434
434
|
no_color = opt_no_color
|
|
435
435
|
|
|
436
|
+
def __init__(self, *args, **kwargs):
|
|
437
|
+
super().__init__(*args, **kwargs)
|
|
438
|
+
if self.dest:
|
|
439
|
+
self.no_color = True
|
|
440
|
+
|
|
436
441
|
|
|
437
442
|
class DiffOptions(GenOptions, ComocutorOptions):
|
|
438
443
|
clear = opt_clear
|
|
@@ -467,6 +472,11 @@ class ShowDiffOptions(DiffOptions, FileOutOptions):
|
|
|
467
472
|
show_rules = opt_show_rules
|
|
468
473
|
no_collapse = opt_no_collapse
|
|
469
474
|
|
|
475
|
+
def __init__(self, *args, **kwargs):
|
|
476
|
+
super().__init__(*args, **kwargs)
|
|
477
|
+
if self.dest:
|
|
478
|
+
self.no_collapse = True
|
|
479
|
+
|
|
470
480
|
|
|
471
481
|
class ShowPatchOptions(PatchOptions, FileOutOptions):
|
|
472
482
|
indent = opt_indent
|
annet/diff.py
CHANGED
|
@@ -30,8 +30,7 @@ def gen_sort_diff(
|
|
|
30
30
|
:param diffs: Маппинг устройства в дифф
|
|
31
31
|
:param args: Параметры коммандной строки
|
|
32
32
|
"""
|
|
33
|
-
|
|
34
|
-
if args.no_collapse or args.dest:
|
|
33
|
+
if args.no_collapse:
|
|
35
34
|
devices_to_diff = {(dev,): diff for dev, diff in diffs.items()}
|
|
36
35
|
else:
|
|
37
36
|
non_pc_diffs = {dev: diff for dev, diff in diffs.items() if not isinstance(diff, PCDiff)}
|
annet/gen.py
CHANGED
|
@@ -425,7 +425,9 @@ def worker(device_id, args: ShowGenOptions, stdin, loader: "Loader", filterer: F
|
|
|
425
425
|
if span:
|
|
426
426
|
span.set_attribute("device.id", device_id)
|
|
427
427
|
|
|
428
|
-
|
|
428
|
+
connector = storage_connector.get()
|
|
429
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
430
|
+
with connector.storage()(storage_opts) as storage:
|
|
429
431
|
for res in old_new(
|
|
430
432
|
args,
|
|
431
433
|
storage,
|
|
@@ -465,7 +467,9 @@ def worker(device_id, args: ShowGenOptions, stdin, loader: "Loader", filterer: F
|
|
|
465
467
|
|
|
466
468
|
|
|
467
469
|
def old_new_worker(device_id, args: DeployOptions, config, stdin, loader: "Loader", filterer: Filterer):
|
|
468
|
-
|
|
470
|
+
connector = storage_connector.get()
|
|
471
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
472
|
+
with connector.storage()(storage_opts) as storage:
|
|
469
473
|
yield from old_new(
|
|
470
474
|
args,
|
|
471
475
|
storage,
|
annet/generators/__init__.py
CHANGED
|
@@ -538,15 +538,7 @@ def _get_generators(module_paths: Union[List[str], dict], storage, device=None):
|
|
|
538
538
|
module = importlib.import_module(module_path)
|
|
539
539
|
if hasattr(module, "get_generators"):
|
|
540
540
|
generators: List[BaseGenerator] = module.get_generators(storage)
|
|
541
|
-
|
|
542
|
-
res_generators += generators
|
|
543
|
-
else:
|
|
544
|
-
logger = get_logger()
|
|
545
|
-
for gen in generators:
|
|
546
|
-
if gen.supports_vendor(device.hw.vendor):
|
|
547
|
-
res_generators.append(gen)
|
|
548
|
-
else:
|
|
549
|
-
logger.info("generator %s does not support device vendor %s, skipping", gen, device.hw.vendor)
|
|
541
|
+
res_generators += generators
|
|
550
542
|
return res_generators
|
|
551
543
|
|
|
552
544
|
|
|
@@ -706,6 +698,12 @@ class PartialGenerator(TreeGenerator):
|
|
|
706
698
|
def run(self, device) -> Iterable[Union[str, tuple]]:
|
|
707
699
|
if hasattr(self, "run_" + device.hw.vendor):
|
|
708
700
|
return getattr(self, "run_" + device.hw.vendor)(device)
|
|
701
|
+
logger = get_logger()
|
|
702
|
+
logger.info(
|
|
703
|
+
"generator %s is not supported for vendor %s",
|
|
704
|
+
self,
|
|
705
|
+
device.hw.vendor,
|
|
706
|
+
)
|
|
709
707
|
return iter(())
|
|
710
708
|
|
|
711
709
|
def get_user_runner(self, device):
|
annet/output.py
CHANGED
|
@@ -133,7 +133,9 @@ class OutputDriverBasic(OutputDriver):
|
|
|
133
133
|
ret = []
|
|
134
134
|
fqdns = {}
|
|
135
135
|
if args:
|
|
136
|
-
|
|
136
|
+
connector = storage_connector.get()
|
|
137
|
+
storage_opts = connector.opts().from_cli_opts(args)
|
|
138
|
+
with connector.storage()(storage_opts) as storage:
|
|
137
139
|
fqdns = storage.resolve_fdnds_by_query(args.query)
|
|
138
140
|
for (assignment, exc) in fail.items():
|
|
139
141
|
label = assignment
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -21,4 +21,6 @@ Requires-Dist: contextlog >=1.1
|
|
|
21
21
|
Requires-Dist: valkit >=0.1.4
|
|
22
22
|
Requires-Dist: aiohttp >=3.8.4
|
|
23
23
|
Requires-Dist: yarl >=1.8.2
|
|
24
|
+
Requires-Dist: adaptix ==3.0.0b2
|
|
25
|
+
Requires-Dist: dataclass-rest ==0.4
|
|
24
26
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
annet/__init__.py,sha256=oyElxAW97sHgQccGafhaWVBveBn1gSjjdP_xHROaRLg,2139
|
|
2
2
|
annet/annet.py,sha256=TMdEuM7GJQ4TjRVmuK3bCTZN-21lxjQ9sXqEdILUuBk,725
|
|
3
3
|
annet/argparse.py,sha256=MoBD0LPnHdA6HU7z1uQNArYlkD92znoeGIFTMnS4dRM,12608
|
|
4
|
-
annet/cli.py,sha256=
|
|
5
|
-
annet/cli_args.py,sha256=
|
|
4
|
+
annet/cli.py,sha256=bkAaHKBYmvdaFawm_KOM7CehMm18RTR8TkMYAxm-7lo,8464
|
|
5
|
+
annet/cli_args.py,sha256=rmBTJ64sljQWFTIbhTEBZRIo08Gi9NAoFZrMermZEuY,16152
|
|
6
6
|
annet/connectors.py,sha256=M2NeyFgBEGJ_tMR9HgQ4cpli0nBciqZJDVMQXEueMws,1908
|
|
7
7
|
annet/deploy.py,sha256=B8E0P_VvCrS2URjFvgmUiIkHp95g7pAWfmT34igaDeo,18893
|
|
8
|
-
annet/diff.py,sha256=
|
|
8
|
+
annet/diff.py,sha256=zLcaCnb4lZRUb7frpH1CstQ3kacRcCblZs1uLG8J5lk,3391
|
|
9
9
|
annet/executor.py,sha256=bw7COJNtssuxIqbQehlHYJnkdUeYvvL8WO5B-c67XE0,19040
|
|
10
10
|
annet/filtering.py,sha256=F4ZKUCU3Yb1RlL2zKdyHtVUaWPzjWF4vWyMcdygKNYk,852
|
|
11
|
-
annet/gen.py,sha256=
|
|
11
|
+
annet/gen.py,sha256=WC3ZMjTKtUCRXE4yy-Z3n5MOm3LkLJbXvspyfW8BeVs,31426
|
|
12
12
|
annet/hardware.py,sha256=HYPDfji_GdRn5S0_0fl4rvM7byOY9aHxG6VMAtsLaxE,1090
|
|
13
13
|
annet/implicit.py,sha256=QigK4uoxvrFho2h9yFjOq1d9rLsC5xFlAU4bKkCuMWk,5139
|
|
14
14
|
annet/lib.py,sha256=zQIfNBg7fAAk2BHbHAqy_McAiXhz0RqpBAcfdU-6pAA,3742
|
|
15
|
-
annet/output.py,sha256=
|
|
15
|
+
annet/output.py,sha256=XsX3o4vxe7Ayw7ocY-pV5VY-9-D5_Q_yeWy2ZY1Hubk,7090
|
|
16
16
|
annet/parallel.py,sha256=hLkzEht0KhzmzUWDdO4QFYQHzhxs3wPlTA8DxbB2ziw,17160
|
|
17
17
|
annet/patching.py,sha256=nILbY5oJajN0b1j3f0HEJm05H3HVThnWvB7vDVh7UQw,559
|
|
18
18
|
annet/reference.py,sha256=B8mH8VUMcecPnzULiTVb_kTQ7jQrCL7zp4pfIZQa5fk,4035
|
|
@@ -21,6 +21,24 @@ annet/tabparser.py,sha256=ZjiI43ZVbrpMVR8qNbTbNh_U3oZ26VDc_2Y9wkkDkYA,874
|
|
|
21
21
|
annet/text_term_format.py,sha256=CHb6viv45vmYl-SK1A1vyPHGhaEni6jVybBusaQnct8,2813
|
|
22
22
|
annet/tracing.py,sha256=ndpM-au1c88uBBpOuH_z52qWZL773edYozNyys_wA68,4044
|
|
23
23
|
annet/types.py,sha256=f0iwSJGSQ7GvWeXgXqBCoxzYNezMa4YASQEHJzWUrWU,6962
|
|
24
|
+
annet/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
annet/adapters/netbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
annet/adapters/netbox/provider.py,sha256=OM7Hq2vnMHNVBfubJvx2qJlMYm3VvKhomdLMNO8YnLQ,1024
|
|
27
|
+
annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
annet/adapters/netbox/common/client.py,sha256=-lWZmphD-OPuLIHNKhW_h2bnjrVaiyKYAD_MUPasEbo,2483
|
|
29
|
+
annet/adapters/netbox/common/manufacturer.py,sha256=UH_tEKT3GXC8WSm15q0xxXRE7aj0b0icgwmR--PRWBs,1771
|
|
30
|
+
annet/adapters/netbox/common/models.py,sha256=Kti1T54emv6_FUkhgRiSIo_ZdmvWZZTRvooHO2_H1bM,1731
|
|
31
|
+
annet/adapters/netbox/common/query.py,sha256=OgUuF-bvshpoBUkrOs0tsMUAhjTsttzx3VV30ryFl0Y,577
|
|
32
|
+
annet/adapters/netbox/common/status_client.py,sha256=3oozmdfewPXODEkNrDRfcz_pTeXRVDQiNiD-AE6Lrug,567
|
|
33
|
+
annet/adapters/netbox/common/storage_opts.py,sha256=rl_0pr3VzmOy6PDZIUMkKSBfJh90gD9TFL3yBhK_8ME,337
|
|
34
|
+
annet/adapters/netbox/v24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
+
annet/adapters/netbox/v24/api_models.py,sha256=xG3n9ILYdD2jNxav8IH6Bm6fX4vbHPUkHBLze4Ly1bc,1314
|
|
36
|
+
annet/adapters/netbox/v24/client.py,sha256=-r91zVTThn12mN1zBj3XNyqlP6BGOrAPm_GbBT2bXpI,1497
|
|
37
|
+
annet/adapters/netbox/v24/storage.py,sha256=SCTSOea8OHiLAPmBXIop80mIUOLuA48rLpKlitYJt1k,5620
|
|
38
|
+
annet/adapters/netbox/v37/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
annet/adapters/netbox/v37/api_models.py,sha256=O59bYesIWlxHx3C2TW4TQnfN9YMsE_rbiw2mYsormcc,886
|
|
40
|
+
annet/adapters/netbox/v37/client.py,sha256=GgFIV5IGlyEplvwOLLd1BxtsbPWkeHEtL22kWV_X0b0,1668
|
|
41
|
+
annet/adapters/netbox/v37/storage.py,sha256=5jp2AgalijTdFkMnjvGGGnxqjwk-bn6QWzTRTfNyyHM,4216
|
|
24
42
|
annet/annlib/__init__.py,sha256=fT1l4xV5fqqg8HPw9HqmZVN2qwS8i6X1aIm2zGDjxKY,252
|
|
25
43
|
annet/annlib/command.py,sha256=uuBddMQphtn8P5MO5kzIa8_QrtMns-k05VeKv1bcAuA,1043
|
|
26
44
|
annet/annlib/diff.py,sha256=UPt3kYFQdQdVVy3ePYzNHPAxMVmHxCrCnZnMCV6ou2Q,4587
|
|
@@ -47,10 +65,10 @@ annet/annlib/rbparser/platform.py,sha256=iyqy4A-6vUKM4j6hrOA6tsgWBXk7LcvkFrS2QHg
|
|
|
47
65
|
annet/annlib/rbparser/syntax.py,sha256=eEUmszwPjdw57aofUYNQVcaxHPNV9yx9JNapjYY-BGM,3572
|
|
48
66
|
annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
67
|
annet/annlib/rulebook/common.py,sha256=9kCZwZpsH5UliF2OzaN9nLs2eLlz_d__4L7_oZ3SrCw,16054
|
|
50
|
-
annet/api/__init__.py,sha256=
|
|
68
|
+
annet/api/__init__.py,sha256=VooP9u9f6e8vF7FPUE-r0JAGqCjck9-2b0dVNWAtoLM,33752
|
|
51
69
|
annet/configs/context.yml,sha256=nt4QnzYzrG2hqmaWOUsab2wgFl-CXmFSzbto6rqqFt4,291
|
|
52
70
|
annet/configs/logging.yaml,sha256=Hu42lRK248dssp9TgkbHCaZNl0E6f4IChGb0XaQnTVo,970
|
|
53
|
-
annet/generators/__init__.py,sha256=
|
|
71
|
+
annet/generators/__init__.py,sha256=LQoqGz_0imhtxvyuwBrBpB6iSuzS2S0UxNJEpO77BiM,33829
|
|
54
72
|
annet/generators/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
73
|
annet/generators/common/initial.py,sha256=XI7uWLMuLrHC-uXm38oRbM1YVuELAvMHLZFHM9x5IF8,1229
|
|
56
74
|
annet/rulebook/__init__.py,sha256=14IpOfTbeJtre7JKrfXVYiH0qAXsUSOL7AatUFmSQs0,3847
|
|
@@ -102,12 +120,10 @@ annet/rulebook/texts/routeros.rul,sha256=ipfxjj0mjFef6IsUlupqx4BY_Je_OUb8u_U1019
|
|
|
102
120
|
annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
121
|
annet_generators/example/__init__.py,sha256=zVd8_DrXuOASrNzg2Ab94rPyvJff83L-_HppDFxnUjM,228
|
|
104
122
|
annet_generators/example/lldp.py,sha256=68CLrK7vxTQQy9XIBxtywuEdBNlIlfXGYj8_wYWs5UI,1146
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
annet-0.
|
|
108
|
-
annet-0.
|
|
109
|
-
annet-0.
|
|
110
|
-
annet-0.
|
|
111
|
-
annet-0.
|
|
112
|
-
annet-0.6.dist-info/top_level.txt,sha256=uL47QByRwuZV5yWC58gd4IkHM8sVSAJ1pZb-6W-gMfY,38
|
|
113
|
-
annet-0.6.dist-info/RECORD,,
|
|
123
|
+
annet-0.7.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
|
|
124
|
+
annet-0.7.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
|
|
125
|
+
annet-0.7.dist-info/METADATA,sha256=hkf7Zql0Tekm9u10L6exfVSV6LjhQ7367c7VZ8WxOw8,691
|
|
126
|
+
annet-0.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
127
|
+
annet-0.7.dist-info/entry_points.txt,sha256=yHimujIzR2bwNIbb--MTs_GpXiAve89Egpu2LlgTEkg,119
|
|
128
|
+
annet-0.7.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
|
|
129
|
+
annet-0.7.dist-info/RECORD,,
|