annet 1.1.0__tar.gz → 1.1.2__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-1.1.0/annet.egg-info → annet-1.1.2}/PKG-INFO +2 -3
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/query.py +3 -1
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/lib.py +0 -14
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/patching.py +9 -3
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/ordering.py +6 -1
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/platform.py +2 -2
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/tabparser.py +54 -22
- {annet-1.1.0 → annet-1.1.2}/annet/api/__init__.py +1 -1
- {annet-1.1.0 → annet-1.1.2}/annet/executor.py +1 -23
- {annet-1.1.0 → annet-1.1.2}/annet/generators/entire.py +0 -4
- {annet-1.1.0 → annet-1.1.2}/annet/lib.py +6 -2
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/juniper/__init__.py +1 -1
- annet-1.1.2/annet/rulebook/texts/juniper.order +4 -0
- {annet-1.1.0 → annet-1.1.2/annet.egg-info}/PKG-INFO +2 -3
- {annet-1.1.0 → annet-1.1.2}/annet.egg-info/requires.txt +1 -2
- {annet-1.1.0 → annet-1.1.2}/requirements.txt +0 -1
- {annet-1.1.0 → annet-1.1.2}/setup.py +1 -1
- annet-1.1.0/annet/rulebook/texts/juniper.order +0 -4
- {annet-1.1.0 → annet-1.1.2}/AUTHORS +0 -0
- {annet-1.1.0 → annet-1.1.2}/LICENSE +0 -0
- {annet-1.1.0 → annet-1.1.2}/MANIFEST.in +0 -0
- {annet-1.1.0 → annet-1.1.2}/README.md +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/fetchers/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/fetchers/stub/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/fetchers/stub/fetcher.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/file/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/file/provider.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/client.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/manufacturer.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/models.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/status_client.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/common/storage_opts.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/provider.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v24/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v24/storage.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v37/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/adapters/netbox/v37/storage.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annet.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/command.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/diff.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/errors.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/filter_acl.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/jsontools.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/db.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/devdb/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/views/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/views/dump.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/netdev/views/hardware.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/output.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/acl.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/deploying.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rbparser/syntax.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rulebook/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/rulebook/common.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/annlib/types.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/argparse.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/bgp_models.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/cli.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/cli_args.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/configs/context.yml +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/configs/logging.yaml +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/connectors.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/deploy.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/deploy_ui.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/diff.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/filtering.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/gen.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/base.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/common/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/common/initial.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/exceptions.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/jsonfragment.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/partial.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/perf.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/ref.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/generators/result.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/hardware.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/implicit.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/basemodel.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/device_models.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/executor.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/match_args.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/models_converter.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/peer_models.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/port_processor.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/mesh/registry.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/output.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/parallel.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/patching.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/reference.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/action.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/condition.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/match_builder.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/policy.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/result.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/routemap.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl/statement_builder.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/aspath.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/community.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/cumulus_frr.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/entities.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/execute.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/policy.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/prefix_lists.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rpl_generators/rd.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/arista/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/arista/aaa.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/arista/iface.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/aruba/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/aruba/ap_env.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/aruba/misc.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/b4com/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/b4com/file.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/b4com/iface.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/iface.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/misc.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/cisco/vlandb.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/common.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/deploying.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/aaa.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/bgp.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/iface.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/misc.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/huawei/vlandb.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/nexus/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/nexus/iface.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/patching.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/routeros/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/routeros/file.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/arista.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/arista.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/arista.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/aruba.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/aruba.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/aruba.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/b4com.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/b4com.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/b4com.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/cisco.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/cisco.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/cisco.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/huawei.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/huawei.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/huawei.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/juniper.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nexus.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nexus.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nexus.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/nokia.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/optixtrans.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/optixtrans.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/optixtrans.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/pc.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/pc.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/pc.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/ribbon.deploy +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/ribbon.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/routeros.order +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/rulebook/texts/routeros.rul +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/storage.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/tabparser.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/text_term_format.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/tracing.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet/types.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet.egg-info/SOURCES.txt +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet.egg-info/dependency_links.txt +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet.egg-info/entry_points.txt +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet.egg-info/top_level.txt +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/example/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/example/lldp.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/mesh_example/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/mesh_example/bgp.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/mesh_example/mesh_logic.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/__init__.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/generator.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/items.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/mesh.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/annet_generators/rpl_example/route_policy.py +0 -0
- {annet-1.1.0 → annet-1.1.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -14,7 +14,6 @@ Requires-Dist: jsonpointer>=2.4
|
|
|
14
14
|
Requires-Dist: PyYAML>=6.0.1
|
|
15
15
|
Requires-Dist: Pygments>=2.14.0
|
|
16
16
|
Requires-Dist: Mako>=1.2.4
|
|
17
|
-
Requires-Dist: Jinja2>=3.1.2
|
|
18
17
|
Requires-Dist: packaging>=23.2
|
|
19
18
|
Requires-Dist: contextlog>=1.1
|
|
20
19
|
Requires-Dist: valkit>=0.1.4
|
|
@@ -22,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
|
|
|
22
21
|
Requires-Dist: adaptix==3.0.0b7
|
|
23
22
|
Requires-Dist: dataclass-rest==0.4
|
|
24
23
|
Provides-Extra: netbox
|
|
25
|
-
Requires-Dist: annetbox[sync]>=0.2.
|
|
24
|
+
Requires-Dist: annetbox[sync]>=0.2.1; extra == "netbox"
|
|
26
25
|
Dynamic: home-page
|
|
27
26
|
Dynamic: license
|
|
28
27
|
Dynamic: provides-extra
|
|
@@ -5,7 +5,7 @@ from typing import cast, List, Union, Iterable, Optional, TypedDict
|
|
|
5
5
|
from annet.storage import Query
|
|
6
6
|
|
|
7
7
|
FIELD_VALUE_SEPARATOR = ":"
|
|
8
|
-
ALLOWED_GLOB_GROUPS = ["site", "tag", "role", "device_type"]
|
|
8
|
+
ALLOWED_GLOB_GROUPS = ["site", "tag", "role", "device_type", "status", "tenant"]
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Filter(TypedDict, total=False):
|
|
@@ -14,6 +14,8 @@ class Filter(TypedDict, total=False):
|
|
|
14
14
|
role: list[str]
|
|
15
15
|
name: list[str]
|
|
16
16
|
device_type: list[str]
|
|
17
|
+
status: list[str]
|
|
18
|
+
tenant: list[str]
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
@dataclass
|
|
@@ -18,7 +18,6 @@ from functools import lru_cache
|
|
|
18
18
|
from typing import List, NamedTuple, Optional, Tuple, Union
|
|
19
19
|
|
|
20
20
|
import contextlog
|
|
21
|
-
import jinja2
|
|
22
21
|
import mako.template
|
|
23
22
|
|
|
24
23
|
_logger = contextlog.get_logger()
|
|
@@ -292,19 +291,6 @@ def mako_render(template, dedent=False, **kwargs):
|
|
|
292
291
|
return ret
|
|
293
292
|
|
|
294
293
|
|
|
295
|
-
def jinja_render(template, dedent=False, **kwargs):
|
|
296
|
-
@lru_cache(None)
|
|
297
|
-
def _compile_jinja(template, dedent):
|
|
298
|
-
if dedent:
|
|
299
|
-
template = textwrap.dedent(template).strip()
|
|
300
|
-
return jinja2.Template(template)
|
|
301
|
-
|
|
302
|
-
ret = _compile_jinja(template, dedent).render(**kwargs)
|
|
303
|
-
if dedent:
|
|
304
|
-
ret = ret.strip()
|
|
305
|
-
return ret
|
|
306
|
-
|
|
307
|
-
|
|
308
294
|
# =====
|
|
309
295
|
def find_exc_in_stack(
|
|
310
296
|
container_exc: Exception,
|
|
@@ -2,7 +2,7 @@ import copy
|
|
|
2
2
|
import operator
|
|
3
3
|
import textwrap
|
|
4
4
|
from collections import OrderedDict as odict
|
|
5
|
-
from typing import (
|
|
5
|
+
from typing import (
|
|
6
6
|
Any,
|
|
7
7
|
Dict,
|
|
8
8
|
Iterator,
|
|
@@ -177,7 +177,7 @@ class Orderer:
|
|
|
177
177
|
def rule_weight(self, row, rule, regexp_key):
|
|
178
178
|
return len(set(row).intersection(set(rule["attrs"][regexp_key].pattern))) / len(row)
|
|
179
179
|
|
|
180
|
-
def get_order(self, row, cmd_direct):
|
|
180
|
+
def get_order(self, row, cmd_direct, scope: str | None = None):
|
|
181
181
|
f_order = None
|
|
182
182
|
f_weight = 0
|
|
183
183
|
f_rule = ""
|
|
@@ -186,6 +186,12 @@ class Orderer:
|
|
|
186
186
|
block_exit = platform.VENDOR_EXIT[self.vendor]
|
|
187
187
|
|
|
188
188
|
for (order, (raw_rule, rule)) in enumerate(ordering.items()):
|
|
189
|
+
if (
|
|
190
|
+
(rule_scope := rule["attrs"]["scope"]) is not None
|
|
191
|
+
and scope not in rule_scope
|
|
192
|
+
):
|
|
193
|
+
continue
|
|
194
|
+
|
|
189
195
|
if rule["attrs"]["global"]:
|
|
190
196
|
children.append((raw_rule, rule))
|
|
191
197
|
|
|
@@ -419,7 +425,7 @@ def make_patch(pre, rb, hw, add_comments, orderer=None, _root_pre=None, do_commi
|
|
|
419
425
|
patch_row = "%s %s" % (row, comments)
|
|
420
426
|
|
|
421
427
|
# pylint: disable=unused-variable
|
|
422
|
-
(order, order_direct, ordering, order_rule) = orderer.get_order(row, direct)
|
|
428
|
+
(order, order_direct, ordering, order_rule) = orderer.get_order(row, direct, scope="patch")
|
|
423
429
|
fmt_row = patch_row
|
|
424
430
|
# fmt_row += " # %s" % str(order_rule) # uncomment to debug ordering
|
|
425
431
|
|
|
@@ -2,7 +2,7 @@ import functools
|
|
|
2
2
|
import re
|
|
3
3
|
from collections import OrderedDict as odict
|
|
4
4
|
|
|
5
|
-
from valkit.common import valid_bool
|
|
5
|
+
from valkit.common import valid_bool, valid_string_list
|
|
6
6
|
|
|
7
7
|
from . import platform, syntax
|
|
8
8
|
|
|
@@ -19,6 +19,10 @@ def compile_ordering_text(text, vendor):
|
|
|
19
19
|
"global": {
|
|
20
20
|
"validator": valid_bool,
|
|
21
21
|
"default": False,
|
|
22
|
+
},
|
|
23
|
+
"scope": {
|
|
24
|
+
"validator": valid_string_list,
|
|
25
|
+
"default": None,
|
|
22
26
|
}
|
|
23
27
|
}),
|
|
24
28
|
reverse_prefix=platform.VENDOR_REVERSES[vendor],
|
|
@@ -49,6 +53,7 @@ def _compile_ordering(tree, reverse_prefix):
|
|
|
49
53
|
),
|
|
50
54
|
"order_reverse": attrs["params"]["order_reverse"],
|
|
51
55
|
"global": attrs["params"]["global"],
|
|
56
|
+
"scope": attrs["params"]["scope"],
|
|
52
57
|
"raw_rule": attrs["raw_rule"],
|
|
53
58
|
"context": attrs["context"],
|
|
54
59
|
},
|
|
@@ -25,7 +25,7 @@ VENDOR_DIFF = {
|
|
|
25
25
|
"routeros": "common.default_diff",
|
|
26
26
|
"aruba": "aruba.default_diff",
|
|
27
27
|
"pc": "common.default_diff",
|
|
28
|
-
"ribbon": "
|
|
28
|
+
"ribbon": "juniper.default_diff",
|
|
29
29
|
"b4com": "common.default_diff",
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -40,7 +40,7 @@ VENDOR_DIFF_ORDERED = {
|
|
|
40
40
|
"routeros": "common.ordered_diff",
|
|
41
41
|
"aruba": "common.ordered_diff",
|
|
42
42
|
"pc": "common.ordered_diff",
|
|
43
|
-
"ribbon": "
|
|
43
|
+
"ribbon": "juniper.ordered_diff",
|
|
44
44
|
"b4com": "common.ordered_diff",
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -387,6 +387,24 @@ class AsrFormatter(BlockExitFormatter):
|
|
|
387
387
|
yield from super().block_exit(context)
|
|
388
388
|
|
|
389
389
|
|
|
390
|
+
class JuniperPatch:
|
|
391
|
+
def __init__(self):
|
|
392
|
+
"""In the case of comments, odict is not suitable: there may be several identical edit and exit"""
|
|
393
|
+
self._items = []
|
|
394
|
+
|
|
395
|
+
def __setitem__(self, key, value):
|
|
396
|
+
self._items.append((key, value))
|
|
397
|
+
|
|
398
|
+
def keys(self):
|
|
399
|
+
return list(self)
|
|
400
|
+
|
|
401
|
+
def items(self):
|
|
402
|
+
return self._items
|
|
403
|
+
|
|
404
|
+
def __iter__(self):
|
|
405
|
+
return iter(item[0] for item in self._items)
|
|
406
|
+
|
|
407
|
+
|
|
390
408
|
class JuniperFormatter(CommonFormatter):
|
|
391
409
|
patch_set_prefix = "set"
|
|
392
410
|
|
|
@@ -399,7 +417,7 @@ class JuniperFormatter(CommonFormatter):
|
|
|
399
417
|
comment: str
|
|
400
418
|
|
|
401
419
|
def __post_init__(self):
|
|
402
|
-
self.row = self.row.strip()
|
|
420
|
+
self.row = " ".join(map(lambda x: x.strip("\"'"), self.row.strip().split(" ")))
|
|
403
421
|
self.comment = self.comment.strip()
|
|
404
422
|
|
|
405
423
|
@classmethod
|
|
@@ -458,6 +476,13 @@ class JuniperFormatter(CommonFormatter):
|
|
|
458
476
|
def patch_plain(self, patch):
|
|
459
477
|
return list(self.cmd_paths(patch).keys())
|
|
460
478
|
|
|
479
|
+
def _blocks(self, tree: "PatchTree", is_patch: bool):
|
|
480
|
+
for row in super()._blocks(tree, is_patch):
|
|
481
|
+
if isinstance(row, str) and row.startswith(self.Comment.begin):
|
|
482
|
+
yield f"{self.Comment.begin} {self.Comment.loads(row).comment} {self.Comment.end}"
|
|
483
|
+
else:
|
|
484
|
+
yield row
|
|
485
|
+
|
|
461
486
|
def _formatted_blocks(self, blocks):
|
|
462
487
|
level = 0
|
|
463
488
|
line = None
|
|
@@ -469,7 +494,7 @@ class JuniperFormatter(CommonFormatter):
|
|
|
469
494
|
elif new_line is BlockEnd:
|
|
470
495
|
level -= 1
|
|
471
496
|
if isinstance(line, str):
|
|
472
|
-
yield line + self._statement_end
|
|
497
|
+
yield line + ("" if line.endswith(self.Comment.end) else self._statement_end)
|
|
473
498
|
yield self._indent * level + self._block_end
|
|
474
499
|
elif isinstance(line, str):
|
|
475
500
|
yield line + ("" if line.endswith(self.Comment.end) else self._statement_end)
|
|
@@ -478,7 +503,8 @@ class JuniperFormatter(CommonFormatter):
|
|
|
478
503
|
yield line + self._statement_end
|
|
479
504
|
|
|
480
505
|
def cmd_paths(self, patch, _prev=tuple()):
|
|
481
|
-
commands =
|
|
506
|
+
commands = JuniperPatch()
|
|
507
|
+
|
|
482
508
|
for item in patch.itms:
|
|
483
509
|
key, childs, context = item.row, item.child, item.context
|
|
484
510
|
|
|
@@ -490,33 +516,39 @@ class JuniperFormatter(CommonFormatter):
|
|
|
490
516
|
value = (
|
|
491
517
|
""
|
|
492
518
|
if key.startswith("delete")
|
|
493
|
-
else
|
|
519
|
+
else key.removeprefix(self.Comment.begin).removesuffix(self.Comment.end).strip()
|
|
494
520
|
)
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
(
|
|
498
|
-
|
|
499
|
-
" ".join(("annotate", context["row"].split(" ")[0], f'"{value}"')),
|
|
500
|
-
"exit"
|
|
501
|
-
)
|
|
521
|
+
cmds = (
|
|
522
|
+
f"edit {' '.join(_prev)}",
|
|
523
|
+
" ".join(("annotate", context["row"].split(" ")[0], f'"{value}"')),
|
|
524
|
+
"exit"
|
|
502
525
|
)
|
|
503
526
|
elif key.startswith("delete"):
|
|
504
|
-
|
|
527
|
+
cmds = (
|
|
528
|
+
" ".join(("delete", *_prev, key.replace("delete", "", 1).strip())),
|
|
529
|
+
)
|
|
505
530
|
elif key.startswith("activate"):
|
|
506
|
-
|
|
531
|
+
cmds = (
|
|
532
|
+
" ".join(("activate", *_prev, key.replace("activate", "", 1).strip())),
|
|
533
|
+
)
|
|
507
534
|
elif key.startswith("deactivate"):
|
|
508
|
-
|
|
535
|
+
cmds = (
|
|
536
|
+
" ".join(("deactivate", *_prev, key.replace("deactivate", "", 1).strip())),
|
|
537
|
+
)
|
|
509
538
|
else:
|
|
510
|
-
|
|
539
|
+
cmds = (
|
|
540
|
+
" ".join((self.patch_set_prefix, *_prev, key.strip())),
|
|
541
|
+
)
|
|
511
542
|
|
|
512
543
|
# Expanding [ a b c ] junipers list of arguments
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
544
|
+
for cmd in cmds:
|
|
545
|
+
if matches := re.search(r"^(.*)\s+\[(.+)\]$", cmd):
|
|
546
|
+
for c in matches.group(2).split(" "):
|
|
547
|
+
if c.strip():
|
|
548
|
+
items = " ".join([matches.group(1), c])
|
|
549
|
+
commands[(items,)] = context
|
|
550
|
+
else:
|
|
551
|
+
commands[(cmd,)] = context
|
|
520
552
|
|
|
521
553
|
return commands
|
|
522
554
|
|
|
@@ -700,7 +700,7 @@ async def adeploy(
|
|
|
700
700
|
ans = deployer.ask_deploy()
|
|
701
701
|
if ans != "y":
|
|
702
702
|
return 2 ** 2
|
|
703
|
-
|
|
703
|
+
|
|
704
704
|
if sys.stdout.isatty() and not args.no_progress:
|
|
705
705
|
progress_bar = annet.deploy_ui.ProgressBars(odict([(device.fqdn, {}) for device in deploy_cmds]))
|
|
706
706
|
progress_bar.init()
|
|
@@ -4,7 +4,7 @@ import statistics
|
|
|
4
4
|
from abc import ABC, abstractmethod
|
|
5
5
|
from functools import partial
|
|
6
6
|
from operator import itemgetter
|
|
7
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, List, Optional
|
|
8
8
|
|
|
9
9
|
import colorama
|
|
10
10
|
from annet.annlib.command import Command, CommandList, Question # noqa: F401
|
|
@@ -16,28 +16,6 @@ class CommandResult(ABC):
|
|
|
16
16
|
pass
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class Connector(ABC):
|
|
20
|
-
@abstractmethod
|
|
21
|
-
async def cmd(self, cmd: Union[Command, str]) -> CommandResult:
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
@abstractmethod
|
|
25
|
-
async def download(self, files: List[str]) -> Dict[str, str]:
|
|
26
|
-
pass
|
|
27
|
-
|
|
28
|
-
@abstractmethod
|
|
29
|
-
async def upload(self, files: Dict[str, str]):
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
@abstractmethod
|
|
33
|
-
def get_conn_trace(self) -> str:
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
@abstractmethod
|
|
37
|
-
async def aclose(self) -> str:
|
|
38
|
-
pass
|
|
39
|
-
|
|
40
|
-
|
|
41
19
|
class ExecutorException(Exception):
|
|
42
20
|
def __init__(self, *args: List[Any], auxiliary: Optional[Any] = None, **kwargs: object):
|
|
43
21
|
self.auxiliary = auxiliary
|
|
@@ -14,7 +14,6 @@ from typing import (
|
|
|
14
14
|
|
|
15
15
|
from annet.lib import (
|
|
16
16
|
flatten,
|
|
17
|
-
jinja_render,
|
|
18
17
|
mako_render,
|
|
19
18
|
)
|
|
20
19
|
from .base import BaseGenerator, _filter_str
|
|
@@ -70,9 +69,6 @@ class Entire(BaseGenerator):
|
|
|
70
69
|
def mako(self, text, **kwargs) -> str:
|
|
71
70
|
return mako_render(text, dedent=True, device=self.__device, **kwargs)
|
|
72
71
|
|
|
73
|
-
def jinja(self, text, **kwargs) -> str:
|
|
74
|
-
return jinja_render(text, dedent=True, device=self.__device, **kwargs)
|
|
75
|
-
|
|
76
72
|
# =====
|
|
77
73
|
|
|
78
74
|
@classmethod
|
|
@@ -24,7 +24,6 @@ from annet.annlib.lib import ( # pylint: disable=unused-import
|
|
|
24
24
|
huawei_expand_vlandb,
|
|
25
25
|
huawei_iface_ranges,
|
|
26
26
|
is_relative,
|
|
27
|
-
jinja_render,
|
|
28
27
|
jun_activate,
|
|
29
28
|
jun_is_inactive,
|
|
30
29
|
juniper_fmt_prefix_lists_acl,
|
|
@@ -151,10 +150,15 @@ def do_async(coro: Awaitable[ReturnType], new_thread=False) -> ReturnType:
|
|
|
151
150
|
|
|
152
151
|
def wrapper(main):
|
|
153
152
|
nonlocal res
|
|
154
|
-
|
|
153
|
+
try:
|
|
154
|
+
res = asyncio.run(main)
|
|
155
|
+
except BaseException as e:
|
|
156
|
+
res = e
|
|
155
157
|
thread = threading.Thread(target=wrapper, args=(coro,))
|
|
156
158
|
thread.start()
|
|
157
159
|
thread.join()
|
|
160
|
+
if isinstance(res, BaseException):
|
|
161
|
+
raise res
|
|
158
162
|
return res
|
|
159
163
|
else:
|
|
160
164
|
return asyncio.run(coro)
|
|
@@ -12,8 +12,8 @@ def comment_processor(item: common.DiffItem):
|
|
|
12
12
|
if item.op in (Op.REMOVED, Op.ADDED) and item.row.startswith(JuniperFormatter.Comment.begin):
|
|
13
13
|
comment = JuniperFormatter.Comment.loads(item.row)
|
|
14
14
|
|
|
15
|
+
item.diff_pre["attrs"]["context"]["comment"] = True
|
|
15
16
|
item.diff_pre["attrs"]["context"]["row"] = comment.row
|
|
16
|
-
item.diff_pre["attrs"]["context"]["comment"] = comment.comment
|
|
17
17
|
item.diff_pre["key"] = item.diff_pre["raw_rule"] = (
|
|
18
18
|
f"{JuniperFormatter.Comment.begin} {comment.row} {JuniperFormatter.Comment.end}"
|
|
19
19
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -14,7 +14,6 @@ Requires-Dist: jsonpointer>=2.4
|
|
|
14
14
|
Requires-Dist: PyYAML>=6.0.1
|
|
15
15
|
Requires-Dist: Pygments>=2.14.0
|
|
16
16
|
Requires-Dist: Mako>=1.2.4
|
|
17
|
-
Requires-Dist: Jinja2>=3.1.2
|
|
18
17
|
Requires-Dist: packaging>=23.2
|
|
19
18
|
Requires-Dist: contextlog>=1.1
|
|
20
19
|
Requires-Dist: valkit>=0.1.4
|
|
@@ -22,7 +21,7 @@ Requires-Dist: yarl>=1.8.2
|
|
|
22
21
|
Requires-Dist: adaptix==3.0.0b7
|
|
23
22
|
Requires-Dist: dataclass-rest==0.4
|
|
24
23
|
Provides-Extra: netbox
|
|
25
|
-
Requires-Dist: annetbox[sync]>=0.2.
|
|
24
|
+
Requires-Dist: annetbox[sync]>=0.2.1; extra == "netbox"
|
|
26
25
|
Dynamic: home-page
|
|
27
26
|
Dynamic: license
|
|
28
27
|
Dynamic: provides-extra
|
|
@@ -5,7 +5,6 @@ jsonpointer>=2.4
|
|
|
5
5
|
PyYAML>=6.0.1
|
|
6
6
|
Pygments>=2.14.0
|
|
7
7
|
Mako>=1.2.4
|
|
8
|
-
Jinja2>=3.1.2
|
|
9
8
|
packaging>=23.2
|
|
10
9
|
contextlog>=1.1
|
|
11
10
|
valkit>=0.1.4
|
|
@@ -14,4 +13,4 @@ adaptix==3.0.0b7
|
|
|
14
13
|
dataclass-rest==0.4
|
|
15
14
|
|
|
16
15
|
[netbox]
|
|
17
|
-
annetbox[sync]>=0.2.
|
|
16
|
+
annetbox[sync]>=0.2.1
|
|
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
|
|
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
|