unifi-network-maps 1.2.4__tar.gz → 1.3.1__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.
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/CHANGELOG.md +15 -0
- unifi_network_maps-1.3.1/LICENSES.md +10 -0
- unifi_network_maps-1.3.1/MANIFEST.in +10 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/PKG-INFO +83 -11
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/README.md +79 -6
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/pyproject.toml +13 -7
- unifi_network_maps-1.3.1/src/unifi_network_maps/__init__.py +1 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/adapters/__init__.py +1 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/adapters}/config.py +7 -1
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/adapters}/unifi.py +1 -1
- unifi_network_maps-1.3.1/src/unifi_network_maps/assets/themes/dark.yaml +47 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/assets/themes/default.yaml +47 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/cli/__init__.py +41 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/cli/__main__.py +8 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/cli/main.py +317 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/io/__init__.py +1 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/io}/debug.py +1 -1
- unifi_network_maps-1.3.1/src/unifi_network_maps/model/__init__.py +1 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/model/labels.py +35 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/model}/lldp.py +19 -33
- unifi_network_maps-1.3.1/src/unifi_network_maps/model/ports.py +23 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/model}/topology.py +246 -93
- unifi_network_maps-1.3.1/src/unifi_network_maps/render/__init__.py +1 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/render/lldp_md.py +254 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/render}/mermaid.py +26 -16
- unifi_network_maps-1.3.1/src/unifi_network_maps/render/mermaid_theme.py +46 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/render}/svg.py +224 -179
- unifi_network_maps-1.3.1/src/unifi_network_maps/render/svg_theme.py +64 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps/render/theme.py +90 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/src/unifi_network_maps.egg-info/PKG-INFO +83 -11
- unifi_network_maps-1.3.1/src/unifi_network_maps.egg-info/SOURCES.txt +99 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps.egg-info/entry_points.txt +2 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/src/unifi_network_maps.egg-info/requires.txt +1 -0
- unifi_network_maps-1.3.1/src/unifi_network_maps.egg-info/top_level.txt +1 -0
- unifi_network_maps-1.3.1/tests/test_cli.py +259 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_clients.py +8 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_config.py +16 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_debug.py +2 -2
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_export.py +1 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_groups.py +2 -2
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_labels.py +16 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_lldp.py +1 -1
- unifi_network_maps-1.3.1/tests/test_lldp_md.py +42 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_mermaid.py +7 -2
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_svg.py +21 -3
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_svg_iso.py +10 -2
- unifi_network_maps-1.3.1/tests/test_theme.py +39 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_topology.py +52 -3
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/tests/test_unifi.py +2 -2
- unifi_network_maps-1.2.4/LICENSES.md +0 -10
- unifi_network_maps-1.2.4/MANIFEST.in +0 -9
- unifi_network_maps-1.2.4/src/unifi_mermaid/__init__.py +0 -1
- unifi_network_maps-1.2.4/src/unifi_mermaid/cli.py +0 -197
- unifi_network_maps-1.2.4/src/unifi_mermaid/labels.py +0 -15
- unifi_network_maps-1.2.4/src/unifi_network_maps.egg-info/SOURCES.txt +0 -84
- unifi_network_maps-1.2.4/src/unifi_network_maps.egg-info/entry_points.txt +0 -2
- unifi_network_maps-1.2.4/src/unifi_network_maps.egg-info/top_level.txt +0 -1
- unifi_network_maps-1.2.4/tests/test_cli.py +0 -193
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/CONTRIBUTING.md +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/LICENSE +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/RELEASING.md +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/SECURITY.md +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/setup.cfg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/__init__.py +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/__init__.py +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/access-point.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/ISOPACKS_LICENSE +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/block.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/cache.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/cardterminal.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/cloud.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/cronjob.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/cube.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/desktop.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/diamond.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/dns.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/document.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/firewall.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/function-module.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/image.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/laptop.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/loadbalancer.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/lock.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/mail.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/mailmultiple.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/mobiledevice.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/office.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/package-module.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/paymentcard.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/plane.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/printer.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/pyramid.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/queue.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/router.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/server.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/speech.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/sphere.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/storage.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/switch-module.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/tower.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/truck-2.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/truck.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/user.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/isometric/vm.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/laptop.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/router-network.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/server-network.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps}/assets/icons/server.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.1/src/unifi_network_maps/io}/export.py +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.1}/src/unifi_network_maps.egg-info/dependency_links.txt +0 -0
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
- TBD.
|
|
7
7
|
|
|
8
|
+
## v1.3.0
|
|
9
|
+
- Reorganized package into submodules (`adapters/`, `model/`, `render/`, `io/`, `cli/`).
|
|
10
|
+
- YAML-based theming with default + dark themes and `--theme-file`.
|
|
11
|
+
- CLI help now grouped by category; CLI logic split into focused helpers.
|
|
12
|
+
- Isometric SVG layout constants centralized; extra viewBox padding to avoid clipping.
|
|
13
|
+
- LLDP port index fallback matches `port_table` `ifname`/`name`.
|
|
14
|
+
- Added PoE/edge/device count logging and improved label ordering helpers.
|
|
15
|
+
- Coverage excludes asset packages; docs updated (options/groups + AI disclosure).
|
|
16
|
+
|
|
17
|
+
## v1.2.4
|
|
18
|
+
- Added typed `UplinkInfo`/`PortInfo` and uplink fallback for LLDP gaps.
|
|
19
|
+
- Deterministic edge ordering for repeatable output.
|
|
20
|
+
- CI publish workflow (trusted publishing) and release docs.
|
|
21
|
+
- Project metadata and packaging updated for OSS readiness.
|
|
22
|
+
|
|
8
23
|
## v1.1.0
|
|
9
24
|
- Added isometric SVG output with grid-aligned links and isometric icon set.
|
|
10
25
|
- Improved port label placement and client labeling in SVG outputs.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Third-Party Licenses
|
|
2
|
+
|
|
3
|
+
## markmanx/isopacks (MIT)
|
|
4
|
+
|
|
5
|
+
Isometric SVG icons are vendored under `src/unifi_network_maps/assets/icons/isometric/`.
|
|
6
|
+
The upstream MIT license is included at:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE
|
|
10
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include SECURITY.md
|
|
5
|
+
include CONTRIBUTING.md
|
|
6
|
+
include LICENSES.md
|
|
7
|
+
include RELEASING.md
|
|
8
|
+
recursive-include src/unifi_network_maps/assets/icons *.svg
|
|
9
|
+
recursive-include src/unifi_network_maps/assets/icons/isometric ISOPACKS_LICENSE
|
|
10
|
+
recursive-include src/unifi_network_maps/assets/themes *.yaml
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unifi-network-maps
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Dynamic UniFi ->
|
|
3
|
+
Version: 1.3.1
|
|
4
|
+
Summary: Dynamic UniFi -> network maps in mermaid or svg
|
|
5
5
|
Author: Merlijn
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/merlijntishauser/unifi-network-maps
|
|
8
8
|
Project-URL: Repository, https://github.com/merlijntishauser/unifi-network-maps
|
|
9
9
|
Project-URL: Issues, https://github.com/merlijntishauser/unifi-network-maps/issues
|
|
@@ -11,7 +11,6 @@ Project-URL: Changelog, https://github.com/merlijntishauser/unifi-network-maps/b
|
|
|
11
11
|
Keywords: unifi,mermaid,network,topology,diagram,svg
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Intended Audience :: System Administrators
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
14
|
Classifier: Operating System :: OS Independent
|
|
16
15
|
Classifier: Programming Language :: Python :: 3
|
|
17
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -23,9 +22,9 @@ Classifier: Topic :: System :: Networking
|
|
|
23
22
|
Requires-Python: >=3.10
|
|
24
23
|
Description-Content-Type: text/markdown
|
|
25
24
|
License-File: LICENSE
|
|
26
|
-
License-File: LICENSES.md
|
|
27
25
|
Requires-Dist: unifi-controller-api
|
|
28
26
|
Requires-Dist: python-dotenv
|
|
27
|
+
Requires-Dist: PyYAML
|
|
29
28
|
Provides-Extra: dev
|
|
30
29
|
Requires-Dist: pre-commit; extra == "dev"
|
|
31
30
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -66,6 +65,12 @@ export UNIFI_PASS=********
|
|
|
66
65
|
export UNIFI_VERIFY_SSL=false
|
|
67
66
|
```
|
|
68
67
|
|
|
68
|
+
Use a custom env file:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
unifi-network-maps --env-file ./site.env --stdout
|
|
72
|
+
```
|
|
73
|
+
|
|
69
74
|
## Usage
|
|
70
75
|
|
|
71
76
|
Basic map (tree layout by LLDP hops):
|
|
@@ -102,6 +107,9 @@ SVG size overrides:
|
|
|
102
107
|
|
|
103
108
|
```bash
|
|
104
109
|
unifi-network-maps --format svg --svg-width 1400 --svg-height 900 --output ./network.svg
|
|
110
|
+
|
|
111
|
+
# LLDP tables for troubleshooting
|
|
112
|
+
unifi-network-maps --format lldp-md --output ./lldp.md
|
|
105
113
|
```
|
|
106
114
|
|
|
107
115
|
Legend only:
|
|
@@ -135,26 +143,90 @@ git push origin vX.Y.Z
|
|
|
135
143
|
|
|
136
144
|
See `LICENSES.md` for third-party license info.
|
|
137
145
|
|
|
146
|
+
## Installation
|
|
147
|
+
|
|
148
|
+
PyPI: https://pypi.org/project/unifi-network-maps/
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install unifi-network-maps
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Then run:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
unifi-network-maps --help
|
|
158
|
+
```
|
|
159
|
+
|
|
138
160
|
## Options
|
|
139
161
|
|
|
140
|
-
|
|
162
|
+
The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `Output`, `Debug`).
|
|
163
|
+
|
|
164
|
+
Source:
|
|
165
|
+
- `--site`: override `UNIFI_SITE`.
|
|
166
|
+
- `--env-file`: load environment variables from a specific `.env` file.
|
|
167
|
+
|
|
168
|
+
Functional:
|
|
141
169
|
- `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
|
|
170
|
+
- `--include-clients`: add active wired clients as leaf nodes.
|
|
171
|
+
- `--client-scope wired|wireless|all`: which client types to include (default wired).
|
|
142
172
|
- `--only-unifi`: only include neighbors that are UniFi devices.
|
|
173
|
+
|
|
174
|
+
Mermaid:
|
|
143
175
|
- `--direction LR|TB`: diagram direction for Mermaid (default TB).
|
|
144
|
-
- `--stdout`: write output to stdout.
|
|
145
|
-
- `--markdown`: wrap Mermaid output in a code fence.
|
|
146
176
|
- `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
|
|
147
|
-
- `--include-clients`: add active wired clients as leaf nodes.
|
|
148
177
|
- `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
|
|
178
|
+
|
|
179
|
+
SVG:
|
|
180
|
+
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
181
|
+
- `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
|
|
182
|
+
|
|
183
|
+
Output:
|
|
184
|
+
- `--format mermaid|svg|svg-iso|lldp-md`: output format (default mermaid).
|
|
185
|
+
- `--stdout`: write output to stdout.
|
|
186
|
+
- `--markdown`: wrap Mermaid output in a code fence.
|
|
187
|
+
|
|
188
|
+
Debug:
|
|
149
189
|
- `--debug-dump`: dump gateway + sample devices to stderr for debugging.
|
|
150
190
|
- `--debug-sample N`: number of non-gateway devices in debug dump (default 2).
|
|
151
|
-
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
152
191
|
|
|
153
192
|
## Notes
|
|
154
193
|
|
|
155
194
|
- Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
|
|
156
195
|
- Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
|
|
157
196
|
- PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
|
|
158
|
-
-
|
|
197
|
+
- Wireless client links render as dashed lines to indicate the last-known upstream.
|
|
198
|
+
- SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
|
|
159
199
|
- Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
|
|
160
200
|
- SVG port labels render inside child nodes for readability.
|
|
201
|
+
|
|
202
|
+
## AI Disclosure
|
|
203
|
+
|
|
204
|
+
This project used OpenAI Codex as a coding assistant for portions of the implementation and documentation.
|
|
205
|
+
|
|
206
|
+
## Theme file
|
|
207
|
+
|
|
208
|
+
Example theme YAML (override only the values you want):
|
|
209
|
+
|
|
210
|
+
```yaml
|
|
211
|
+
mermaid:
|
|
212
|
+
nodes:
|
|
213
|
+
gateway:
|
|
214
|
+
fill: "#ffe3b3"
|
|
215
|
+
stroke: "#d98300"
|
|
216
|
+
poe_link: "#1e88e5"
|
|
217
|
+
svg:
|
|
218
|
+
links:
|
|
219
|
+
standard:
|
|
220
|
+
from: "#2ecc71"
|
|
221
|
+
to: "#1b8f4a"
|
|
222
|
+
poe:
|
|
223
|
+
from: "#1e88e5"
|
|
224
|
+
to: "#0d47a1"
|
|
225
|
+
nodes:
|
|
226
|
+
switch:
|
|
227
|
+
from: "#d6ecff"
|
|
228
|
+
to: "#b6dcff"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
|
|
232
|
+
`src/unifi_network_maps/assets/themes/dark.yaml`.
|
|
@@ -31,6 +31,12 @@ export UNIFI_PASS=********
|
|
|
31
31
|
export UNIFI_VERIFY_SSL=false
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
Use a custom env file:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
unifi-network-maps --env-file ./site.env --stdout
|
|
38
|
+
```
|
|
39
|
+
|
|
34
40
|
## Usage
|
|
35
41
|
|
|
36
42
|
Basic map (tree layout by LLDP hops):
|
|
@@ -67,6 +73,9 @@ SVG size overrides:
|
|
|
67
73
|
|
|
68
74
|
```bash
|
|
69
75
|
unifi-network-maps --format svg --svg-width 1400 --svg-height 900 --output ./network.svg
|
|
76
|
+
|
|
77
|
+
# LLDP tables for troubleshooting
|
|
78
|
+
unifi-network-maps --format lldp-md --output ./lldp.md
|
|
70
79
|
```
|
|
71
80
|
|
|
72
81
|
Legend only:
|
|
@@ -100,26 +109,90 @@ git push origin vX.Y.Z
|
|
|
100
109
|
|
|
101
110
|
See `LICENSES.md` for third-party license info.
|
|
102
111
|
|
|
112
|
+
## Installation
|
|
113
|
+
|
|
114
|
+
PyPI: https://pypi.org/project/unifi-network-maps/
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pip install unifi-network-maps
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then run:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
unifi-network-maps --help
|
|
124
|
+
```
|
|
125
|
+
|
|
103
126
|
## Options
|
|
104
127
|
|
|
105
|
-
|
|
128
|
+
The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `Output`, `Debug`).
|
|
129
|
+
|
|
130
|
+
Source:
|
|
131
|
+
- `--site`: override `UNIFI_SITE`.
|
|
132
|
+
- `--env-file`: load environment variables from a specific `.env` file.
|
|
133
|
+
|
|
134
|
+
Functional:
|
|
106
135
|
- `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
|
|
136
|
+
- `--include-clients`: add active wired clients as leaf nodes.
|
|
137
|
+
- `--client-scope wired|wireless|all`: which client types to include (default wired).
|
|
107
138
|
- `--only-unifi`: only include neighbors that are UniFi devices.
|
|
139
|
+
|
|
140
|
+
Mermaid:
|
|
108
141
|
- `--direction LR|TB`: diagram direction for Mermaid (default TB).
|
|
109
|
-
- `--stdout`: write output to stdout.
|
|
110
|
-
- `--markdown`: wrap Mermaid output in a code fence.
|
|
111
142
|
- `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
|
|
112
|
-
- `--include-clients`: add active wired clients as leaf nodes.
|
|
113
143
|
- `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
|
|
144
|
+
|
|
145
|
+
SVG:
|
|
146
|
+
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
147
|
+
- `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
|
|
148
|
+
|
|
149
|
+
Output:
|
|
150
|
+
- `--format mermaid|svg|svg-iso|lldp-md`: output format (default mermaid).
|
|
151
|
+
- `--stdout`: write output to stdout.
|
|
152
|
+
- `--markdown`: wrap Mermaid output in a code fence.
|
|
153
|
+
|
|
154
|
+
Debug:
|
|
114
155
|
- `--debug-dump`: dump gateway + sample devices to stderr for debugging.
|
|
115
156
|
- `--debug-sample N`: number of non-gateway devices in debug dump (default 2).
|
|
116
|
-
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
117
157
|
|
|
118
158
|
## Notes
|
|
119
159
|
|
|
120
160
|
- Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
|
|
121
161
|
- Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
|
|
122
162
|
- PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
|
|
123
|
-
-
|
|
163
|
+
- Wireless client links render as dashed lines to indicate the last-known upstream.
|
|
164
|
+
- SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
|
|
124
165
|
- Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
|
|
125
166
|
- SVG port labels render inside child nodes for readability.
|
|
167
|
+
|
|
168
|
+
## AI Disclosure
|
|
169
|
+
|
|
170
|
+
This project used OpenAI Codex as a coding assistant for portions of the implementation and documentation.
|
|
171
|
+
|
|
172
|
+
## Theme file
|
|
173
|
+
|
|
174
|
+
Example theme YAML (override only the values you want):
|
|
175
|
+
|
|
176
|
+
```yaml
|
|
177
|
+
mermaid:
|
|
178
|
+
nodes:
|
|
179
|
+
gateway:
|
|
180
|
+
fill: "#ffe3b3"
|
|
181
|
+
stroke: "#d98300"
|
|
182
|
+
poe_link: "#1e88e5"
|
|
183
|
+
svg:
|
|
184
|
+
links:
|
|
185
|
+
standard:
|
|
186
|
+
from: "#2ecc71"
|
|
187
|
+
to: "#1b8f4a"
|
|
188
|
+
poe:
|
|
189
|
+
from: "#1e88e5"
|
|
190
|
+
to: "#0d47a1"
|
|
191
|
+
nodes:
|
|
192
|
+
switch:
|
|
193
|
+
from: "#d6ecff"
|
|
194
|
+
to: "#b6dcff"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
|
|
198
|
+
`src/unifi_network_maps/assets/themes/dark.yaml`.
|
|
@@ -4,17 +4,17 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unifi-network-maps"
|
|
7
|
-
version = "1.
|
|
8
|
-
description = "Dynamic UniFi ->
|
|
7
|
+
version = "1.3.1"
|
|
8
|
+
description = "Dynamic UniFi -> network maps in mermaid or svg"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
|
-
license =
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
12
13
|
authors = [{ name = "Merlijn" }]
|
|
13
14
|
keywords = ["unifi", "mermaid", "network", "topology", "diagram", "svg"]
|
|
14
15
|
classifiers = [
|
|
15
16
|
"Development Status :: 3 - Alpha",
|
|
16
17
|
"Intended Audience :: System Administrators",
|
|
17
|
-
"License :: OSI Approved :: MIT License",
|
|
18
18
|
"Operating System :: OS Independent",
|
|
19
19
|
"Programming Language :: Python :: 3",
|
|
20
20
|
"Programming Language :: Python :: 3 :: Only",
|
|
@@ -27,6 +27,7 @@ classifiers = [
|
|
|
27
27
|
dependencies = [
|
|
28
28
|
"unifi-controller-api",
|
|
29
29
|
"python-dotenv",
|
|
30
|
+
"PyYAML",
|
|
30
31
|
]
|
|
31
32
|
|
|
32
33
|
[project.urls]
|
|
@@ -44,7 +45,7 @@ dev = [
|
|
|
44
45
|
]
|
|
45
46
|
|
|
46
47
|
[project.scripts]
|
|
47
|
-
unifi-network-maps = "
|
|
48
|
+
unifi-network-maps = "unifi_network_maps.cli:main"
|
|
48
49
|
|
|
49
50
|
[tool.ruff]
|
|
50
51
|
line-length = 100
|
|
@@ -59,10 +60,15 @@ line-ending = "lf"
|
|
|
59
60
|
|
|
60
61
|
[tool.pytest.ini_options]
|
|
61
62
|
testpaths = ["tests"]
|
|
63
|
+
norecursedirs = ["src/unifi_network_maps/assets"]
|
|
62
64
|
|
|
63
65
|
[tool.coverage.run]
|
|
64
66
|
branch = true
|
|
65
|
-
source = ["
|
|
67
|
+
source = ["unifi_network_maps"]
|
|
68
|
+
omit = [
|
|
69
|
+
"src/unifi_network_maps/assets/*",
|
|
70
|
+
"src/unifi_network_maps/assets/**",
|
|
71
|
+
]
|
|
66
72
|
|
|
67
73
|
[tool.coverage.report]
|
|
68
74
|
show_missing = true
|
|
@@ -71,7 +77,7 @@ show_missing = true
|
|
|
71
77
|
package-dir = {"" = "src"}
|
|
72
78
|
|
|
73
79
|
[tool.setuptools.package-data]
|
|
74
|
-
"
|
|
80
|
+
"unifi_network_maps" = [
|
|
75
81
|
"assets/icons/*.svg",
|
|
76
82
|
"assets/icons/isometric/*.svg",
|
|
77
83
|
"assets/icons/isometric/ISOPACKS_LICENSE",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.3.1"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Package module."""
|
|
@@ -26,7 +26,13 @@ class Config:
|
|
|
26
26
|
verify_ssl: bool
|
|
27
27
|
|
|
28
28
|
@classmethod
|
|
29
|
-
def from_env(cls) -> Config:
|
|
29
|
+
def from_env(cls, *, env_file: str | None = None) -> Config:
|
|
30
|
+
if env_file:
|
|
31
|
+
try:
|
|
32
|
+
from dotenv import load_dotenv
|
|
33
|
+
except ImportError:
|
|
34
|
+
raise ValueError("python-dotenv required for --env-file") from None
|
|
35
|
+
load_dotenv(dotenv_path=env_file)
|
|
30
36
|
url = os.environ.get("UNIFI_URL", "").strip()
|
|
31
37
|
site = os.environ.get("UNIFI_SITE", "default").strip()
|
|
32
38
|
user = os.environ.get("UNIFI_USER", "").strip()
|
|
@@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def _cache_dir() -> Path:
|
|
23
|
-
return Path(os.environ.get("UNIFI_CACHE_DIR", ".cache/
|
|
23
|
+
return Path(os.environ.get("UNIFI_CACHE_DIR", ".cache/unifi_network_maps"))
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def _cache_ttl_seconds() -> int:
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
mermaid:
|
|
2
|
+
nodes:
|
|
3
|
+
gateway:
|
|
4
|
+
fill: "#5c3b00"
|
|
5
|
+
stroke: "#ffb347"
|
|
6
|
+
switch:
|
|
7
|
+
fill: "#0f2b3d"
|
|
8
|
+
stroke: "#5dade2"
|
|
9
|
+
ap:
|
|
10
|
+
fill: "#0f3b2d"
|
|
11
|
+
stroke: "#2ecc71"
|
|
12
|
+
client:
|
|
13
|
+
fill: "#2b1f3b"
|
|
14
|
+
stroke: "#b084ff"
|
|
15
|
+
other:
|
|
16
|
+
fill: "#2a2a2a"
|
|
17
|
+
stroke: "#9e9e9e"
|
|
18
|
+
poe_link: "#64b5f6"
|
|
19
|
+
poe_link_width: 2
|
|
20
|
+
poe_link_arrow: "none"
|
|
21
|
+
standard_link: "#66bb6a"
|
|
22
|
+
standard_link_width: 2
|
|
23
|
+
standard_link_arrow: "none"
|
|
24
|
+
svg:
|
|
25
|
+
links:
|
|
26
|
+
standard:
|
|
27
|
+
from: "#66bb6a"
|
|
28
|
+
to: "#2e7d32"
|
|
29
|
+
poe:
|
|
30
|
+
from: "#64b5f6"
|
|
31
|
+
to: "#1e88e5"
|
|
32
|
+
nodes:
|
|
33
|
+
gateway:
|
|
34
|
+
from: "#5c3b00"
|
|
35
|
+
to: "#3e2a00"
|
|
36
|
+
switch:
|
|
37
|
+
from: "#0f2b3d"
|
|
38
|
+
to: "#0a1f2c"
|
|
39
|
+
ap:
|
|
40
|
+
from: "#0f3b2d"
|
|
41
|
+
to: "#0b2a20"
|
|
42
|
+
client:
|
|
43
|
+
from: "#2b1f3b"
|
|
44
|
+
to: "#20162b"
|
|
45
|
+
other:
|
|
46
|
+
from: "#2a2a2a"
|
|
47
|
+
to: "#1f1f1f"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
mermaid:
|
|
2
|
+
nodes:
|
|
3
|
+
gateway:
|
|
4
|
+
fill: "#ffe3b3"
|
|
5
|
+
stroke: "#d98300"
|
|
6
|
+
switch:
|
|
7
|
+
fill: "#d6ecff"
|
|
8
|
+
stroke: "#3a7bd5"
|
|
9
|
+
ap:
|
|
10
|
+
fill: "#d7f5e7"
|
|
11
|
+
stroke: "#27ae60"
|
|
12
|
+
client:
|
|
13
|
+
fill: "#f2e5ff"
|
|
14
|
+
stroke: "#7f3fbf"
|
|
15
|
+
other:
|
|
16
|
+
fill: "#eeeeee"
|
|
17
|
+
stroke: "#8f8f8f"
|
|
18
|
+
poe_link: "#1e88e5"
|
|
19
|
+
poe_link_width: 2
|
|
20
|
+
poe_link_arrow: "none"
|
|
21
|
+
standard_link: "#2ecc71"
|
|
22
|
+
standard_link_width: 2
|
|
23
|
+
standard_link_arrow: "none"
|
|
24
|
+
svg:
|
|
25
|
+
links:
|
|
26
|
+
standard:
|
|
27
|
+
from: "#2ecc71"
|
|
28
|
+
to: "#1b8f4a"
|
|
29
|
+
poe:
|
|
30
|
+
from: "#1e88e5"
|
|
31
|
+
to: "#0d47a1"
|
|
32
|
+
nodes:
|
|
33
|
+
gateway:
|
|
34
|
+
from: "#ffe3b3"
|
|
35
|
+
to: "#f7c77b"
|
|
36
|
+
switch:
|
|
37
|
+
from: "#d6ecff"
|
|
38
|
+
to: "#b6dcff"
|
|
39
|
+
ap:
|
|
40
|
+
from: "#d7f5e7"
|
|
41
|
+
to: "#b8f0d2"
|
|
42
|
+
client:
|
|
43
|
+
from: "#f2e5ff"
|
|
44
|
+
to: "#e0c9ff"
|
|
45
|
+
other:
|
|
46
|
+
from: "#eeeeee"
|
|
47
|
+
to: "#d7d7d7"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""CLI package facade."""
|
|
2
|
+
|
|
3
|
+
from .main import (
|
|
4
|
+
Config,
|
|
5
|
+
SvgOptions,
|
|
6
|
+
build_client_edges,
|
|
7
|
+
build_device_index,
|
|
8
|
+
build_node_type_map,
|
|
9
|
+
build_topology,
|
|
10
|
+
debug_dump_devices,
|
|
11
|
+
fetch_clients,
|
|
12
|
+
fetch_devices,
|
|
13
|
+
group_devices_by_type,
|
|
14
|
+
main,
|
|
15
|
+
normalize_devices,
|
|
16
|
+
render_legend,
|
|
17
|
+
render_mermaid,
|
|
18
|
+
render_svg,
|
|
19
|
+
resolve_themes,
|
|
20
|
+
write_output,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"Config",
|
|
25
|
+
"SvgOptions",
|
|
26
|
+
"build_client_edges",
|
|
27
|
+
"build_device_index",
|
|
28
|
+
"build_node_type_map",
|
|
29
|
+
"build_topology",
|
|
30
|
+
"debug_dump_devices",
|
|
31
|
+
"fetch_clients",
|
|
32
|
+
"fetch_devices",
|
|
33
|
+
"group_devices_by_type",
|
|
34
|
+
"main",
|
|
35
|
+
"normalize_devices",
|
|
36
|
+
"render_legend",
|
|
37
|
+
"render_mermaid",
|
|
38
|
+
"render_svg",
|
|
39
|
+
"resolve_themes",
|
|
40
|
+
"write_output",
|
|
41
|
+
]
|