annet 0.13.6__tar.gz → 0.14.0__tar.gz
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-0.13.6/annet.egg-info → annet-0.14.0}/PKG-INFO +1 -1
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/patching.py +2 -2
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/tabparser.py +152 -56
- {annet-0.13.6 → annet-0.14.0}/annet/cli_args.py +3 -3
- {annet-0.13.6 → annet-0.14.0/annet.egg-info}/PKG-INFO +1 -1
- {annet-0.13.6 → annet-0.14.0}/AUTHORS +0 -0
- {annet-0.13.6 → annet-0.14.0}/LICENSE +0 -0
- {annet-0.13.6 → annet-0.14.0}/MANIFEST.in +0 -0
- {annet-0.13.6 → annet-0.14.0}/README.md +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/client.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/manufacturer.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/models.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/query.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/status_client.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/common/storage_opts.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/provider.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/v24/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/v24/storage.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/v37/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/adapters/netbox/v37/storage.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annet.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/command.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/diff.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/errors.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/filter_acl.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/jsontools.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/lib.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/db.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/devdb/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/views/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/views/dump.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/netdev/views/hardware.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/output.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rbparser/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rbparser/acl.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rbparser/deploying.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rbparser/ordering.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rbparser/platform.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rbparser/syntax.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rulebook/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/rulebook/common.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/annlib/types.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/api/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/argparse.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/cli.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/configs/context.yml +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/configs/logging.yaml +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/connectors.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/deploy.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/diff.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/executor.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/filtering.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/gen.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/base.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/common/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/common/initial.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/entire.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/exceptions.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/jsonfragment.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/partial.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/perf.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/ref.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/generators/result.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/hardware.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/implicit.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/lib.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/output.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/parallel.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/patching.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/reference.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/arista/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/arista/iface.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/aruba/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/aruba/ap_env.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/aruba/misc.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/cisco/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/cisco/iface.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/cisco/misc.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/cisco/vlandb.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/common.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/deploying.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/huawei/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/huawei/aaa.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/huawei/bgp.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/huawei/iface.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/huawei/misc.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/huawei/vlandb.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/juniper/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/nexus/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/nexus/iface.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/patching.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/ribbon/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/arista.deploy +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/arista.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/arista.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/aruba.deploy +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/aruba.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/aruba.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/cisco.deploy +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/cisco.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/cisco.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/huawei.deploy +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/huawei.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/huawei.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/juniper.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/nexus.deploy +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/nexus.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/nexus.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/nokia.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/pc.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/pc.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/ribbon.deploy +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/ribbon.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/routeros.order +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/rulebook/texts/routeros.rul +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/storage.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/tabparser.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/text_term_format.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/tracing.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet/types.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet.egg-info/SOURCES.txt +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet.egg-info/dependency_links.txt +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet.egg-info/entry_points.txt +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet.egg-info/requires.txt +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet.egg-info/top_level.txt +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet_generators/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet_generators/example/__init__.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/annet_generators/example/lldp.py +0 -0
- {annet-0.13.6 → annet-0.14.0}/requirements.txt +0 -0
- {annet-0.13.6 → annet-0.14.0}/setup.cfg +0 -0
- {annet-0.13.6 → annet-0.14.0}/setup.py +0 -0
|
@@ -15,8 +15,8 @@ from typing import ( # pylint: disable=unused-import
|
|
|
15
15
|
from .lib import jun_activate, merge_dicts, strip_annotation, uniq
|
|
16
16
|
from .rbparser import platform
|
|
17
17
|
from .rbparser.ordering import compile_ordering_text
|
|
18
|
-
from .rulebook.common import default as common_default
|
|
19
18
|
from .rulebook.common import call_diff_logic
|
|
19
|
+
from .rulebook.common import default as common_default
|
|
20
20
|
from .tabparser import CommonFormatter
|
|
21
21
|
from .types import Diff, Op
|
|
22
22
|
|
|
@@ -115,7 +115,7 @@ class PatchTree:
|
|
|
115
115
|
return (
|
|
116
116
|
f"PatchTree(\n"
|
|
117
117
|
f" itms=[\n"
|
|
118
|
-
f"
|
|
118
|
+
f"{textwrap.indent(n.join(itms), ' ')}\n"
|
|
119
119
|
f" ]\n"
|
|
120
120
|
f")"
|
|
121
121
|
)
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
import itertools
|
|
2
3
|
import re
|
|
3
4
|
from collections import OrderedDict as odict
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Tuple, Union
|
|
4
6
|
|
|
5
7
|
from .types import Op
|
|
6
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .patching import PatchTree
|
|
11
|
+
|
|
7
12
|
|
|
8
13
|
# =====
|
|
9
14
|
class ParserError(Exception):
|
|
@@ -23,6 +28,40 @@ class BlockEnd:
|
|
|
23
28
|
pass
|
|
24
29
|
|
|
25
30
|
|
|
31
|
+
RowWithContext = Tuple[str, Optional[Dict[str, Any]]]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def block_wrapper(value: Any) -> Iterable[Any]:
|
|
35
|
+
yield from iter((BlockBegin, value, BlockEnd))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclasses.dataclass
|
|
39
|
+
class FormatterContext:
|
|
40
|
+
parent: Optional["FormatterContext"] = None
|
|
41
|
+
|
|
42
|
+
prev: Optional[RowWithContext] = None
|
|
43
|
+
current: Optional[RowWithContext] = None
|
|
44
|
+
next: Optional[RowWithContext] = None
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def level(self) -> int:
|
|
48
|
+
if self.parent is None:
|
|
49
|
+
return 0
|
|
50
|
+
return self.parent.level + 1
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def row_prev(self) -> Optional[str]:
|
|
54
|
+
return self.prev and self.prev[0]
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def row(self) -> Optional[str]:
|
|
58
|
+
return self.current and self.current[0]
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def row_next(self) -> Optional[str]:
|
|
62
|
+
return self.next and self.next[0]
|
|
63
|
+
|
|
64
|
+
|
|
26
65
|
# =====
|
|
27
66
|
class CommonFormatter:
|
|
28
67
|
def __init__(self, indent=" "):
|
|
@@ -41,12 +80,12 @@ class CommonFormatter:
|
|
|
41
80
|
)
|
|
42
81
|
)
|
|
43
82
|
|
|
44
|
-
def diff(self, diff):
|
|
45
|
-
return list(self._diff_lines(diff))
|
|
46
|
-
|
|
47
83
|
def diff_generator(self, diff):
|
|
48
84
|
yield from self._diff_lines(diff)
|
|
49
85
|
|
|
86
|
+
def diff(self, diff):
|
|
87
|
+
return list(self.diff_generator(diff))
|
|
88
|
+
|
|
50
89
|
def patch(self, patch):
|
|
51
90
|
return "\n".join(
|
|
52
91
|
_filtered_block_marks(
|
|
@@ -103,17 +142,37 @@ class CommonFormatter:
|
|
|
103
142
|
row = self._indent * _level + row
|
|
104
143
|
yield row
|
|
105
144
|
|
|
106
|
-
def blocks_and_context(
|
|
107
|
-
|
|
145
|
+
def blocks_and_context(
|
|
146
|
+
self,
|
|
147
|
+
tree: "PatchTree",
|
|
148
|
+
is_patch: bool,
|
|
149
|
+
context: Optional[FormatterContext] = None
|
|
150
|
+
):
|
|
151
|
+
if context is None:
|
|
152
|
+
context = FormatterContext()
|
|
153
|
+
|
|
108
154
|
if is_patch:
|
|
109
|
-
items = (
|
|
155
|
+
items = [(item.row, item.child, item.context) for item in tree.itms]
|
|
110
156
|
else:
|
|
111
|
-
items = (
|
|
112
|
-
|
|
113
|
-
|
|
157
|
+
items = [(row, child, {}) for row, child in tree.items()]
|
|
158
|
+
|
|
159
|
+
n = len(items)
|
|
160
|
+
for i in range(n):
|
|
161
|
+
prev_row, prev_sub_config, prev_row_context = items[i - 1] if i > 0 else (None, None, None)
|
|
162
|
+
row, sub_config, row_context = items[i]
|
|
163
|
+
next_row, next_sub_config, next_row_context = items[i + 1] if i + 1 < n else (None, None, None)
|
|
164
|
+
|
|
165
|
+
context.current = (row, row_context)
|
|
166
|
+
context.prev = (prev_row, prev_row_context) if prev_row else None
|
|
167
|
+
context.next = (next_row, next_row_context) if next_row else None
|
|
168
|
+
|
|
169
|
+
yield row, row_context
|
|
170
|
+
|
|
114
171
|
if sub_config or (is_patch and sub_config is not None):
|
|
115
172
|
yield BlockBegin, None
|
|
116
|
-
yield from self.blocks_and_context(
|
|
173
|
+
yield from self.blocks_and_context(
|
|
174
|
+
sub_config, is_patch, context=FormatterContext(parent=context)
|
|
175
|
+
)
|
|
117
176
|
yield BlockEnd, None
|
|
118
177
|
|
|
119
178
|
def _blocks(self, tree, is_patch):
|
|
@@ -133,20 +192,32 @@ class BlockExitFormatter(CommonFormatter):
|
|
|
133
192
|
res = super().split(text)
|
|
134
193
|
return res
|
|
135
194
|
|
|
136
|
-
def block_exit(self,
|
|
137
|
-
|
|
138
|
-
|
|
195
|
+
def block_exit(self, context: Optional[FormatterContext]) -> Iterable[Any]:
|
|
196
|
+
current = context and context.row
|
|
197
|
+
if current and not current.startswith(self._no_block_exit):
|
|
198
|
+
yield from block_wrapper(self._block_exit)
|
|
199
|
+
|
|
200
|
+
def blocks_and_context(self, tree, is_patch, context: Optional[FormatterContext] = None):
|
|
201
|
+
if context is None:
|
|
202
|
+
context = FormatterContext()
|
|
203
|
+
|
|
204
|
+
level = context.level
|
|
205
|
+
block_level = level
|
|
139
206
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
207
|
+
last_row_context = {}
|
|
208
|
+
for row, row_context in super().blocks_and_context(tree, is_patch, context=context):
|
|
209
|
+
yield row, row_context
|
|
210
|
+
if row_context is not None:
|
|
211
|
+
last_row_context = row_context
|
|
212
|
+
|
|
213
|
+
if row is BlockBegin:
|
|
214
|
+
block_level += 1
|
|
215
|
+
elif row is BlockEnd:
|
|
216
|
+
block_level -= 1
|
|
217
|
+
|
|
218
|
+
if row is BlockEnd and block_level == level and is_patch:
|
|
219
|
+
for exit_statement in filter(None, self.block_exit(context)):
|
|
220
|
+
yield exit_statement, last_row_context
|
|
150
221
|
|
|
151
222
|
|
|
152
223
|
class HuaweiFormatter(BlockExitFormatter):
|
|
@@ -166,18 +237,30 @@ class HuaweiFormatter(BlockExitFormatter):
|
|
|
166
237
|
# например на VRP V100R006C00SPC500 + V100R006SPH003
|
|
167
238
|
policy_end_blocks = ("end-list", "endif", "end-filter")
|
|
168
239
|
tree = self.split_remove_spaces(text)
|
|
169
|
-
tree[:] = filter(lambda x: not x.
|
|
240
|
+
tree[:] = filter(lambda x: not str(x).strip().startswith(policy_end_blocks), tree)
|
|
170
241
|
return tree
|
|
171
242
|
|
|
172
|
-
def block_exit(self,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
243
|
+
def block_exit(self, context: Optional[FormatterContext]):
|
|
244
|
+
row = context and context.row or ""
|
|
245
|
+
row_next = context and context.row_next
|
|
246
|
+
parent_row = context and context.parent and context.parent.row or ""
|
|
247
|
+
|
|
248
|
+
if row.startswith("xpl route-filter"):
|
|
249
|
+
yield from block_wrapper("end-filter")
|
|
250
|
+
return
|
|
251
|
+
|
|
252
|
+
if row.startswith("xpl"):
|
|
253
|
+
yield from block_wrapper("end-list")
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
if parent_row.startswith("xpl route-filter"):
|
|
257
|
+
if (row.startswith(("if", "elseif")) and row.endswith("then")) and not row_next:
|
|
258
|
+
yield "endif"
|
|
259
|
+
elif row == "else":
|
|
260
|
+
yield "endif"
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
yield from super().block_exit(context)
|
|
181
264
|
|
|
182
265
|
|
|
183
266
|
class CiscoFormatter(BlockExitFormatter):
|
|
@@ -198,15 +281,17 @@ class AsrFormatter(BlockExitFormatter):
|
|
|
198
281
|
tree[:] = filter(lambda x: not x.endswith(policy_end_blocks), tree)
|
|
199
282
|
return tree
|
|
200
283
|
|
|
201
|
-
def block_exit(self,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
284
|
+
def block_exit(self, context: Optional[FormatterContext]) -> str:
|
|
285
|
+
current = context and context.row or ""
|
|
286
|
+
|
|
287
|
+
if current.startswith(("prefix-set", "as-path-set", "community-set")):
|
|
288
|
+
yield from block_wrapper("end-set")
|
|
289
|
+
elif current.startswith("if") and current.endswith("then"):
|
|
290
|
+
yield from block_wrapper("endif")
|
|
291
|
+
elif current.startswith("route-policy"):
|
|
292
|
+
yield from block_wrapper("end-policy")
|
|
293
|
+
else:
|
|
294
|
+
yield from super().block_exit(context)
|
|
210
295
|
|
|
211
296
|
|
|
212
297
|
class JuniperFormatter(CommonFormatter):
|
|
@@ -381,18 +466,24 @@ class RosFormatter(CommonFormatter):
|
|
|
381
466
|
def patch_plain(self, patch):
|
|
382
467
|
return list(self.cmd_paths(patch).keys())
|
|
383
468
|
|
|
384
|
-
def blocks_and_context(
|
|
469
|
+
def blocks_and_context(
|
|
470
|
+
self,
|
|
471
|
+
tree: "PatchTree",
|
|
472
|
+
is_patch: bool,
|
|
473
|
+
context: Optional[FormatterContext] = None
|
|
474
|
+
):
|
|
385
475
|
rows = []
|
|
386
|
-
|
|
476
|
+
|
|
387
477
|
if is_patch:
|
|
388
478
|
items = ((item.row, item.child, item.context) for item in tree.itms)
|
|
389
479
|
else:
|
|
390
|
-
items = ((row, child,
|
|
391
|
-
|
|
480
|
+
items = ((row, child, {}) for row, child in tree.items())
|
|
481
|
+
|
|
482
|
+
for row, sub_config, row_context in items:
|
|
392
483
|
if sub_config or (is_patch and sub_config is not None):
|
|
393
|
-
rows.append((row, sub_config,
|
|
484
|
+
rows.append((row, sub_config, row_context))
|
|
394
485
|
else:
|
|
395
|
-
rows.append((row, None,
|
|
486
|
+
rows.append((row, None, row_context))
|
|
396
487
|
|
|
397
488
|
prev_prow = None
|
|
398
489
|
for sub_config, row_group in itertools.groupby(rows, lambda x: x[1]):
|
|
@@ -400,20 +491,25 @@ class RosFormatter(CommonFormatter):
|
|
|
400
491
|
if prev_prow:
|
|
401
492
|
yield prev_prow
|
|
402
493
|
yield BlockBegin, None
|
|
403
|
-
for
|
|
404
|
-
yield row,
|
|
494
|
+
for row, _, row_context in row_group:
|
|
495
|
+
yield row, row_context
|
|
405
496
|
if prev_prow:
|
|
406
497
|
yield BlockEnd, None
|
|
407
498
|
else:
|
|
408
|
-
for
|
|
409
|
-
if
|
|
410
|
-
prev_prow =
|
|
411
|
-
prow = f"{
|
|
499
|
+
for row, _, row_context in row_group:
|
|
500
|
+
if context and context.parent and context.parent.row:
|
|
501
|
+
prev_prow = context.parent.row
|
|
502
|
+
prow = f"{context.parent.row} {row}"
|
|
412
503
|
else:
|
|
413
504
|
prow = row
|
|
414
|
-
yield prow,
|
|
505
|
+
yield prow, row_context
|
|
506
|
+
|
|
415
507
|
yield BlockBegin, None
|
|
416
|
-
yield from self.blocks_and_context(
|
|
508
|
+
yield from self.blocks_and_context(
|
|
509
|
+
sub_config,
|
|
510
|
+
is_patch,
|
|
511
|
+
context=FormatterContext(parent=context, current=(prow, row_context))
|
|
512
|
+
)
|
|
417
513
|
yield BlockEnd, None
|
|
418
514
|
|
|
419
515
|
def _formatted_blocks(self, blocks):
|
|
@@ -27,7 +27,7 @@ def convert_to_none(arg):
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def valid_config_source(value):
|
|
30
|
-
if value not in ["
|
|
30
|
+
if value not in ["running", "empty", "-"] and not os.path.exists(value):
|
|
31
31
|
raise ValueError("No such file or directory %r" % value)
|
|
32
32
|
return value
|
|
33
33
|
|
|
@@ -174,14 +174,14 @@ opt_annotate = Arg(
|
|
|
174
174
|
|
|
175
175
|
opt_config = Arg(
|
|
176
176
|
"--config", default="running", type=valid_config_source,
|
|
177
|
-
help="'
|
|
177
|
+
help="'running', 'empty', путь к файлу конфига, "
|
|
178
178
|
"каталогу с файлами конфига в формате <hostname>.cfg "
|
|
179
179
|
"или '-' (stdin)"
|
|
180
180
|
)
|
|
181
181
|
|
|
182
182
|
opt_clear = Arg(
|
|
183
183
|
"--clear", default=False,
|
|
184
|
-
help="Используя acl вычищает команды относящиеся к данному
|
|
184
|
+
help="Используя acl вычищает команды относящиеся к данному генератору, "
|
|
185
185
|
"аналогично использованию return в самом начале генератора"
|
|
186
186
|
)
|
|
187
187
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|