annet 2.2.1__py3-none-any.whl → 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of annet might be problematic. Click here for more details.
- annet/api/__init__.py +32 -96
- annet/cli.py +15 -8
- annet/cli_args.py +1 -0
- annet/deploy_ui.py +1 -2
- annet/diff.py +102 -9
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/METADATA +1 -1
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/RECORD +12 -12
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/WHEEL +1 -1
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/AUTHORS +0 -0
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/LICENSE +0 -0
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/entry_points.txt +0 -0
- {annet-2.2.1.dist-info → annet-2.3.0.dist-info}/top_level.txt +0 -0
annet/api/__init__.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import abc
|
|
2
|
+
import inspect
|
|
2
3
|
import os
|
|
3
4
|
import re
|
|
4
5
|
import sys
|
|
@@ -8,13 +9,11 @@ from collections import OrderedDict as odict
|
|
|
8
9
|
from itertools import groupby, chain
|
|
9
10
|
from operator import itemgetter
|
|
10
11
|
from typing import (
|
|
11
|
-
Any,
|
|
12
12
|
Dict,
|
|
13
13
|
Generator,
|
|
14
14
|
Iterable,
|
|
15
15
|
List,
|
|
16
16
|
Mapping,
|
|
17
|
-
Optional,
|
|
18
17
|
Set,
|
|
19
18
|
Tuple,
|
|
20
19
|
Union, cast,
|
|
@@ -41,7 +40,6 @@ from annet.rulebook import deploying
|
|
|
41
40
|
from annet.filtering import Filterer
|
|
42
41
|
from annet.hardware import hardware_connector
|
|
43
42
|
from annet.output import (
|
|
44
|
-
LABEL_NEW_PREFIX,
|
|
45
43
|
format_file_diff,
|
|
46
44
|
output_driver_connector,
|
|
47
45
|
print_err_label,
|
|
@@ -51,7 +49,6 @@ from annet.reference import RefTracker
|
|
|
51
49
|
from annet.storage import Device, get_storage
|
|
52
50
|
from annet.types import Diff, ExitCode, OldNewResult, Op, PCDiff, PCDiffFile
|
|
53
51
|
|
|
54
|
-
|
|
55
52
|
DEFAULT_INDENT = " "
|
|
56
53
|
|
|
57
54
|
|
|
@@ -240,15 +237,6 @@ def gen(args: cli_args.ShowGenOptions, loader: ann_gen.Loader):
|
|
|
240
237
|
|
|
241
238
|
|
|
242
239
|
# =====
|
|
243
|
-
def _diff_files(hw, old_files, new_files):
|
|
244
|
-
ret = {}
|
|
245
|
-
differ = file_differ_connector.get()
|
|
246
|
-
for (path, (new_text, reload_data)) in new_files.items():
|
|
247
|
-
old_text = old_files.get(path)
|
|
248
|
-
is_new = old_text is None
|
|
249
|
-
diff_lines = differ.diff_file(hw, path, old_text, new_text)
|
|
250
|
-
ret[path] = (diff_lines, reload_data, is_new)
|
|
251
|
-
return ret
|
|
252
240
|
|
|
253
241
|
|
|
254
242
|
def patch(args: cli_args.ShowPatchOptions, loader: ann_gen.Loader):
|
|
@@ -322,62 +310,39 @@ def res_diff_patch(
|
|
|
322
310
|
|
|
323
311
|
|
|
324
312
|
def diff(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
device_ids: List[int],
|
|
328
|
-
filterer: filtering.Filterer,
|
|
313
|
+
args: cli_args.DiffOptions,
|
|
314
|
+
loader: ann_gen.Loader,
|
|
329
315
|
) -> Mapping[Device, Union[Diff, PCDiff]]:
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
args,
|
|
333
|
-
config=args.config,
|
|
334
|
-
loader=loader,
|
|
335
|
-
no_new=args.clear,
|
|
336
|
-
do_files_download=True,
|
|
337
|
-
device_ids=device_ids,
|
|
338
|
-
filterer=filterer,
|
|
339
|
-
):
|
|
340
|
-
old = res.get_old(args.acl_safe)
|
|
341
|
-
new = res.get_new(args.acl_safe)
|
|
342
|
-
device = res.device
|
|
343
|
-
acl_rules = res.get_acl_rules(args.acl_safe)
|
|
344
|
-
new_files = res.get_new_files(args.acl_safe)
|
|
345
|
-
new_json_fragment_files = res.get_new_file_fragments(args.acl_safe)
|
|
346
|
-
|
|
347
|
-
pc_diff_files = []
|
|
348
|
-
if res.old_files or new_files:
|
|
349
|
-
pc_diff_files.extend(_pc_diff(res.device.hw, device.hostname, res.old_files, new_files))
|
|
350
|
-
if res.old_json_fragment_files or new_json_fragment_files:
|
|
351
|
-
pc_diff_files.extend(_json_fragment_diff(res.device.hw, device.hostname, res.old_json_fragment_files, new_json_fragment_files))
|
|
316
|
+
""" Сгенерировать конфиг для устройств """
|
|
317
|
+
stdin = args.stdin(filter_acl=args.filter_acl, config=None)
|
|
352
318
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
orderer = patching.Orderer.from_hw(device.hw)
|
|
358
|
-
rb = rulebook.get_rulebook(device.hw)
|
|
359
|
-
diff_tree = patching.make_diff(
|
|
360
|
-
old,
|
|
361
|
-
orderer.order_config(new),
|
|
362
|
-
rb,
|
|
363
|
-
[acl_rules, res.filter_acl_rules],
|
|
364
|
-
)
|
|
365
|
-
diff_tree = patching.strip_unchanged(diff_tree)
|
|
366
|
-
ret[device] = diff_tree
|
|
319
|
+
filterer = filtering.filterer_connector.get()
|
|
320
|
+
pool = Parallel(ann_diff.worker, args, stdin, loader, filterer).tune_args(args)
|
|
321
|
+
if args.show_hosts_progress:
|
|
322
|
+
pool.add_callback(PoolProgressLogger(loader.device_fqdns))
|
|
367
323
|
|
|
368
|
-
return
|
|
324
|
+
return pool.run(loader.device_ids, args.tolerate_fails, args.strict_exit_code)
|
|
369
325
|
|
|
370
326
|
|
|
371
|
-
def collapse_texts(texts: Mapping[str, str]) -> Mapping[Tuple[str, ...], str]:
|
|
327
|
+
def collapse_texts(texts: Mapping[str, str | Generator[str, None, None]]) -> Mapping[Tuple[str, ...], str]:
|
|
372
328
|
"""
|
|
373
329
|
Группировка текстов.
|
|
374
330
|
:param texts:
|
|
375
331
|
:return: словарь с несколькими хостнеймами в ключе.
|
|
376
332
|
"""
|
|
377
|
-
diffs_with_orig = {
|
|
333
|
+
diffs_with_orig = {}
|
|
334
|
+
for key, value in texts.items():
|
|
335
|
+
if inspect.isgenerator(value):
|
|
336
|
+
lines = list(value)
|
|
337
|
+
diffs_with_orig[key] = ["".join(lines), lines]
|
|
338
|
+
else:
|
|
339
|
+
diffs_with_orig[key] = [value, value.splitlines()]
|
|
340
|
+
|
|
378
341
|
res = {}
|
|
379
|
-
for _, collapsed_diff_iter in groupby(
|
|
380
|
-
|
|
342
|
+
for _, collapsed_diff_iter in groupby(
|
|
343
|
+
sorted(diffs_with_orig.items(), key=lambda x: (x[0], x[1][1])),
|
|
344
|
+
key=lambda x: x[1][1]
|
|
345
|
+
):
|
|
381
346
|
collapsed_diff = list(collapsed_diff_iter)
|
|
382
347
|
res[tuple(x[0] for x in collapsed_diff)] = collapsed_diff[0][1][0]
|
|
383
348
|
|
|
@@ -744,8 +709,10 @@ def file_diff(args: cli_args.FileDiffOptions):
|
|
|
744
709
|
return pool.run(old_new, tolerate_fails=True)
|
|
745
710
|
|
|
746
711
|
|
|
747
|
-
def file_diff_worker(
|
|
748
|
-
Tuple[str, str
|
|
712
|
+
def file_diff_worker(
|
|
713
|
+
old_new: Tuple[str, str],
|
|
714
|
+
args: cli_args.FileDiffOptions
|
|
715
|
+
) -> Generator[Tuple[str, str, bool], None, None]:
|
|
749
716
|
old_path, new_path = old_new
|
|
750
717
|
hw = args.hw
|
|
751
718
|
if isinstance(args.hw, str):
|
|
@@ -753,10 +720,12 @@ def file_diff_worker(old_new: Tuple[str, str], args: cli_args.FileDiffOptions) -
|
|
|
753
720
|
|
|
754
721
|
if os.path.isdir(old_path) and os.path.isdir(new_path):
|
|
755
722
|
hostname = os.path.basename(new_path)
|
|
756
|
-
new_files = {
|
|
757
|
-
|
|
723
|
+
new_files = {
|
|
724
|
+
relative_cfg_path: (cfg_text, "")
|
|
725
|
+
for relative_cfg_path, cfg_text in ann_gen.load_pc_config(new_path).items()
|
|
726
|
+
}
|
|
758
727
|
old_files = ann_gen.load_pc_config(old_path)
|
|
759
|
-
for diff_file in
|
|
728
|
+
for diff_file in ann_diff.pc_diff(hw, hostname, old_files, new_files):
|
|
760
729
|
diff_text = (
|
|
761
730
|
"\n".join(diff_file.diff_lines)
|
|
762
731
|
if args.no_color
|
|
@@ -796,39 +765,6 @@ def file_patch_worker(old_new: Tuple[str, str], args: cli_args.FileDiffOptions)
|
|
|
796
765
|
yield dest_name, patch_text, False
|
|
797
766
|
|
|
798
767
|
|
|
799
|
-
def _pc_diff(hw, hostname: str, old_files: Dict[str, str], new_files: Dict[str, str]) -> Generator[PCDiffFile, None, None]:
|
|
800
|
-
sorted_lines = sorted(_diff_files(hw, old_files, new_files).items())
|
|
801
|
-
for (path, (diff_lines, _reload_data, is_new)) in sorted_lines:
|
|
802
|
-
if not diff_lines:
|
|
803
|
-
continue
|
|
804
|
-
label = hostname + os.sep + path
|
|
805
|
-
if is_new:
|
|
806
|
-
label = LABEL_NEW_PREFIX + label
|
|
807
|
-
yield PCDiffFile(label=label, diff_lines=diff_lines)
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
def _json_fragment_diff(
|
|
811
|
-
hw,
|
|
812
|
-
hostname: str,
|
|
813
|
-
old_files: Dict[str, Any],
|
|
814
|
-
new_files: Dict[str, Tuple[Any, Optional[str]]],
|
|
815
|
-
) -> Generator[PCDiffFile, None, None]:
|
|
816
|
-
def jsonify_multi(files):
|
|
817
|
-
return {
|
|
818
|
-
path: jsontools.format_json(cfg)
|
|
819
|
-
for path, cfg in files.items()
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
def jsonify_multi_with_cmd(files):
|
|
823
|
-
ret = {}
|
|
824
|
-
for path, cfg_reload_cmd in files.items():
|
|
825
|
-
cfg, reload_cmd = cfg_reload_cmd
|
|
826
|
-
ret[path] = (jsontools.format_json(cfg), reload_cmd)
|
|
827
|
-
return ret
|
|
828
|
-
jold, jnew = jsonify_multi(old_files), jsonify_multi_with_cmd(new_files)
|
|
829
|
-
return _pc_diff(hw, hostname, jold, jnew)
|
|
830
|
-
|
|
831
|
-
|
|
832
768
|
def guess_hw(config_text: str):
|
|
833
769
|
"""Пытаемся угадать вендора и hw на основе
|
|
834
770
|
текста конфига и annet/rulebook/texts/*.rul"""
|
annet/cli.py
CHANGED
|
@@ -113,6 +113,7 @@ def show_device_dump(args: cli_args.QueryOptions, arg_out: cli_args.FileOutOptio
|
|
|
113
113
|
)
|
|
114
114
|
else:
|
|
115
115
|
get_logger().warning("method `dump` not implemented for %s", type(device))
|
|
116
|
+
|
|
116
117
|
arg_gens = cli_args.GenOptions(arg_out, args)
|
|
117
118
|
with get_loader(arg_gens, args) as loader:
|
|
118
119
|
if not loader.devices:
|
|
@@ -190,7 +191,7 @@ def gen(args: cli_args.ShowGenOptions):
|
|
|
190
191
|
output_driver = output_driver_connector.get()
|
|
191
192
|
if args.dest is None:
|
|
192
193
|
text_mapping = {item[0]: item[1] for item in out}
|
|
193
|
-
out = [(",".join(key), value, False) for key, value in collapse_texts(text_mapping).items()]
|
|
194
|
+
out = [(", ".join(key), value, False) for key, value in collapse_texts(text_mapping).items()]
|
|
194
195
|
|
|
195
196
|
out.extend(output_driver.format_fails(fail, loader.device_fqdns))
|
|
196
197
|
total = len(success) + len(fail)
|
|
@@ -203,13 +204,19 @@ def gen(args: cli_args.ShowGenOptions):
|
|
|
203
204
|
def diff(args: cli_args.ShowDiffOptions):
|
|
204
205
|
""" Generate configuration for devices and show a diff with current configuration using the rulebook """
|
|
205
206
|
with get_loader(args, args) as loader:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
success, fail = api.diff(args, loader)
|
|
208
|
+
|
|
209
|
+
out = list(gen_sort_diff({loader.get_device(k): v for k, v in success.items()}, args))
|
|
210
|
+
output_driver = output_driver_connector.get()
|
|
211
|
+
if args.dest is None:
|
|
212
|
+
text_mapping = {item[0]: item[1] for item in out}
|
|
213
|
+
out = [(", ".join(key), value, False) for key, value in collapse_texts(text_mapping).items()]
|
|
214
|
+
out.extend(output_driver.format_fails(fail, loader.device_fqdns))
|
|
215
|
+
|
|
216
|
+
if total := len(success) + len(fail):
|
|
217
|
+
output_driver.write_output(args, out, total)
|
|
218
|
+
else:
|
|
219
|
+
get_logger().error("No devices found for %s", args.query)
|
|
213
220
|
|
|
214
221
|
|
|
215
222
|
@subcommand(cli_args.ShowPatchOptions)
|
annet/cli_args.py
CHANGED
annet/deploy_ui.py
CHANGED
|
@@ -782,11 +782,10 @@ def draw_lines_in_win(
|
|
|
782
782
|
max_x -= 2 * (margin or x_margin)
|
|
783
783
|
lines_count = len(lines)
|
|
784
784
|
if lines_count > max_y:
|
|
785
|
-
start_line = lines_count - max_y
|
|
785
|
+
start_line = lines_count - max_y
|
|
786
786
|
else:
|
|
787
787
|
start_line = 0
|
|
788
788
|
for line_no, line_data in enumerate(lines[start_line:]):
|
|
789
|
-
line_no = line_no - start_line
|
|
790
789
|
line_pos_calc = 0
|
|
791
790
|
for line_part in line_data:
|
|
792
791
|
if not isinstance(line_part, TextArgs):
|
annet/diff.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import difflib
|
|
3
|
+
import os
|
|
3
4
|
import re
|
|
4
5
|
from itertools import groupby
|
|
5
6
|
from pathlib import Path
|
|
6
|
-
from typing import Generator, List, Mapping, Tuple, Union
|
|
7
|
+
from typing import Any, Dict, Generator, List, Mapping, Optional, Protocol, Tuple, Union
|
|
7
8
|
|
|
9
|
+
from annet import cli_args, filtering, patching, rulebook, tabparser
|
|
10
|
+
from annet.annlib import jsontools
|
|
8
11
|
from annet.annlib.diff import ( # pylint: disable=unused-import
|
|
9
12
|
colorize_line,
|
|
10
13
|
diff_cmp,
|
|
@@ -13,23 +16,113 @@ from annet.annlib.diff import ( # pylint: disable=unused-import
|
|
|
13
16
|
resort_diff,
|
|
14
17
|
)
|
|
15
18
|
from annet.annlib.netdev.views.hardware import HardwareView
|
|
16
|
-
from annet.annlib.output import format_file_diff
|
|
17
|
-
|
|
18
|
-
from annet import patching, rulebook, tabparser, hardware
|
|
19
|
+
from annet.annlib.output import LABEL_NEW_PREFIX, format_file_diff
|
|
19
20
|
from annet.cli_args import ShowDiffOptions
|
|
20
21
|
from annet.connectors import CachedConnector
|
|
21
22
|
from annet.output import output_driver_connector
|
|
22
23
|
from annet.storage import Device
|
|
23
24
|
from annet.tabparser import make_formatter
|
|
24
|
-
from annet.types import Diff, PCDiff
|
|
25
|
+
from annet.types import Diff, PCDiff, PCDiffFile
|
|
26
|
+
|
|
27
|
+
from .gen import Loader, old_new
|
|
28
|
+
|
|
25
29
|
|
|
30
|
+
def _diff_files(hw, old_files, new_files):
|
|
31
|
+
ret = {}
|
|
32
|
+
differ = file_differ_connector.get()
|
|
33
|
+
for (path, (new_text, reload_data)) in new_files.items():
|
|
34
|
+
old_text = old_files.get(path)
|
|
35
|
+
is_new = old_text is None
|
|
36
|
+
diff_lines = differ.diff_file(hw, path, old_text, new_text)
|
|
37
|
+
ret[path] = (diff_lines, reload_data, is_new)
|
|
38
|
+
return ret
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
|
|
41
|
+
def pc_diff(hw, hostname: str, old_files: Dict[str, str], new_files: Dict[str, str]) -> Generator[
|
|
42
|
+
PCDiffFile, None, None]:
|
|
43
|
+
sorted_lines = sorted(_diff_files(hw, old_files, new_files).items())
|
|
44
|
+
for (path, (diff_lines, _reload_data, is_new)) in sorted_lines:
|
|
45
|
+
if not diff_lines:
|
|
46
|
+
continue
|
|
47
|
+
label = hostname + os.sep + path
|
|
48
|
+
if is_new:
|
|
49
|
+
label = LABEL_NEW_PREFIX + label
|
|
50
|
+
yield PCDiffFile(label=label, diff_lines=diff_lines)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def json_fragment_diff(
|
|
54
|
+
hw,
|
|
55
|
+
hostname: str,
|
|
56
|
+
old_files: Dict[str, Any],
|
|
57
|
+
new_files: Dict[str, Tuple[Any, Optional[str]]],
|
|
58
|
+
) -> Generator[PCDiffFile, None, None]:
|
|
59
|
+
def jsonify_multi(files):
|
|
60
|
+
return {
|
|
61
|
+
path: jsontools.format_json(cfg)
|
|
62
|
+
for path, cfg in files.items()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
def jsonify_multi_with_cmd(files):
|
|
66
|
+
ret = {}
|
|
67
|
+
for path, cfg_reload_cmd in files.items():
|
|
68
|
+
cfg, reload_cmd = cfg_reload_cmd
|
|
69
|
+
ret[path] = (jsontools.format_json(cfg), reload_cmd)
|
|
70
|
+
return ret
|
|
71
|
+
|
|
72
|
+
jold, jnew = jsonify_multi(old_files), jsonify_multi_with_cmd(new_files)
|
|
73
|
+
return pc_diff(hw, hostname, jold, jnew)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def worker(
|
|
77
|
+
device_id,
|
|
78
|
+
args: cli_args.DiffOptions,
|
|
79
|
+
stdin,
|
|
80
|
+
loader: Loader,
|
|
81
|
+
filterer: filtering.Filterer,
|
|
82
|
+
) -> Union[Diff, PCDiff, None]:
|
|
83
|
+
for res in old_new(
|
|
84
|
+
args,
|
|
85
|
+
config=args.config,
|
|
86
|
+
loader=loader,
|
|
87
|
+
no_new=args.clear,
|
|
88
|
+
do_files_download=True,
|
|
89
|
+
device_ids=[device_id],
|
|
90
|
+
filterer=filterer,
|
|
91
|
+
stdin=stdin,
|
|
92
|
+
):
|
|
93
|
+
old = res.get_old(args.acl_safe)
|
|
94
|
+
new = res.get_new(args.acl_safe)
|
|
95
|
+
device = res.device
|
|
96
|
+
acl_rules = res.get_acl_rules(args.acl_safe)
|
|
97
|
+
new_files = res.get_new_files(args.acl_safe)
|
|
98
|
+
new_json_fragment_files = res.get_new_file_fragments(args.acl_safe)
|
|
99
|
+
|
|
100
|
+
pc_diff_files = []
|
|
101
|
+
if res.old_files or new_files:
|
|
102
|
+
pc_diff_files.extend(pc_diff(res.device.hw, device.hostname, res.old_files, new_files))
|
|
103
|
+
if res.old_json_fragment_files or new_json_fragment_files:
|
|
104
|
+
pc_diff_files.extend(json_fragment_diff(res.device.hw, device.hostname, res.old_json_fragment_files,
|
|
105
|
+
new_json_fragment_files))
|
|
106
|
+
|
|
107
|
+
if pc_diff_files:
|
|
108
|
+
pc_diff_files.sort(key=lambda f: f.label)
|
|
109
|
+
return PCDiff(hostname=device.hostname, diff_files=pc_diff_files)
|
|
110
|
+
elif old is not None:
|
|
111
|
+
orderer = patching.Orderer.from_hw(device.hw)
|
|
112
|
+
rb = rulebook.get_rulebook(device.hw)
|
|
113
|
+
diff_tree = patching.make_diff(
|
|
114
|
+
old,
|
|
115
|
+
orderer.order_config(new),
|
|
116
|
+
rb,
|
|
117
|
+
[acl_rules, res.filter_acl_rules],
|
|
118
|
+
)
|
|
119
|
+
diff_tree = patching.strip_unchanged(diff_tree)
|
|
120
|
+
return diff_tree
|
|
28
121
|
|
|
29
122
|
|
|
30
123
|
def gen_sort_diff(
|
|
31
124
|
diffs: Mapping[Device, Union[Diff, PCDiff]], args: ShowDiffOptions
|
|
32
|
-
) -> Generator[Tuple[str, Generator[str, None, None], bool], None, None]:
|
|
125
|
+
) -> Generator[Tuple[str, Generator[str, None, None] | str, bool], None, None]:
|
|
33
126
|
"""
|
|
34
127
|
Возвращает осортированный дифф, совместимый с write_output
|
|
35
128
|
:param diffs: Маппинг устройства в дифф
|
|
@@ -71,7 +164,7 @@ def _make_text_diff(device: Device, diff: Diff) -> List[str]:
|
|
|
71
164
|
return res
|
|
72
165
|
|
|
73
166
|
|
|
74
|
-
def collapse_diffs(diffs: Mapping[Device, Diff]) ->
|
|
167
|
+
def collapse_diffs(diffs: Mapping[Device, Diff]) -> Dict[Tuple[Device, ...], Diff]:
|
|
75
168
|
"""
|
|
76
169
|
Группировка диффов.
|
|
77
170
|
:param diffs:
|
|
@@ -128,7 +221,7 @@ class FrrFileDiffer(UnifiedFileDiffer):
|
|
|
128
221
|
return self._diff_frr_conf(hw, old, new)
|
|
129
222
|
return super().diff_file(hw, path, old, new)
|
|
130
223
|
|
|
131
|
-
def _diff_frr_conf(self,
|
|
224
|
+
def _diff_frr_conf(self, hw: HardwareView, old_text: str | None, new_text: str | None) -> list[str]:
|
|
132
225
|
"""Calculate the differences for frr.conf files."""
|
|
133
226
|
indent = " "
|
|
134
227
|
rb = rulebook.rulebook_provider_connector.get()
|
|
@@ -2,12 +2,12 @@ annet/__init__.py,sha256=0OKkFkqog8As7B6ApdpKQkrEAcEELUREWp82D8WvGA8,1846
|
|
|
2
2
|
annet/annet.py,sha256=8Hc-n0S6d-YhcMpMiMET_SsYKfHFJeCA_E2gKgzK-2Y,790
|
|
3
3
|
annet/argparse.py,sha256=v1MfhjR0B8qahza0WinmXClpR8UiDFhmwDDWtNroJPA,12855
|
|
4
4
|
annet/bgp_models.py,sha256=oibTSdipNkGL4t8Xn94bhyKHMOtwbPBqmYaAy4FmTxQ,12361
|
|
5
|
-
annet/cli.py,sha256=
|
|
6
|
-
annet/cli_args.py,sha256=
|
|
5
|
+
annet/cli.py,sha256=II1R_HFdr4NAwVojffAy8JEJpFEnU6q8BMr16-f1T4w,12714
|
|
6
|
+
annet/cli_args.py,sha256=jzMKRezWe_87k7VBNzgwPjWGMROJksbgrlX-GDd6oQs,13533
|
|
7
7
|
annet/connectors.py,sha256=aoiDVLPizx8CW2p8SAwGCzyO_WW8H9xc2aujbGC4bDg,4882
|
|
8
8
|
annet/deploy.py,sha256=Dp-l0z7gmVIGpFB4snj6P_5G4siEeGC6vBWGJayJcn0,7732
|
|
9
|
-
annet/deploy_ui.py,sha256=
|
|
10
|
-
annet/diff.py,sha256=
|
|
9
|
+
annet/deploy_ui.py,sha256=KcP1g_c1HSA3n5qFxbGHd8t_arL4_xJV46PFO-7FLg8,28650
|
|
10
|
+
annet/diff.py,sha256=vz51az7RrXdYXsPbNMi9Y2awbjNRPQSFl6zzvE36Kx4,9441
|
|
11
11
|
annet/executor.py,sha256=lcKI-EbYqeCiBNpL729kSltduzxbAzOkQ1L_QK7tNv8,5112
|
|
12
12
|
annet/filtering.py,sha256=ZtqxPsKdV9reZoRxtQyBg22BqyMqd-2SotYcxZ-68AQ,903
|
|
13
13
|
annet/gen.py,sha256=m76bL6rVbusNV_uVHrHnA3D7TUvvLtckXx7hlr5HGA0,31897
|
|
@@ -68,7 +68,7 @@ annet/annlib/rbparser/platform.py,sha256=65-r9mboRA3gaz9DRkSwPCdCRQneItqxppdMB6z
|
|
|
68
68
|
annet/annlib/rbparser/syntax.py,sha256=iZ7Y-4QQBw4L3UtjEh54qisiRDhobl7HZxFNdP8mi54,3577
|
|
69
69
|
annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
70
|
annet/annlib/rulebook/common.py,sha256=hqwmmNofm5q2f-hV2usMY-IPMeiANLth28tZcRBYJTw,16640
|
|
71
|
-
annet/api/__init__.py,sha256=
|
|
71
|
+
annet/api/__init__.py,sha256=SIxUCX3u91ioFw-_AIy3aGCqdQav9Mtd2fBczy8zdeg,32616
|
|
72
72
|
annet/configs/context.yml,sha256=RVLrKLIHpCty7AGwOnmqf7Uu0iZQCn-AjYhophDJer8,259
|
|
73
73
|
annet/configs/logging.yaml,sha256=EUagfir99QqA73Scc3k7sfQccbU3E1SvEQdyhLFtCl4,997
|
|
74
74
|
annet/generators/__init__.py,sha256=rVHHDTPKHPZsml1eNEAj3o-8RweFTN8J7LX3tKMXdIY,16402
|
|
@@ -178,10 +178,10 @@ annet_generators/rpl_example/generator.py,sha256=zndIGfV4ZlTxPgAGYs7bMQvTc_tYScO
|
|
|
178
178
|
annet_generators/rpl_example/items.py,sha256=d99HSXDHFjZq511EvGhIqRTWK3F4ZsCWfdUqFYQcyhE,772
|
|
179
179
|
annet_generators/rpl_example/mesh.py,sha256=z_WgfDZZ4xnyh3cSf75igyH09hGvtexEVwy1gCD_DzA,288
|
|
180
180
|
annet_generators/rpl_example/route_policy.py,sha256=z6nPb0VDeQtKD1NIg9sFvmUxBD5tVs2frfNIuKdM-5c,2318
|
|
181
|
-
annet-2.
|
|
182
|
-
annet-2.
|
|
183
|
-
annet-2.
|
|
184
|
-
annet-2.
|
|
185
|
-
annet-2.
|
|
186
|
-
annet-2.
|
|
187
|
-
annet-2.
|
|
181
|
+
annet-2.3.0.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
|
|
182
|
+
annet-2.3.0.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
|
|
183
|
+
annet-2.3.0.dist-info/METADATA,sha256=5m1CMIWY8pk9goNCLOvHma1A2z7vGN5tVYJ0utQwDIM,793
|
|
184
|
+
annet-2.3.0.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
|
|
185
|
+
annet-2.3.0.dist-info/entry_points.txt,sha256=5lIaDGlGi3l6QQ2ry2jZaqViP5Lvt8AmsegdD0Uznck,192
|
|
186
|
+
annet-2.3.0.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
|
|
187
|
+
annet-2.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|