annet 0.14.9__py3-none-any.whl → 0.14.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/netbox/common/query.py +3 -0
- annet/annlib/rbparser/syntax.py +1 -1
- annet/cli.py +64 -4
- annet/gen.py +3 -0
- annet/implicit.py +8 -0
- annet/storage.py +4 -1
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/METADATA +1 -1
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/RECORD +13 -13
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/AUTHORS +0 -0
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/LICENSE +0 -0
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/WHEEL +0 -0
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/entry_points.txt +0 -0
- {annet-0.14.9.dist-info → annet-0.14.10.dist-info}/top_level.txt +0 -0
annet/annlib/rbparser/syntax.py
CHANGED
|
@@ -31,7 +31,7 @@ def compile_row_regexp(row, flags=0):
|
|
|
31
31
|
row = row[:-3]
|
|
32
32
|
elif "~/" in row:
|
|
33
33
|
# ~/{regex}/ -> {regex}, () не нужны поскольку уже (?:) - non-captured
|
|
34
|
-
row = re.sub(r"~/(
|
|
34
|
+
row = re.sub(r"~/(((?!~/).)+)/", r"\1", row)
|
|
35
35
|
else:
|
|
36
36
|
row += r"(?:\s|$)"
|
|
37
37
|
row = re.sub(r"\s+", r"\\s+", row)
|
annet/cli.py
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
import argparse
|
|
2
|
+
import itertools
|
|
3
|
+
import json
|
|
2
4
|
import operator
|
|
3
5
|
import os
|
|
4
6
|
import platform
|
|
5
7
|
import subprocess
|
|
6
8
|
import shutil
|
|
9
|
+
import sys
|
|
7
10
|
from contextlib import ExitStack, contextmanager
|
|
8
11
|
from typing import Tuple, Iterable
|
|
9
12
|
|
|
13
|
+
import tabulate
|
|
10
14
|
import yaml
|
|
11
15
|
from contextlog import get_logger
|
|
12
16
|
from valkit.python import valid_logging_level
|
|
13
17
|
|
|
14
18
|
from annet.deploy import driver_connector, fetcher_connector
|
|
15
|
-
from annet import api, cli_args, filtering
|
|
19
|
+
from annet import api, cli_args, filtering, generators
|
|
16
20
|
from annet.api import collapse_texts, Deployer
|
|
17
21
|
from annet.argparse import ArgParser, subcommand
|
|
18
22
|
from annet.diff import gen_sort_diff
|
|
19
23
|
from annet.gen import Loader, old_raw
|
|
20
24
|
from annet.lib import get_context_path, repair_context_file
|
|
21
25
|
from annet.output import output_driver_connector, OutputDriver
|
|
22
|
-
from annet.storage import get_storage
|
|
26
|
+
from annet.storage import get_storage, Device
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
def fill_base_args(parser: ArgParser, pkg_name: str, logging_config: str):
|
|
@@ -60,14 +64,14 @@ def _gen_current_items(
|
|
|
60
64
|
|
|
61
65
|
|
|
62
66
|
@contextmanager
|
|
63
|
-
def get_loader(gen_args: cli_args.GenOptions, args: cli_args.
|
|
67
|
+
def get_loader(gen_args: cli_args.GenOptions, args: cli_args.QueryOptionsBase):
|
|
64
68
|
exit_stack = ExitStack()
|
|
65
69
|
storages = []
|
|
66
70
|
with exit_stack:
|
|
67
71
|
connector, connector_opts = get_storage()
|
|
68
72
|
storage_opts = connector.opts().parse_params(connector_opts, args)
|
|
69
73
|
storages.append(exit_stack.enter_context(connector.storage()(storage_opts)))
|
|
70
|
-
yield Loader(*storages, args=gen_args)
|
|
74
|
+
yield Loader(*storages, args=gen_args, no_empty_warning=args.query.is_empty())
|
|
71
75
|
|
|
72
76
|
|
|
73
77
|
@subcommand(is_group=True)
|
|
@@ -120,6 +124,62 @@ def show_device_dump(args: cli_args.QueryOptions, arg_out: cli_args.FileOutOptio
|
|
|
120
124
|
)
|
|
121
125
|
|
|
122
126
|
|
|
127
|
+
@subcommand(cli_args.ShowGeneratorsOptions, parent=show)
|
|
128
|
+
def show_generators(args: cli_args.ShowGeneratorsOptions):
|
|
129
|
+
""" List applicable generators (for a device if query is set) """
|
|
130
|
+
arg_gens = cli_args.GenOptions(args)
|
|
131
|
+
with get_loader(arg_gens, args) as loader:
|
|
132
|
+
device: Device | None = None
|
|
133
|
+
devices = loader.devices
|
|
134
|
+
if len(devices) == 1:
|
|
135
|
+
device = devices[0]
|
|
136
|
+
elif len(devices) > 1:
|
|
137
|
+
get_logger().error("cannot show generators for more than one device at once")
|
|
138
|
+
sys.exit(1)
|
|
139
|
+
elif len(devices) == 0 and not args.query.is_empty():
|
|
140
|
+
# the error message will be logged in get_loader()
|
|
141
|
+
sys.exit(1)
|
|
142
|
+
|
|
143
|
+
if not device:
|
|
144
|
+
found_generators = loader.iter_all_gens()
|
|
145
|
+
else:
|
|
146
|
+
found_generators = []
|
|
147
|
+
gens = loader.resolve_gens(loader.devices)
|
|
148
|
+
for g in gens.partial[device]:
|
|
149
|
+
acl_func = g.acl_safe if args.acl_safe else g.acl
|
|
150
|
+
if g.supports_device(device) and acl_func(device):
|
|
151
|
+
found_generators.append(g)
|
|
152
|
+
for g in gens.entire[device]:
|
|
153
|
+
if g.supports_device(device) and g.path(device):
|
|
154
|
+
found_generators.append(g)
|
|
155
|
+
for g in gens.json_fragment[device]:
|
|
156
|
+
if g.supports_device(device) and g.path(device) and g.acl(device):
|
|
157
|
+
found_generators.append(g)
|
|
158
|
+
|
|
159
|
+
output_data = []
|
|
160
|
+
for g in found_generators:
|
|
161
|
+
output_data.append({
|
|
162
|
+
"name": g.__class__.__name__,
|
|
163
|
+
"type": g.TYPE,
|
|
164
|
+
"tags": g.TAGS,
|
|
165
|
+
"module": g.__class__.__module__,
|
|
166
|
+
"description": generators.get_description(g.__class__),
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
if args.format == "json":
|
|
170
|
+
print(json.dumps(output_data))
|
|
171
|
+
|
|
172
|
+
elif args.format == "text":
|
|
173
|
+
keyfunc = operator.itemgetter("type")
|
|
174
|
+
for gen_type, gens in itertools.groupby(sorted(output_data, key=keyfunc, reverse=True), keyfunc):
|
|
175
|
+
print(tabulate.tabulate(
|
|
176
|
+
[(g["name"], ", ".join(g["tags"]), g["module"], g["description"]) for g in gens],
|
|
177
|
+
[f"{gen_type}-Class", "Tags", "Module", "Description"],
|
|
178
|
+
tablefmt="orgtbl",
|
|
179
|
+
))
|
|
180
|
+
print()
|
|
181
|
+
|
|
182
|
+
|
|
123
183
|
@subcommand(cli_args.ShowGenOptions)
|
|
124
184
|
def gen(args: cli_args.ShowGenOptions):
|
|
125
185
|
""" Generate configuration for devices """
|
annet/gen.py
CHANGED
annet/implicit.py
CHANGED
|
@@ -132,6 +132,14 @@ def _implicit_tree(device):
|
|
|
132
132
|
!neighbor *
|
|
133
133
|
no shutdown
|
|
134
134
|
"""
|
|
135
|
+
elif device.hw.Cisco:
|
|
136
|
+
if device.hw.Cisco.Catalyst:
|
|
137
|
+
# this configuration is not visible in running-config when enabled
|
|
138
|
+
text += r"""
|
|
139
|
+
# line console aaa config
|
|
140
|
+
!line con 0
|
|
141
|
+
authorization exec default
|
|
142
|
+
"""
|
|
135
143
|
return parse_text(text)
|
|
136
144
|
|
|
137
145
|
|
annet/storage.py
CHANGED
|
@@ -75,10 +75,13 @@ class StorageOpts(abc.ABC):
|
|
|
75
75
|
|
|
76
76
|
class Query(abc.ABC):
|
|
77
77
|
@classmethod
|
|
78
|
-
@abc.
|
|
78
|
+
@abc.abstractmethod
|
|
79
79
|
def new(cls, query: Union[str, Iterable[str]], hosts_range: Optional[slice] = None) -> "Query":
|
|
80
80
|
pass
|
|
81
81
|
|
|
82
|
+
def is_empty(self) -> bool:
|
|
83
|
+
return False
|
|
84
|
+
|
|
82
85
|
|
|
83
86
|
class Device(Protocol):
|
|
84
87
|
@property
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
annet/__init__.py,sha256=oyElxAW97sHgQccGafhaWVBveBn1gSjjdP_xHROaRLg,2139
|
|
2
2
|
annet/annet.py,sha256=TMdEuM7GJQ4TjRVmuK3bCTZN-21lxjQ9sXqEdILUuBk,725
|
|
3
3
|
annet/argparse.py,sha256=ZHKQriVCysSnox5stZnYxKLaPKzDjXbShxFyNW6LiiQ,12754
|
|
4
|
-
annet/cli.py,sha256=
|
|
4
|
+
annet/cli.py,sha256=yUStwwUKGgGuNw94EvabUEMhBs0YsIsc4omUivst8H0,12366
|
|
5
5
|
annet/cli_args.py,sha256=_Du9Jhe86F4fsx7u9njjvg25jTdoBsdbTEzbuDFgrFU,13248
|
|
6
6
|
annet/connectors.py,sha256=Xgr7fNopRhFAYnkiDxhohBtjlFOLY8v0xLExHmVMr00,2511
|
|
7
7
|
annet/deploy.py,sha256=B8E0P_VvCrS2URjFvgmUiIkHp95g7pAWfmT34igaDeo,18893
|
|
8
8
|
annet/diff.py,sha256=zLcaCnb4lZRUb7frpH1CstQ3kacRcCblZs1uLG8J5lk,3391
|
|
9
9
|
annet/executor.py,sha256=FrYAUuh2TpSVX42SlTN_PhuSHmXG4Wj1nieY9Wqv9so,19122
|
|
10
10
|
annet/filtering.py,sha256=F4ZKUCU3Yb1RlL2zKdyHtVUaWPzjWF4vWyMcdygKNYk,852
|
|
11
|
-
annet/gen.py,sha256=
|
|
11
|
+
annet/gen.py,sha256=8IPejduvYXmezUDolLKg4Imt1TxEp0KJ7kSgMtFcaCY,33628
|
|
12
12
|
annet/hardware.py,sha256=HYPDfji_GdRn5S0_0fl4rvM7byOY9aHxG6VMAtsLaxE,1090
|
|
13
|
-
annet/implicit.py,sha256=
|
|
13
|
+
annet/implicit.py,sha256=_3eY9NKqpLUm25vlJIP2cHN4gdTgzO6rG6mwCKJYMnQ,5439
|
|
14
14
|
annet/lib.py,sha256=tQQlxZg1A2Q-tp18PoqBuORQmvP5dAAmAPvP6bBA6a0,3764
|
|
15
15
|
annet/output.py,sha256=hJNGzL4Z3KgvqaCBkkmuuiXPhb64F1QV8YHkwnfhaaI,6852
|
|
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
|
|
19
|
-
annet/storage.py,sha256
|
|
19
|
+
annet/storage.py,sha256=Wr_D_w7JQD08nD2IvC6bcGJLH6Uv62tKznUyWWWVW5Q,3144
|
|
20
20
|
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
|
|
@@ -28,7 +28,7 @@ annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
28
28
|
annet/adapters/netbox/common/client.py,sha256=-lWZmphD-OPuLIHNKhW_h2bnjrVaiyKYAD_MUPasEbo,2483
|
|
29
29
|
annet/adapters/netbox/common/manufacturer.py,sha256=i-1mXQheS4ORZav1_xYxMuGBWVWQHolZYkEXNdGyf0g,1361
|
|
30
30
|
annet/adapters/netbox/common/models.py,sha256=Vgxbl_Mm-zOAi2BTlEzDppTTgZjafFEC5F9s_MTd_xU,3263
|
|
31
|
-
annet/adapters/netbox/common/query.py,sha256=
|
|
31
|
+
annet/adapters/netbox/common/query.py,sha256=ziUFM7cUEbEIf3k1szTll4aO-OCUa-2Ogxbebi7Tegs,646
|
|
32
32
|
annet/adapters/netbox/common/status_client.py,sha256=W4nTb2yvBlJ2UkWUmUhKQ2PaSQb1shjhHj5ebb4s2s4,591
|
|
33
33
|
annet/adapters/netbox/common/storage_opts.py,sha256=idOm1na_2Axdi4MdLN4tAsPvsp5zBtJYD9j7cUiI-W8,400
|
|
34
34
|
annet/adapters/netbox/v24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -58,7 +58,7 @@ annet/annlib/rbparser/acl.py,sha256=RR8yPt6t96_IiyuKVbeZ-3x32cyhBAT2wC1y99oWBO8,
|
|
|
58
58
|
annet/annlib/rbparser/deploying.py,sha256=ACT8QNhDAhJx3ZKuGh2nYBOrpdka2qEKuLDxvQAGKLk,1649
|
|
59
59
|
annet/annlib/rbparser/ordering.py,sha256=DiKqyY8Khz-5MTxNF1GSNtZgtyKwT3YYCXpahIPB6Ps,1779
|
|
60
60
|
annet/annlib/rbparser/platform.py,sha256=iyqy4A-6vUKM4j6hrOA6tsgWBXk7LcvkFrS2QHgkqho,1231
|
|
61
|
-
annet/annlib/rbparser/syntax.py,sha256=
|
|
61
|
+
annet/annlib/rbparser/syntax.py,sha256=iZ7Y-4QQBw4L3UtjEh54qisiRDhobl7HZxFNdP8mi54,3577
|
|
62
62
|
annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
annet/annlib/rulebook/common.py,sha256=9kCZwZpsH5UliF2OzaN9nLs2eLlz_d__4L7_oZ3SrCw,16054
|
|
64
64
|
annet/api/__init__.py,sha256=-G9wlYePC3ZgNo1p8r17vmx0WLb3UNvCw3ZJ9UhYJ-I,33169
|
|
@@ -124,10 +124,10 @@ annet/rulebook/texts/routeros.rul,sha256=ipfxjj0mjFef6IsUlupqx4BY_Je_OUb8u_U1019
|
|
|
124
124
|
annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
125
125
|
annet_generators/example/__init__.py,sha256=zVd8_DrXuOASrNzg2Ab94rPyvJff83L-_HppDFxnUjM,228
|
|
126
126
|
annet_generators/example/lldp.py,sha256=68CLrK7vxTQQy9XIBxtywuEdBNlIlfXGYj8_wYWs5UI,1146
|
|
127
|
-
annet-0.14.
|
|
128
|
-
annet-0.14.
|
|
129
|
-
annet-0.14.
|
|
130
|
-
annet-0.14.
|
|
131
|
-
annet-0.14.
|
|
132
|
-
annet-0.14.
|
|
133
|
-
annet-0.14.
|
|
127
|
+
annet-0.14.10.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
|
|
128
|
+
annet-0.14.10.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
|
|
129
|
+
annet-0.14.10.dist-info/METADATA,sha256=OvFvw8iDLiH6ZmTlDQIPwkONw9LHMEIcWldHqTtgAhA,695
|
|
130
|
+
annet-0.14.10.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
|
131
|
+
annet-0.14.10.dist-info/entry_points.txt,sha256=yHimujIzR2bwNIbb--MTs_GpXiAve89Egpu2LlgTEkg,119
|
|
132
|
+
annet-0.14.10.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
|
|
133
|
+
annet-0.14.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|