annet 1.0.2__tar.gz → 1.0.3__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.0.2/annet.egg-info → annet-1.0.3}/PKG-INFO +2 -2
- {annet-1.0.2 → annet-1.0.3}/annet/__init__.py +0 -5
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/models.py +12 -7
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/storage_opts.py +17 -2
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/v37/storage.py +5 -36
- {annet-1.0.2 → annet-1.0.3}/annet/bgp_models.py +1 -0
- {annet-1.0.2 → annet-1.0.3}/annet/connectors.py +12 -15
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/executor.py +9 -8
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/peer_models.py +1 -0
- {annet-1.0.2 → annet-1.0.3/annet.egg-info}/PKG-INFO +2 -2
- {annet-1.0.2 → annet-1.0.3}/annet.egg-info/requires.txt +1 -1
- {annet-1.0.2 → annet-1.0.3}/setup.py +1 -1
- {annet-1.0.2 → annet-1.0.3}/AUTHORS +0 -0
- {annet-1.0.2 → annet-1.0.3}/LICENSE +0 -0
- {annet-1.0.2 → annet-1.0.3}/MANIFEST.in +0 -0
- {annet-1.0.2 → annet-1.0.3}/README.md +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/fetchers/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/fetchers/stub/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/fetchers/stub/fetcher.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/file/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/file/provider.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/client.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/manufacturer.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/query.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/common/status_client.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/provider.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/v24/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/v24/storage.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/adapters/netbox/v37/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annet.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/command.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/diff.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/errors.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/filter_acl.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/jsontools.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/lib.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/db.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/devdb/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/devdb/data/devdb.json +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/views/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/views/dump.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/netdev/views/hardware.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/output.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/patching.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rbparser/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rbparser/acl.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rbparser/deploying.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rbparser/ordering.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rbparser/platform.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rbparser/syntax.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rulebook/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/rulebook/common.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/tabparser.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/annlib/types.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/api/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/argparse.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/cli.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/cli_args.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/configs/context.yml +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/configs/logging.yaml +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/deploy.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/deploy_ui.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/diff.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/executor.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/filtering.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/gen.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/base.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/common/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/common/initial.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/entire.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/exceptions.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/jsonfragment.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/partial.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/perf.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/ref.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/generators/result.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/hardware.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/implicit.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/lib.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/basemodel.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/device_models.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/match_args.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/models_converter.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/port_processor.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/mesh/registry.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/output.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/parallel.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/patching.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/reference.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/action.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/condition.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/match_builder.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/policy.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/result.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/routemap.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl/statement_builder.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/aspath.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/community.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/cumulus_frr.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/entities.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/execute.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/policy.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/prefix_lists.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rpl_generators/rd.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/arista/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/arista/iface.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/aruba/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/aruba/ap_env.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/aruba/misc.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/b4com/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/b4com/file.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/b4com/iface.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/cisco/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/cisco/iface.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/cisco/misc.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/cisco/vlandb.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/common.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/deploying.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/huawei/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/huawei/aaa.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/huawei/bgp.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/huawei/iface.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/huawei/misc.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/huawei/vlandb.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/juniper/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/nexus/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/nexus/iface.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/patching.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/ribbon/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/routeros/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/routeros/file.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/arista.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/arista.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/arista.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/aruba.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/aruba.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/aruba.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/b4com.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/b4com.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/b4com.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/cisco.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/cisco.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/cisco.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/huawei.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/huawei.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/huawei.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/juniper.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/nexus.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/nexus.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/nexus.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/nokia.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/optixtrans.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/optixtrans.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/optixtrans.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/pc.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/pc.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/pc.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/ribbon.deploy +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/ribbon.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/routeros.order +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/rulebook/texts/routeros.rul +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/storage.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/tabparser.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/text_term_format.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/tracing.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet/types.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet.egg-info/SOURCES.txt +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet.egg-info/dependency_links.txt +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet.egg-info/entry_points.txt +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet.egg-info/top_level.txt +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/example/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/example/lldp.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/mesh_example/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/mesh_example/bgp.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/mesh_example/mesh_logic.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/rpl_example/__init__.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/rpl_example/generator.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/rpl_example/items.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/rpl_example/mesh.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/annet_generators/rpl_example/route_policy.py +0 -0
- {annet-1.0.2 → annet-1.0.3}/requirements.txt +0 -0
- {annet-1.0.2 → annet-1.0.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -23,7 +23,7 @@ Requires-Dist: yarl>=1.8.2
|
|
|
23
23
|
Requires-Dist: adaptix==3.0.0b7
|
|
24
24
|
Requires-Dist: dataclass-rest==0.4
|
|
25
25
|
Provides-Extra: netbox
|
|
26
|
-
Requires-Dist: annetbox[sync]>=0.
|
|
26
|
+
Requires-Dist: annetbox[sync]>=0.2.0; extra == "netbox"
|
|
27
27
|
Dynamic: home-page
|
|
28
28
|
Dynamic: license
|
|
29
29
|
Dynamic: provides-extra
|
|
@@ -49,11 +49,6 @@ def init(options: Namespace):
|
|
|
49
49
|
colorama.init = lambda *_, **__: None
|
|
50
50
|
colorama.init()
|
|
51
51
|
|
|
52
|
-
# Workaround for Python 3.8.0: https://bugs.python.org/issue38529
|
|
53
|
-
import asyncio.streams
|
|
54
|
-
if hasattr(asyncio.streams.StreamReaderProtocol, "_on_reader_gc"):
|
|
55
|
-
asyncio.streams.StreamReaderProtocol._on_reader_gc = lambda *args, **kwargs: None # pylint: disable=protected-access
|
|
56
|
-
|
|
57
52
|
|
|
58
53
|
def assert_python_version():
|
|
59
54
|
if sys.version_info < (3, 10, 0):
|
|
@@ -192,20 +192,25 @@ class NetboxDevice(Entity):
|
|
|
192
192
|
breed: str
|
|
193
193
|
|
|
194
194
|
interfaces: List[Interface]
|
|
195
|
-
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def neighbors(self) -> List["Entity"]:
|
|
198
|
+
return [
|
|
199
|
+
endpoint.device
|
|
200
|
+
for iface in self.interfaces
|
|
201
|
+
if iface.connected_endpoints
|
|
202
|
+
for endpoint in iface.connected_endpoints
|
|
203
|
+
if endpoint.device
|
|
204
|
+
]
|
|
196
205
|
|
|
197
206
|
# compat
|
|
198
207
|
@property
|
|
199
208
|
def neighbours_fqdns(self) -> list[str]:
|
|
200
|
-
|
|
201
|
-
return []
|
|
202
|
-
return [dev.fqdn for dev in self.neighbours]
|
|
209
|
+
return [dev.name for dev in self.neighbors]
|
|
203
210
|
|
|
204
211
|
@property
|
|
205
212
|
def neighbours_ids(self):
|
|
206
|
-
|
|
207
|
-
return []
|
|
208
|
-
return [dev.id for dev in self.neighbours]
|
|
213
|
+
return [dev.id for dev in self.neighbors]
|
|
209
214
|
|
|
210
215
|
def __hash__(self):
|
|
211
216
|
return hash((self.id, type(self)))
|
|
@@ -5,16 +5,25 @@ DEFAULT_URL = "http://localhost"
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class NetboxStorageOpts:
|
|
8
|
-
def __init__(
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
url: str,
|
|
11
|
+
token: str,
|
|
12
|
+
insecure: bool = False,
|
|
13
|
+
exact_host_filter: bool = False,
|
|
14
|
+
threads: int = 1,
|
|
15
|
+
):
|
|
9
16
|
self.url = url
|
|
10
17
|
self.token = token
|
|
11
18
|
self.insecure = insecure
|
|
12
19
|
self.exact_host_filter = exact_host_filter
|
|
20
|
+
self.threads = threads
|
|
13
21
|
|
|
14
22
|
@classmethod
|
|
15
23
|
def parse_params(cls, conf_params: Optional[dict[str, str]], cli_opts: Any):
|
|
16
24
|
url = os.getenv("NETBOX_URL") or conf_params.get("url") or DEFAULT_URL
|
|
17
25
|
token = os.getenv("NETBOX_TOKEN", "").strip() or conf_params.get("token") or ""
|
|
26
|
+
threads = os.getenv("NETBOX_CLIENT_THREADS", "").strip() or conf_params.get("threads") or "1"
|
|
18
27
|
insecure = False
|
|
19
28
|
if insecure_env := os.getenv("NETBOX_INSECURE", "").lower():
|
|
20
29
|
insecure = insecure_env in ("true", "1", "t")
|
|
@@ -24,4 +33,10 @@ class NetboxStorageOpts:
|
|
|
24
33
|
exact_host_filter = exact_host_filter_env in ("true", "1", "t")
|
|
25
34
|
else:
|
|
26
35
|
exact_host_filter = bool(conf_params.get("exact_host_filter") or False)
|
|
27
|
-
return cls(
|
|
36
|
+
return cls(
|
|
37
|
+
url=url,
|
|
38
|
+
token=token,
|
|
39
|
+
insecure=insecure,
|
|
40
|
+
exact_host_filter=exact_host_filter,
|
|
41
|
+
threads=int(threads),
|
|
42
|
+
)
|
|
@@ -24,7 +24,6 @@ logger = getLogger(__name__)
|
|
|
24
24
|
@impl_converter(recipe=[
|
|
25
25
|
link(P[api_models.Device].name, P[models.NetboxDevice].hostname),
|
|
26
26
|
link(P[api_models.Device].name, P[models.NetboxDevice].fqdn),
|
|
27
|
-
link_constant(P[models.NetboxDevice].neighbours, value=None),
|
|
28
27
|
])
|
|
29
28
|
def extend_device_base(
|
|
30
29
|
device: api_models.Device,
|
|
@@ -39,7 +38,6 @@ def extend_device_base(
|
|
|
39
38
|
def extend_device(
|
|
40
39
|
device: api_models.Device,
|
|
41
40
|
interfaces: List[models.Interface],
|
|
42
|
-
neighbours: Optional[List[models.NetboxDevice]],
|
|
43
41
|
storage: Storage,
|
|
44
42
|
) -> models.NetboxDevice:
|
|
45
43
|
platform_name: str = ""
|
|
@@ -64,7 +62,6 @@ def extend_device(
|
|
|
64
62
|
hw=hw,
|
|
65
63
|
storage=storage,
|
|
66
64
|
)
|
|
67
|
-
res.neighbours = neighbours
|
|
68
65
|
return res
|
|
69
66
|
|
|
70
67
|
|
|
@@ -91,6 +88,7 @@ class NetboxStorageV37(Storage):
|
|
|
91
88
|
url = ""
|
|
92
89
|
token = ""
|
|
93
90
|
self.exact_host_filter = False
|
|
91
|
+
threads = 1
|
|
94
92
|
if opts:
|
|
95
93
|
if opts.insecure:
|
|
96
94
|
ctx = ssl.create_default_context()
|
|
@@ -98,8 +96,10 @@ class NetboxStorageV37(Storage):
|
|
|
98
96
|
ctx.verify_mode = ssl.CERT_NONE
|
|
99
97
|
url = opts.url
|
|
100
98
|
token = opts.token
|
|
99
|
+
threads = opts.threads
|
|
101
100
|
self.exact_host_filter = opts.exact_host_filter
|
|
102
|
-
|
|
101
|
+
|
|
102
|
+
self.netbox = NetboxV37(url=url, token=token, ssl_context=ctx, threads=threads)
|
|
103
103
|
self._all_fqdns: Optional[list[str]] = None
|
|
104
104
|
self._id_devices: dict[int, models.NetboxDevice] = {}
|
|
105
105
|
self._name_devices: dict[str, models.NetboxDevice] = {}
|
|
@@ -174,7 +174,6 @@ class NetboxStorageV37(Storage):
|
|
|
174
174
|
device.id: extend_device(
|
|
175
175
|
device=device,
|
|
176
176
|
interfaces=[],
|
|
177
|
-
neighbours=[],
|
|
178
177
|
storage=self,
|
|
179
178
|
)
|
|
180
179
|
for device in self._load_devices(query)
|
|
@@ -186,16 +185,8 @@ class NetboxStorageV37(Storage):
|
|
|
186
185
|
self._record_device(device)
|
|
187
186
|
|
|
188
187
|
interfaces = self._load_interfaces(list(device_ids))
|
|
189
|
-
neighbours = {x.id: x for x in self._load_neighbours(interfaces)}
|
|
190
|
-
neighbours_seen: dict[str, set] = defaultdict(set)
|
|
191
|
-
|
|
192
188
|
for interface in interfaces:
|
|
193
189
|
device_ids[interface.device.id].interfaces.append(interface)
|
|
194
|
-
for e in interface.connected_endpoints or []:
|
|
195
|
-
neighbour = neighbours[e.device.id]
|
|
196
|
-
if neighbour.id not in neighbours_seen[interface.device.id]:
|
|
197
|
-
neighbours_seen[interface.device.id].add(neighbour.id)
|
|
198
|
-
device_ids[interface.device.id].neighbours.append(neighbour)
|
|
199
190
|
|
|
200
191
|
return list(device_ids.values())
|
|
201
192
|
|
|
@@ -233,8 +224,7 @@ class NetboxStorageV37(Storage):
|
|
|
233
224
|
extended_ifaces[ip.assigned_object_id].ip_addresses.append(ip)
|
|
234
225
|
return list(extended_ifaces.values())
|
|
235
226
|
|
|
236
|
-
def _load_interfaces(self, device_ids: List[int]) -> List[
|
|
237
|
-
models.Interface]:
|
|
227
|
+
def _load_interfaces(self, device_ids: List[int]) -> List[models.Interface]:
|
|
238
228
|
interfaces = self.netbox.dcim_all_interfaces(device_id=device_ids)
|
|
239
229
|
return self._extend_interfaces(interfaces.results)
|
|
240
230
|
|
|
@@ -242,25 +232,6 @@ class NetboxStorageV37(Storage):
|
|
|
242
232
|
interfaces = self.netbox.dcim_all_interfaces_by_id(id=ids)
|
|
243
233
|
return self._extend_interfaces(interfaces.results)
|
|
244
234
|
|
|
245
|
-
def _load_neighbours(self, interfaces: List[models.Interface]) -> List[models.NetboxDevice]:
|
|
246
|
-
endpoints = [e for i in interfaces for e in i.connected_endpoints or []]
|
|
247
|
-
remote_interfaces_ids = [e.id for e in endpoints]
|
|
248
|
-
neighbours_ids = [e.device.id for e in endpoints]
|
|
249
|
-
neighbours_ifaces_dics = defaultdict(list)
|
|
250
|
-
# load only the connected interface to speed things up
|
|
251
|
-
for iface in self._load_interfaces_by_id(remote_interfaces_ids):
|
|
252
|
-
neighbours_ifaces_dics[iface.device.id].append(iface)
|
|
253
|
-
neighbours = []
|
|
254
|
-
for neighbour in self.netbox.dcim_all_devices_by_id(id=neighbours_ids).results:
|
|
255
|
-
extended_neighbour = extend_device(
|
|
256
|
-
device=neighbour,
|
|
257
|
-
storage=self,
|
|
258
|
-
interfaces=neighbours_ifaces_dics[neighbour.id],
|
|
259
|
-
neighbours=None, # do not load recursively
|
|
260
|
-
)
|
|
261
|
-
neighbours.append(extended_neighbour)
|
|
262
|
-
return neighbours
|
|
263
|
-
|
|
264
235
|
def get_device(
|
|
265
236
|
self, obj_id, preload_neighbors=False, use_mesh=None,
|
|
266
237
|
**kwargs,
|
|
@@ -270,13 +241,11 @@ class NetboxStorageV37(Storage):
|
|
|
270
241
|
|
|
271
242
|
device = self.netbox.dcim_device(obj_id)
|
|
272
243
|
interfaces = self._load_interfaces([device.id])
|
|
273
|
-
neighbours = self._load_neighbours(interfaces)
|
|
274
244
|
|
|
275
245
|
res = extend_device(
|
|
276
246
|
device=device,
|
|
277
247
|
storage=self,
|
|
278
248
|
interfaces=interfaces,
|
|
279
|
-
neighbours=neighbours,
|
|
280
249
|
)
|
|
281
250
|
self._record_device(res)
|
|
282
251
|
return res
|
|
@@ -111,33 +111,30 @@ class AdapterWithName(ABC):
|
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
def get_connector_from_config(config_key: str, connectors: List[Type[Connector]]) -> Tuple[Connector, Dict[str, Any]]:
|
|
114
|
-
seen: list[str] = []
|
|
115
114
|
if not connectors:
|
|
116
115
|
raise Exception("empty connectors")
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
|
|
117
|
+
# handle configuration
|
|
118
|
+
connector_params = dict[str, Any]() # default
|
|
119
119
|
if context_storage := get_context().get(config_key):
|
|
120
|
-
adapter_name = context_storage.get("adapter", None)
|
|
121
120
|
connector_params = context_storage.get("params", {})
|
|
122
|
-
if adapter_name:
|
|
121
|
+
if adapter_name := context_storage.get("adapter", None):
|
|
122
|
+
seen = list[str]()
|
|
123
123
|
for con in connectors:
|
|
124
|
-
con_name = connector.__name__
|
|
125
124
|
if issubclass(con, AdapterWithName):
|
|
126
125
|
con_name = con.name()
|
|
126
|
+
else:
|
|
127
|
+
con_name = con.__name__
|
|
127
128
|
seen.append(con_name)
|
|
128
129
|
if adapter_name == con_name:
|
|
129
|
-
|
|
130
|
+
connectors = [con]
|
|
130
131
|
break
|
|
131
132
|
else:
|
|
132
133
|
raise Exception("unknown %s %s: seen %s" % (config_key, adapter_name, seen))
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
else:
|
|
138
|
-
connector = connectors[0]
|
|
139
|
-
if len(connectors) > 1:
|
|
140
|
-
warnings.warn(f"Please specify '{config_key}'. Found more than one classes {connectors}", UserWarning)
|
|
134
|
+
|
|
135
|
+
if len(connectors) > 1:
|
|
136
|
+
warnings.warn(f"Please specify adapter for '{config_key}'. Found more than one classes {connectors}", UserWarning)
|
|
137
|
+
connector = connectors[0]
|
|
141
138
|
if issubclass(connector, AdapterWithConfig):
|
|
142
139
|
connector_ins = connector.with_config(**connector_params)
|
|
143
140
|
else:
|
|
@@ -132,30 +132,30 @@ class MeshExecutor:
|
|
|
132
132
|
# we can have multiple rules for the same pair
|
|
133
133
|
# we merge them according to remote fqdn
|
|
134
134
|
neighbor_peers: dict[PeerKey, Pair] = {}
|
|
135
|
-
# TODO batch resolve
|
|
136
135
|
rules = self._registry.lookup_direct(device.fqdn, device.neighbours_fqdns)
|
|
137
136
|
fqdns = {
|
|
138
137
|
rule.name_right if rule.direct_order else rule.name_left
|
|
139
138
|
for rule in rules
|
|
140
139
|
}
|
|
141
|
-
|
|
140
|
+
logger.debug("Loading neighbor devices: %s", fqdns)
|
|
141
|
+
neighbors = {
|
|
142
142
|
d.fqdn: d for d in self._storage.make_devices(list(fqdns))
|
|
143
143
|
}
|
|
144
144
|
for rule in rules:
|
|
145
145
|
handler_name = self._handler_name(rule.handler)
|
|
146
146
|
if rule.direct_order:
|
|
147
|
-
if rule.name_right not in
|
|
148
|
-
print(list(neigbors), flush=True)
|
|
147
|
+
if rule.name_right not in neighbors:
|
|
149
148
|
raise ValueError(
|
|
150
|
-
f"Device `{device.fqdn}` has no neighbor `{rule.name_right}`
|
|
149
|
+
f"Device `{device.fqdn}` has no neighbor `{rule.name_right}` "
|
|
150
|
+
f"required for `{handler_name}`. {list(neighbors)}",
|
|
151
151
|
)
|
|
152
|
-
neighbor_device =
|
|
152
|
+
neighbor_device = neighbors[rule.name_right]
|
|
153
153
|
else:
|
|
154
|
-
if rule.name_left not in
|
|
154
|
+
if rule.name_left not in neighbors:
|
|
155
155
|
raise ValueError(
|
|
156
156
|
f"Device `{device.fqdn}` has no neighbor `{rule.name_left}` required for `{handler_name}`",
|
|
157
157
|
)
|
|
158
|
-
neighbor_device =
|
|
158
|
+
neighbor_device = neighbors[rule.name_left]
|
|
159
159
|
all_connected_ports = [
|
|
160
160
|
(p1.name, p2.name)
|
|
161
161
|
for p1, p2 in self._storage.search_connections(device, neighbor_device)
|
|
@@ -238,6 +238,7 @@ class MeshExecutor:
|
|
|
238
238
|
rule.name_right if rule.direct_order else rule.name_left
|
|
239
239
|
for rule in rules
|
|
240
240
|
}
|
|
241
|
+
logger.debug("Loading indirect connected devices: %s", fqdns)
|
|
241
242
|
connected_devices = {
|
|
242
243
|
d.fqdn: d for d in self._storage.make_devices(list(fqdns))
|
|
243
244
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: annet
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: annet
|
|
5
5
|
Home-page: https://github.com/annetutil/annet
|
|
6
6
|
License: MIT
|
|
@@ -23,7 +23,7 @@ Requires-Dist: yarl>=1.8.2
|
|
|
23
23
|
Requires-Dist: adaptix==3.0.0b7
|
|
24
24
|
Requires-Dist: dataclass-rest==0.4
|
|
25
25
|
Provides-Extra: netbox
|
|
26
|
-
Requires-Dist: annetbox[sync]>=0.
|
|
26
|
+
Requires-Dist: annetbox[sync]>=0.2.0; extra == "netbox"
|
|
27
27
|
Dynamic: home-page
|
|
28
28
|
Dynamic: license
|
|
29
29
|
Dynamic: provides-extra
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|