annet 0.11__py3-none-any.whl → 0.12__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.

@@ -0,0 +1,127 @@
1
+ from __future__ import annotations
2
+
3
+ import textwrap
4
+ from collections import OrderedDict as odict
5
+ from typing import (
6
+ Any,
7
+ Dict,
8
+ Optional,
9
+ Tuple, Callable,
10
+ )
11
+
12
+ from annet.annlib import jsontools
13
+ from annet.lib import (
14
+ merge_dicts,
15
+ )
16
+ from annet.reference import RefMatcher, RefTracker
17
+ from annet.types import (
18
+ GeneratorEntireResult,
19
+ GeneratorJSONFragmentResult,
20
+ GeneratorPartialResult,
21
+ )
22
+
23
+
24
+ def _combine_acl_text(
25
+ partial_results: Dict[str, GeneratorPartialResult],
26
+ acl_getter: Callable[[GeneratorPartialResult], str]
27
+ ) -> str:
28
+ acl_text = ""
29
+ for gr in partial_results.values():
30
+ for line in textwrap.dedent(acl_getter(gr)).split("\n"):
31
+ if line and not line.isspace():
32
+ acl_text += line.rstrip()
33
+ acl_text += fr" %generator_names={gr.name}"
34
+ acl_text += "\n"
35
+ return acl_text
36
+
37
+
38
+ class RunGeneratorResult:
39
+ """
40
+ Результат запуска run_partial_generators/run_file_generators
41
+ """
42
+
43
+ def __init__(self):
44
+ self.partial_results: Dict[str, GeneratorPartialResult] = {}
45
+ self.entire_results: Dict[str, GeneratorEntireResult] = {}
46
+ self.json_fragment_results: Dict[str, GeneratorJSONFragmentResult] = {}
47
+ self.ref_track: RefTracker = RefTracker()
48
+ self.ref_matcher: RefMatcher = RefMatcher()
49
+
50
+ def add_partial(self, result: GeneratorPartialResult):
51
+ self.partial_results[result.name] = result
52
+
53
+ def add_entire(self, result: GeneratorEntireResult) -> None:
54
+ # Если есть несколько генераторов на один файл, выбрать тот, что с большим приоритетом
55
+ if result.path:
56
+ if result.path not in self.entire_results or \
57
+ result.prio > self.entire_results[result.path].prio:
58
+ self.entire_results[result.path] = result
59
+
60
+ def add_json_fragment(self, result: GeneratorJSONFragmentResult) -> None:
61
+ self.json_fragment_results[result.name] = result
62
+
63
+ def config_tree(self, safe: bool = False) -> Dict[str, Any]: # OrderedDict
64
+ tree = odict()
65
+ for gr in self.partial_results.values():
66
+ config = gr.safe_config if safe else gr.config
67
+ tree = merge_dicts(tree, config)
68
+ return tree
69
+
70
+ def new_files(self, safe: bool = False) -> Dict[str, Tuple[str, str]]:
71
+ files = {}
72
+ for gr in self.entire_results.values():
73
+ if not safe or gr.is_safe:
74
+ files[gr.path] = (gr.output, gr.reload)
75
+ return files
76
+
77
+ def acl_text(self) -> str:
78
+ return _combine_acl_text(self.partial_results, lambda gr: gr.acl)
79
+
80
+ def acl_safe_text(self) -> str:
81
+ return _combine_acl_text(self.partial_results, lambda gr: gr.acl_safe)
82
+
83
+ def new_json_fragment_files(
84
+ self,
85
+ old_files: Dict[str, Optional[str]],
86
+ safe: bool = False,
87
+ ) -> Dict[str, Tuple[Any, Optional[str]]]:
88
+ # TODO: safe
89
+ files: Dict[str, Tuple[Any, Optional[str]]] = {}
90
+ reload_prios: Dict[str, int] = {}
91
+ for generator_result in self.json_fragment_results.values():
92
+ filepath = generator_result.path
93
+ if filepath not in files:
94
+ if old_files.get(filepath) is not None:
95
+ files[filepath] = (old_files[filepath], None)
96
+ else:
97
+ files[filepath] = ({}, None)
98
+ result_acl = generator_result.acl
99
+ if safe:
100
+ result_acl = generator_result.acl_safe
101
+ previous_config: Dict[str, Any] = files[filepath][0]
102
+ new_fragment = generator_result.config
103
+ new_config = jsontools.apply_json_fragment(
104
+ previous_config,
105
+ new_fragment,
106
+ result_acl,
107
+ )
108
+ if filepath in reload_prios and \
109
+ reload_prios[filepath] > generator_result.reload_prio:
110
+ _, reload_cmd = files[filepath]
111
+ else:
112
+ reload_cmd = generator_result.reload
113
+ reload_prios[filepath] = generator_result.reload_prio
114
+ files[filepath] = (new_config, reload_cmd)
115
+ return files
116
+
117
+ def perf_mesures(self) -> Dict[str, Dict[str, int]]:
118
+ mesures = {}
119
+ for gr in self.partial_results.values():
120
+ mesures[gr.name] = {"total": gr.perf.total,
121
+ "rt": gr.perf.rt,
122
+ "meta": gr.perf.meta}
123
+ for gr in self.entire_results.values():
124
+ mesures[gr.name] = {"total": gr.perf.total,
125
+ "rt": gr.perf.rt,
126
+ "meta": gr.perf.meta}
127
+ return mesures
annet/output.py CHANGED
@@ -2,7 +2,7 @@ import abc
2
2
  import os
3
3
  import posixpath
4
4
  import sys
5
- from typing import List, Optional, Tuple, Type
5
+ from typing import List, Optional, Tuple, Type, Dict
6
6
 
7
7
  import colorama
8
8
  from annet.annlib.output import ( # pylint: disable=unused-import
@@ -41,7 +41,7 @@ class OutputDriver(abc.ABC):
41
41
  pass
42
42
 
43
43
  @abc.abstractmethod
44
- def format_fails(self, fail, args: Optional[QueryOptions] = None) -> Tuple[str, str]:
44
+ def format_fails(self, fail, fqdns: Optional[Dict[int, str]] = None) -> Tuple[str, str]:
45
45
  pass
46
46
 
47
47
  @abc.abstractmethod
@@ -129,14 +129,9 @@ class OutputDriverBasic(OutputDriver):
129
129
  with open(dest, "w") as file:
130
130
  writer.write(file)
131
131
 
132
- def format_fails(self, fail, args: Optional[QueryOptions] = None):
132
+ def format_fails(self, fail, fqdns: Optional[Dict[int, str]] = None):
133
133
  ret = []
134
- fqdns = {}
135
- if args:
136
- connector = storage_connector.get()
137
- storage_opts = connector.opts().from_cli_opts(args)
138
- with connector.storage()(storage_opts) as storage:
139
- fqdns = storage.resolve_fdnds_by_query(args.query)
134
+ fqdns = fqdns or {}
140
135
  for (assignment, exc) in fail.items():
141
136
  label = assignment
142
137
  if assignment in fqdns:
annet/storage.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import abc
2
- from typing import Any, Iterable, Optional, Type, Union
3
-
2
+ from typing import Any, Iterable, Optional, Type, Union, Protocol
4
3
 
5
4
  try:
6
5
  from annet.connectors import Connector
@@ -81,7 +80,12 @@ class Query(abc.ABC):
81
80
  pass
82
81
 
83
82
 
84
- class Device(abc.ABC):
83
+ class Device(Protocol):
84
+ @property
85
+ @abc.abstractmethod
86
+ def storage(self) -> Storage:
87
+ pass
88
+
85
89
  @abc.abstractmethod
86
90
  def __hash__(self):
87
91
  pass
annet/types.py CHANGED
@@ -43,7 +43,6 @@ class GeneratorPartialRunArgs:
43
43
  def __init__(
44
44
  self,
45
45
  device: Device,
46
- storage: Storage,
47
46
  use_acl: bool = False,
48
47
  use_acl_safe: bool = False,
49
48
  annotate: bool = False,
@@ -51,7 +50,6 @@ class GeneratorPartialRunArgs:
51
50
  no_new: bool = False,
52
51
  ):
53
52
  self.device = device
54
- self.storage = storage
55
53
  self.use_acl = use_acl # фильтруем по acl ввыод генератора (--no-acl для дебага)
56
54
  self.use_acl_safe = use_acl_safe # [NOCDEV-6190] используем более строгий генераторный acl
57
55
  self.annotate = annotate # добавляем в каждую строку вывода информацию откуда она была заyield'ена
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: annet
3
- Version: 0.11
3
+ Version: 0.12
4
4
  Summary: annet
5
5
  Home-page: https://github.com/annetutil/annet
6
6
  License: MIT
@@ -1,44 +1,44 @@
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=bkAaHKBYmvdaFawm_KOM7CehMm18RTR8TkMYAxm-7lo,8464
5
- annet/cli_args.py,sha256=rmBTJ64sljQWFTIbhTEBZRIo08Gi9NAoFZrMermZEuY,16152
6
- annet/connectors.py,sha256=M2NeyFgBEGJ_tMR9HgQ4cpli0nBciqZJDVMQXEueMws,1908
4
+ annet/cli.py,sha256=Nk956O3nOEVsOLyOqKDgjqJaB2uVlwYb9tPrWMbB4E4,9632
5
+ annet/cli_args.py,sha256=AQIJDCUHMGmuhDKN5CBZPw44CZPzHM5--cS102Th3Cg,16054
6
+ annet/connectors.py,sha256=FLFJlhb73g2c8e61zYnGn8dTkIiaaWYqeUCsZd48AWg,2471
7
7
  annet/deploy.py,sha256=B8E0P_VvCrS2URjFvgmUiIkHp95g7pAWfmT34igaDeo,18893
8
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=yxlAht0SgYKFYI1gxhqEz92aNy-D5Cq_Gi78orFpG8w,33195
11
+ annet/gen.py,sha256=jrtGQwGjD3Rf4U8CNXcsijuPN6RM2ryZj7S0fv4XxdU,32492
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=XsX3o4vxe7Ayw7ocY-pV5VY-9-D5_Q_yeWy2ZY1Hubk,7090
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=V1AQDGxaAEKC5EXOcPy2DqglR_sUdp3l_AS_2c1CFfA,2299
19
+ annet/storage.py,sha256=B16iUJwxKd0RWnUaogWQs0WQtiH1YCzPypSHNpBYPDM,2395
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
23
- annet/types.py,sha256=wT1z1DM-hcjfHizmLxAe9aUi4uhuQ13POiV_MTygUJM,7158
23
+ annet/types.py,sha256=uHfRL3Bh6B3TyS9WfdukWKyF0fpYNdIzFB6Dgjo_Pqk,7101
24
24
  annet/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  annet/adapters/netbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  annet/adapters/netbox/provider.py,sha256=OM7Hq2vnMHNVBfubJvx2qJlMYm3VvKhomdLMNO8YnLQ,1024
27
27
  annet/adapters/netbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  annet/adapters/netbox/common/client.py,sha256=-lWZmphD-OPuLIHNKhW_h2bnjrVaiyKYAD_MUPasEbo,2483
29
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
30
+ annet/adapters/netbox/common/models.py,sha256=yHppe8UIc4Ww8UUqXChlfkmqgr96uhsOlvT8NrxvYGA,1917
31
31
  annet/adapters/netbox/common/query.py,sha256=OgUuF-bvshpoBUkrOs0tsMUAhjTsttzx3VV30ryFl0Y,577
32
- annet/adapters/netbox/common/status_client.py,sha256=3oozmdfewPXODEkNrDRfcz_pTeXRVDQiNiD-AE6Lrug,567
32
+ annet/adapters/netbox/common/status_client.py,sha256=W4nTb2yvBlJ2UkWUmUhKQ2PaSQb1shjhHj5ebb4s2s4,591
33
33
  annet/adapters/netbox/common/storage_opts.py,sha256=rl_0pr3VzmOy6PDZIUMkKSBfJh90gD9TFL3yBhK_8ME,337
34
34
  annet/adapters/netbox/v24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- annet/adapters/netbox/v24/api_models.py,sha256=xG3n9ILYdD2jNxav8IH6Bm6fX4vbHPUkHBLze4Ly1bc,1314
35
+ annet/adapters/netbox/v24/api_models.py,sha256=D6CWsqRQz91LEFUdrC53GkO0EWL4SWK305wJlEe21k0,1333
36
36
  annet/adapters/netbox/v24/client.py,sha256=-r91zVTThn12mN1zBj3XNyqlP6BGOrAPm_GbBT2bXpI,1497
37
- annet/adapters/netbox/v24/storage.py,sha256=SCTSOea8OHiLAPmBXIop80mIUOLuA48rLpKlitYJt1k,5620
37
+ annet/adapters/netbox/v24/storage.py,sha256=ZidFYibx8TSVuTPqMg8JhVTW9ZnfWCvFFaCLcQwYXmY,5864
38
38
  annet/adapters/netbox/v37/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- annet/adapters/netbox/v37/api_models.py,sha256=O59bYesIWlxHx3C2TW4TQnfN9YMsE_rbiw2mYsormcc,886
39
+ annet/adapters/netbox/v37/api_models.py,sha256=W9l1pXaatBY0zuGwku4Smzw3d7tJoXwqpJDvrfDEm4U,905
40
40
  annet/adapters/netbox/v37/client.py,sha256=GgFIV5IGlyEplvwOLLd1BxtsbPWkeHEtL22kWV_X0b0,1668
41
- annet/adapters/netbox/v37/storage.py,sha256=5jp2AgalijTdFkMnjvGGGnxqjwk-bn6QWzTRTfNyyHM,4216
41
+ annet/adapters/netbox/v37/storage.py,sha256=moFUulyf64zDId1WXOvlPvTB5BqBXDTgRri1YViORo0,4462
42
42
  annet/annlib/__init__.py,sha256=fT1l4xV5fqqg8HPw9HqmZVN2qwS8i6X1aIm2zGDjxKY,252
43
43
  annet/annlib/command.py,sha256=uuBddMQphtn8P5MO5kzIa8_QrtMns-k05VeKv1bcAuA,1043
44
44
  annet/annlib/diff.py,sha256=UPt3kYFQdQdVVy3ePYzNHPAxMVmHxCrCnZnMCV6ou2Q,4587
@@ -65,12 +65,20 @@ annet/annlib/rbparser/platform.py,sha256=iyqy4A-6vUKM4j6hrOA6tsgWBXk7LcvkFrS2QHg
65
65
  annet/annlib/rbparser/syntax.py,sha256=eEUmszwPjdw57aofUYNQVcaxHPNV9yx9JNapjYY-BGM,3572
66
66
  annet/annlib/rulebook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  annet/annlib/rulebook/common.py,sha256=9kCZwZpsH5UliF2OzaN9nLs2eLlz_d__4L7_oZ3SrCw,16054
68
- annet/api/__init__.py,sha256=VooP9u9f6e8vF7FPUE-r0JAGqCjck9-2b0dVNWAtoLM,33752
68
+ annet/api/__init__.py,sha256=LDl_JB_azU3v-sI5EwsJkiMDm_zZ7zYFBx8FHDW3Eag,33180
69
69
  annet/configs/context.yml,sha256=nt4QnzYzrG2hqmaWOUsab2wgFl-CXmFSzbto6rqqFt4,291
70
70
  annet/configs/logging.yaml,sha256=Hu42lRK248dssp9TgkbHCaZNl0E6f4IChGb0XaQnTVo,970
71
- annet/generators/__init__.py,sha256=0aswTm4MD_DWas0iwQQI8DaGX1iRQYHXHg6sl8549CI,34979
71
+ annet/generators/__init__.py,sha256=ZWKdxy6XbANW8vO6Tz7TMP_5rkHHKPBiBhPK2g-NOvI,15609
72
+ annet/generators/base.py,sha256=rgQLcQBPZm4ecbKmRhVOpBR-GFJAiVfdb_y5f2-LUR8,3670
73
+ annet/generators/entire.py,sha256=7WySkVaXNT3ZAiHcQ0JUKdlhGJAN8cNUxF6c7ilYnO8,2928
74
+ annet/generators/exceptions.py,sha256=GPXTBgn2xZ3Ev_bdOPlfCLGRC1kQHe_dEq88S-uyi5s,151
75
+ annet/generators/jsonfragment.py,sha256=itHDq46B50o2-zxnEtCAPb8XKyc0-ozTe-E_MjpkfHw,4020
76
+ annet/generators/partial.py,sha256=XI01KDA--XwjSEU33SOQCCJZRXFq5boRz1uJA8lVA1g,3502
77
+ annet/generators/perf.py,sha256=M6qVosLxuvKBkcvVUR6be1Ak2wHMooUT_qgwBjfi558,2329
78
+ annet/generators/ref.py,sha256=QVdeL8po1D0kBsVLOpCjFR81D8yNTk-kaQj5WUM4hng,438
79
+ annet/generators/result.py,sha256=boMG4mwvitBLlHdPM8rPOqlKPrrNAqdV6NAM9wwIZHc,4765
72
80
  annet/generators/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- annet/generators/common/initial.py,sha256=XI7uWLMuLrHC-uXm38oRbM1YVuELAvMHLZFHM9x5IF8,1229
81
+ annet/generators/common/initial.py,sha256=TDkY-ZNaL3yMxGGATVD76uR-nsNTmZrXs2_56MyndxM,1232
74
82
  annet/rulebook/__init__.py,sha256=14IpOfTbeJtre7JKrfXVYiH0qAXsUSOL7AatUFmSQs0,3847
75
83
  annet/rulebook/common.py,sha256=zK1s2c5lc5HQbIlMUQ4HARQudXSgOYiZ_Sxc2I_tHqg,721
76
84
  annet/rulebook/deploying.py,sha256=XV0XQvc3YvwM8SOgOQlc-fCW4bnjQg_1CTZkTwMp14A,2972
@@ -120,10 +128,10 @@ annet/rulebook/texts/routeros.rul,sha256=ipfxjj0mjFef6IsUlupqx4BY_Je_OUb8u_U1019
120
128
  annet_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
129
  annet_generators/example/__init__.py,sha256=zVd8_DrXuOASrNzg2Ab94rPyvJff83L-_HppDFxnUjM,228
122
130
  annet_generators/example/lldp.py,sha256=68CLrK7vxTQQy9XIBxtywuEdBNlIlfXGYj8_wYWs5UI,1146
123
- annet-0.11.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
124
- annet-0.11.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
125
- annet-0.11.dist-info/METADATA,sha256=NsxmrzE8om8V_vysVIFVFXPEMPGDWyz0VG6DYSu5Q-k,692
126
- annet-0.11.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
127
- annet-0.11.dist-info/entry_points.txt,sha256=yHimujIzR2bwNIbb--MTs_GpXiAve89Egpu2LlgTEkg,119
128
- annet-0.11.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
129
- annet-0.11.dist-info/RECORD,,
131
+ annet-0.12.dist-info/AUTHORS,sha256=rh3w5P6gEgqmuC-bw-HB68vBCr-yIBFhVL0PG4hguLs,878
132
+ annet-0.12.dist-info/LICENSE,sha256=yPxl7dno02Pw7gAcFPIFONzx_gapwDoPXsIsh6Y7lC0,1079
133
+ annet-0.12.dist-info/METADATA,sha256=1Fu2-NgJ4kk5UeSG8OFTJxjeARpGW5tG_fLiykOfQUM,692
134
+ annet-0.12.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
135
+ annet-0.12.dist-info/entry_points.txt,sha256=yHimujIzR2bwNIbb--MTs_GpXiAve89Egpu2LlgTEkg,119
136
+ annet-0.12.dist-info/top_level.txt,sha256=QsoTZBsUtwp_FEcmRwuN8QITBmLOZFqjssRfKilGbP8,23
137
+ annet-0.12.dist-info/RECORD,,
File without changes
File without changes
File without changes