forward-netbox 0.1.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.
- forward_netbox-0.1.1/LICENSE +21 -0
- forward_netbox-0.1.1/PKG-INFO +148 -0
- forward_netbox-0.1.1/README.md +125 -0
- forward_netbox-0.1.1/forward_netbox/__init__.py +17 -0
- forward_netbox-0.1.1/forward_netbox/api/__init__.py +1 -0
- forward_netbox-0.1.1/forward_netbox/api/serializers.py +174 -0
- forward_netbox-0.1.1/forward_netbox/api/urls.py +16 -0
- forward_netbox-0.1.1/forward_netbox/api/views.py +221 -0
- forward_netbox-0.1.1/forward_netbox/choices.py +74 -0
- forward_netbox-0.1.1/forward_netbox/exceptions.py +14 -0
- forward_netbox-0.1.1/forward_netbox/filtersets.py +150 -0
- forward_netbox-0.1.1/forward_netbox/forms.py +481 -0
- forward_netbox-0.1.1/forward_netbox/jobs.py +164 -0
- forward_netbox-0.1.1/forward_netbox/management/__init__.py +0 -0
- forward_netbox-0.1.1/forward_netbox/management/commands/__init__.py +0 -0
- forward_netbox-0.1.1/forward_netbox/management/commands/forward_smoke_sync.py +262 -0
- forward_netbox-0.1.1/forward_netbox/migrations/0001_initial.py +306 -0
- forward_netbox-0.1.1/forward_netbox/migrations/__init__.py +0 -0
- forward_netbox-0.1.1/forward_netbox/models.py +628 -0
- forward_netbox-0.1.1/forward_netbox/navigation.py +62 -0
- forward_netbox-0.1.1/forward_netbox/queries/__init__.py +0 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_device_models.nqe +23 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_device_types.nqe +19 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_device_vendors.nqe +18 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_devices.nqe +38 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_interfaces.nqe +40 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_inventory_items.nqe +29 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_ip_addresses.nqe +143 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_locations.nqe +30 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_mac_addresses.nqe +16 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_platforms.nqe +20 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_prefixes_ipv4.nqe +23 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_prefixes_ipv6.nqe +23 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_virtual_chassis.nqe +27 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_vlans.nqe +21 -0
- forward_netbox-0.1.1/forward_netbox/queries/forward_vrfs.nqe +17 -0
- forward_netbox-0.1.1/forward_netbox/queries/netbox_utilities.nqe +68 -0
- forward_netbox-0.1.1/forward_netbox/signals.py +36 -0
- forward_netbox-0.1.1/forward_netbox/tables.py +163 -0
- forward_netbox-0.1.1/forward_netbox/template_content.py +1 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/forwardingestion.html +154 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/forwardnqemap.html +74 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/forwardsource.html +69 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/forwardsync.html +110 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/inc/diff.html +64 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/inc/logs_pending.html +6 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/inc/merge_form.html +19 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/ingestion_all.html +30 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/ingestion_merge_button.html +19 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/ingestion_progress.html +34 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/ingestion_statistics.html +20 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/ingestion_status.html +3 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/job_logs.html +85 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/object_tabs.html +9 -0
- forward_netbox-0.1.1/forward_netbox/templates/forward_netbox/partials/stage_switcher_buttons.html +18 -0
- forward_netbox-0.1.1/forward_netbox/templatetags/__init__.py +0 -0
- forward_netbox-0.1.1/forward_netbox/templatetags/forward_netbox_helpers.py +23 -0
- forward_netbox-0.1.1/forward_netbox/tests/__init__.py +0 -0
- forward_netbox-0.1.1/forward_netbox/tests/test_api_views.py +90 -0
- forward_netbox-0.1.1/forward_netbox/tests/test_forms.py +63 -0
- forward_netbox-0.1.1/forward_netbox/tests/test_forward_api.py +162 -0
- forward_netbox-0.1.1/forward_netbox/tests/test_models.py +108 -0
- forward_netbox-0.1.1/forward_netbox/tests/test_query_registry.py +293 -0
- forward_netbox-0.1.1/forward_netbox/tests/test_sync.py +341 -0
- forward_netbox-0.1.1/forward_netbox/urls.py +41 -0
- forward_netbox-0.1.1/forward_netbox/utilities/__init__.py +4 -0
- forward_netbox-0.1.1/forward_netbox/utilities/forward_api.py +233 -0
- forward_netbox-0.1.1/forward_netbox/utilities/logging.py +70 -0
- forward_netbox-0.1.1/forward_netbox/utilities/merge.py +142 -0
- forward_netbox-0.1.1/forward_netbox/utilities/query_registry.py +290 -0
- forward_netbox-0.1.1/forward_netbox/utilities/sync.py +519 -0
- forward_netbox-0.1.1/forward_netbox/views.py +475 -0
- forward_netbox-0.1.1/pyproject.toml +38 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Craig Johnson, Forward Networks
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: forward-netbox
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: NetBox plugin to sync Forward Networks data into NetBox via built-in NQE queries
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: netbox,forward,plugin,sync,nqe
|
|
8
|
+
Author: Craig Johnson
|
|
9
|
+
Author-email: craigjohnson@forwardnetworks.com
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Requires-Dist: httpx (>0.26,<0.29)
|
|
20
|
+
Requires-Dist: netboxlabs-netbox-branching (>=0.7.0)
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# Forward NetBox Plugin
|
|
24
|
+
|
|
25
|
+
`forward_netbox` is a NetBox plugin that syncs Forward Networks inventory into NetBox through direct Forward API connectivity and NQE while preserving the branch-backed sync, diff, and merge workflow.
|
|
26
|
+
|
|
27
|
+
## Release Compatibility
|
|
28
|
+
|
|
29
|
+
| Plugin Release | NetBox Version | Status |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `v0.1.1` | `4.5.x` only | Current unsupported release |
|
|
32
|
+
|
|
33
|
+
## Support Disclaimer
|
|
34
|
+
|
|
35
|
+
This repository is provided for use at your own risk. It is an unsupported release and is not an officially supported Forward Networks product. There is no warranty, support commitment, or compatibility guarantee beyond the version table above.
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- Branch-backed sync, diff, and merge flow through `netbox_branching`
|
|
40
|
+
- Forward `Sources`, `NQE Maps`, `Syncs`, and `Ingestions`
|
|
41
|
+
- Built-in shipped NQE maps seeded automatically after migration
|
|
42
|
+
- Support for either published Forward `query_id` references or raw NQE `query` text
|
|
43
|
+
- Repository-authored built-in queries can share local helper modules and still execute as flattened raw NQE when bundled
|
|
44
|
+
- Automatic paging across multi-page Forward NQE result sets during sync execution
|
|
45
|
+
- Snapshot-aware execution with `latestProcessed` or an explicit Forward snapshot per sync
|
|
46
|
+
- Ingestion records that preserve the selected snapshot mode, resolved snapshot ID, and Forward snapshot metrics
|
|
47
|
+
- Built-in coverage for:
|
|
48
|
+
- `dcim.site`
|
|
49
|
+
- `dcim.manufacturer`
|
|
50
|
+
- `dcim.devicerole`
|
|
51
|
+
- `dcim.platform`
|
|
52
|
+
- `dcim.devicetype`
|
|
53
|
+
- `dcim.device`
|
|
54
|
+
- `dcim.virtualchassis`
|
|
55
|
+
- `dcim.interface`
|
|
56
|
+
- `dcim.macaddress`
|
|
57
|
+
- `dcim.inventoryitem`
|
|
58
|
+
- `ipam.vlan`
|
|
59
|
+
- `ipam.vrf`
|
|
60
|
+
- `ipam.prefix` for IPv4 and IPv6
|
|
61
|
+
- `ipam.ipaddress`
|
|
62
|
+
|
|
63
|
+
## Quickstart
|
|
64
|
+
|
|
65
|
+
1. Install the plugin into the same Python environment as NetBox:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install forward-netbox==0.1.1
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If you need an offline or pinned artifact workflow, install the wheel or source archive from GitHub Releases instead:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install /path/to/forward_netbox-0.1.1-py3-none-any.whl
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
2. Enable both plugins in the NetBox configuration:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
PLUGINS = [
|
|
81
|
+
"netbox_branching",
|
|
82
|
+
"forward_netbox",
|
|
83
|
+
]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
3. Apply migrations:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python manage.py migrate
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
4. Open NetBox and create a `Forward Source`.
|
|
93
|
+
5. Select a Forward network for that source.
|
|
94
|
+
6. Create a `Forward Sync`, choose the snapshot selector, and enable the NetBox models you want to sync.
|
|
95
|
+
7. Run an adhoc ingestion, review the staged branch diff, review the recorded snapshot details and metrics, and merge when the changes look correct.
|
|
96
|
+
|
|
97
|
+
## Test It Yourself
|
|
98
|
+
|
|
99
|
+
Use this quick validation flow after installation:
|
|
100
|
+
|
|
101
|
+
1. Create a `Forward Source` using `https://fwd.app` or your custom Forward URL.
|
|
102
|
+
2. Enter a Forward username and password, then confirm the `Network` field populates from the live Forward tenant.
|
|
103
|
+
3. Open `NQE Maps` and verify the built-in maps are present.
|
|
104
|
+
4. Create a `Forward Sync` tied to the source, leaving `Snapshot` at `latestProcessed` for the first run.
|
|
105
|
+
5. Run the sync from the sync detail page.
|
|
106
|
+
6. Review the generated `Forward Ingestion`, `Issues`, snapshot details, snapshot metrics, and change diff.
|
|
107
|
+
7. Merge the branch and confirm the synced objects appear in NetBox.
|
|
108
|
+
|
|
109
|
+
## Local Validation
|
|
110
|
+
|
|
111
|
+
The repository now includes local validation tasks:
|
|
112
|
+
|
|
113
|
+
- `invoke forward_netbox.lint`
|
|
114
|
+
- `invoke forward_netbox.check`
|
|
115
|
+
- `invoke forward_netbox.test`
|
|
116
|
+
- `invoke forward_netbox.docs`
|
|
117
|
+
- `invoke forward_netbox.package`
|
|
118
|
+
- `invoke forward_netbox.ci`
|
|
119
|
+
|
|
120
|
+
For a live Forward smoke run outside CI, set these environment variables and run the smoke task locally:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
export FORWARD_SMOKE_USERNAME='your-forward-username'
|
|
124
|
+
export FORWARD_SMOKE_PASSWORD='your-forward-password'
|
|
125
|
+
export FORWARD_SMOKE_NETWORK_ID='your-network-id'
|
|
126
|
+
invoke forward_netbox.smoke-sync
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Optional smoke-sync variables:
|
|
130
|
+
|
|
131
|
+
- `FORWARD_SMOKE_URL` defaults to `https://fwd.app`
|
|
132
|
+
- `FORWARD_SMOKE_SNAPSHOT_ID` defaults to `latestProcessed`
|
|
133
|
+
- `FORWARD_SMOKE_MODELS` accepts a comma-separated subset such as `dcim.site,dcim.device,dcim.interface`
|
|
134
|
+
- `invoke forward_netbox.smoke-sync --validate-only` runs live snapshot/query validation without executing an ingestion
|
|
135
|
+
- `invoke forward_netbox.smoke-sync --merge` will merge the staged branch after a clean run
|
|
136
|
+
|
|
137
|
+
## Documentation
|
|
138
|
+
|
|
139
|
+
- [Documentation Home](docs/README.md)
|
|
140
|
+
- [Installation](docs/01_User_Guide/README.md)
|
|
141
|
+
- [Configuration](docs/01_User_Guide/configuration.md)
|
|
142
|
+
- [Usage and Validation](docs/01_User_Guide/usage.md)
|
|
143
|
+
- [Troubleshooting](docs/01_User_Guide/troubleshooting.md)
|
|
144
|
+
- [Built-In NQE Reference](docs/02_Reference/built-in-nqe-maps.md)
|
|
145
|
+
- [Model Mapping Matrix](docs/02_Reference/model-mapping-matrix.md)
|
|
146
|
+
- [Shipped NQE Query Files](https://github.com/forwardnetworks/forward-netbox/tree/main/forward_netbox/queries)
|
|
147
|
+
- [License](LICENSE)
|
|
148
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Forward NetBox Plugin
|
|
2
|
+
|
|
3
|
+
`forward_netbox` is a NetBox plugin that syncs Forward Networks inventory into NetBox through direct Forward API connectivity and NQE while preserving the branch-backed sync, diff, and merge workflow.
|
|
4
|
+
|
|
5
|
+
## Release Compatibility
|
|
6
|
+
|
|
7
|
+
| Plugin Release | NetBox Version | Status |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `v0.1.1` | `4.5.x` only | Current unsupported release |
|
|
10
|
+
|
|
11
|
+
## Support Disclaimer
|
|
12
|
+
|
|
13
|
+
This repository is provided for use at your own risk. It is an unsupported release and is not an officially supported Forward Networks product. There is no warranty, support commitment, or compatibility guarantee beyond the version table above.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Branch-backed sync, diff, and merge flow through `netbox_branching`
|
|
18
|
+
- Forward `Sources`, `NQE Maps`, `Syncs`, and `Ingestions`
|
|
19
|
+
- Built-in shipped NQE maps seeded automatically after migration
|
|
20
|
+
- Support for either published Forward `query_id` references or raw NQE `query` text
|
|
21
|
+
- Repository-authored built-in queries can share local helper modules and still execute as flattened raw NQE when bundled
|
|
22
|
+
- Automatic paging across multi-page Forward NQE result sets during sync execution
|
|
23
|
+
- Snapshot-aware execution with `latestProcessed` or an explicit Forward snapshot per sync
|
|
24
|
+
- Ingestion records that preserve the selected snapshot mode, resolved snapshot ID, and Forward snapshot metrics
|
|
25
|
+
- Built-in coverage for:
|
|
26
|
+
- `dcim.site`
|
|
27
|
+
- `dcim.manufacturer`
|
|
28
|
+
- `dcim.devicerole`
|
|
29
|
+
- `dcim.platform`
|
|
30
|
+
- `dcim.devicetype`
|
|
31
|
+
- `dcim.device`
|
|
32
|
+
- `dcim.virtualchassis`
|
|
33
|
+
- `dcim.interface`
|
|
34
|
+
- `dcim.macaddress`
|
|
35
|
+
- `dcim.inventoryitem`
|
|
36
|
+
- `ipam.vlan`
|
|
37
|
+
- `ipam.vrf`
|
|
38
|
+
- `ipam.prefix` for IPv4 and IPv6
|
|
39
|
+
- `ipam.ipaddress`
|
|
40
|
+
|
|
41
|
+
## Quickstart
|
|
42
|
+
|
|
43
|
+
1. Install the plugin into the same Python environment as NetBox:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install forward-netbox==0.1.1
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If you need an offline or pinned artifact workflow, install the wheel or source archive from GitHub Releases instead:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install /path/to/forward_netbox-0.1.1-py3-none-any.whl
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. Enable both plugins in the NetBox configuration:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
PLUGINS = [
|
|
59
|
+
"netbox_branching",
|
|
60
|
+
"forward_netbox",
|
|
61
|
+
]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. Apply migrations:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python manage.py migrate
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
4. Open NetBox and create a `Forward Source`.
|
|
71
|
+
5. Select a Forward network for that source.
|
|
72
|
+
6. Create a `Forward Sync`, choose the snapshot selector, and enable the NetBox models you want to sync.
|
|
73
|
+
7. Run an adhoc ingestion, review the staged branch diff, review the recorded snapshot details and metrics, and merge when the changes look correct.
|
|
74
|
+
|
|
75
|
+
## Test It Yourself
|
|
76
|
+
|
|
77
|
+
Use this quick validation flow after installation:
|
|
78
|
+
|
|
79
|
+
1. Create a `Forward Source` using `https://fwd.app` or your custom Forward URL.
|
|
80
|
+
2. Enter a Forward username and password, then confirm the `Network` field populates from the live Forward tenant.
|
|
81
|
+
3. Open `NQE Maps` and verify the built-in maps are present.
|
|
82
|
+
4. Create a `Forward Sync` tied to the source, leaving `Snapshot` at `latestProcessed` for the first run.
|
|
83
|
+
5. Run the sync from the sync detail page.
|
|
84
|
+
6. Review the generated `Forward Ingestion`, `Issues`, snapshot details, snapshot metrics, and change diff.
|
|
85
|
+
7. Merge the branch and confirm the synced objects appear in NetBox.
|
|
86
|
+
|
|
87
|
+
## Local Validation
|
|
88
|
+
|
|
89
|
+
The repository now includes local validation tasks:
|
|
90
|
+
|
|
91
|
+
- `invoke forward_netbox.lint`
|
|
92
|
+
- `invoke forward_netbox.check`
|
|
93
|
+
- `invoke forward_netbox.test`
|
|
94
|
+
- `invoke forward_netbox.docs`
|
|
95
|
+
- `invoke forward_netbox.package`
|
|
96
|
+
- `invoke forward_netbox.ci`
|
|
97
|
+
|
|
98
|
+
For a live Forward smoke run outside CI, set these environment variables and run the smoke task locally:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export FORWARD_SMOKE_USERNAME='your-forward-username'
|
|
102
|
+
export FORWARD_SMOKE_PASSWORD='your-forward-password'
|
|
103
|
+
export FORWARD_SMOKE_NETWORK_ID='your-network-id'
|
|
104
|
+
invoke forward_netbox.smoke-sync
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Optional smoke-sync variables:
|
|
108
|
+
|
|
109
|
+
- `FORWARD_SMOKE_URL` defaults to `https://fwd.app`
|
|
110
|
+
- `FORWARD_SMOKE_SNAPSHOT_ID` defaults to `latestProcessed`
|
|
111
|
+
- `FORWARD_SMOKE_MODELS` accepts a comma-separated subset such as `dcim.site,dcim.device,dcim.interface`
|
|
112
|
+
- `invoke forward_netbox.smoke-sync --validate-only` runs live snapshot/query validation without executing an ingestion
|
|
113
|
+
- `invoke forward_netbox.smoke-sync --merge` will merge the staged branch after a clean run
|
|
114
|
+
|
|
115
|
+
## Documentation
|
|
116
|
+
|
|
117
|
+
- [Documentation Home](docs/README.md)
|
|
118
|
+
- [Installation](docs/01_User_Guide/README.md)
|
|
119
|
+
- [Configuration](docs/01_User_Guide/configuration.md)
|
|
120
|
+
- [Usage and Validation](docs/01_User_Guide/usage.md)
|
|
121
|
+
- [Troubleshooting](docs/01_User_Guide/troubleshooting.md)
|
|
122
|
+
- [Built-In NQE Reference](docs/02_Reference/built-in-nqe-maps.md)
|
|
123
|
+
- [Model Mapping Matrix](docs/02_Reference/model-mapping-matrix.md)
|
|
124
|
+
- [Shipped NQE Query Files](https://github.com/forwardnetworks/forward-netbox/tree/main/forward_netbox/queries)
|
|
125
|
+
- [License](LICENSE)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from netbox.plugins import PluginConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class NetboxForwardConfig(PluginConfig):
|
|
5
|
+
name = "forward_netbox"
|
|
6
|
+
verbose_name = "NetBox Forward Networks Plugin"
|
|
7
|
+
description = "Sync Forward Networks data into NetBox using built-in NQE queries."
|
|
8
|
+
version = "0.1.1"
|
|
9
|
+
base_url = "forward"
|
|
10
|
+
min_version = "4.5.0"
|
|
11
|
+
|
|
12
|
+
def ready(self):
|
|
13
|
+
super().ready()
|
|
14
|
+
from . import signals # noqa: F401
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
config = NetboxForwardConfig
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .serializers import * # noqa: F401, F403
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
from django.contrib.contenttypes.models import ContentType
|
|
2
|
+
from netbox.api.fields import ChoiceField
|
|
3
|
+
from netbox.api.fields import ContentTypeField
|
|
4
|
+
from netbox.api.serializers import NestedGroupModelSerializer
|
|
5
|
+
from netbox_branching.api.serializers import BranchSerializer
|
|
6
|
+
from rest_framework import serializers
|
|
7
|
+
|
|
8
|
+
from forward_netbox.choices import ForwardIngestionPhaseChoices
|
|
9
|
+
from forward_netbox.choices import ForwardSourceDeploymentChoices
|
|
10
|
+
from forward_netbox.choices import ForwardSourceStatusChoices
|
|
11
|
+
from forward_netbox.choices import ForwardSyncStatusChoices
|
|
12
|
+
from forward_netbox.models import FORWARD_SUPPORTED_SYNC_MODELS
|
|
13
|
+
from forward_netbox.models import ForwardIngestion
|
|
14
|
+
from forward_netbox.models import ForwardIngestionIssue
|
|
15
|
+
from forward_netbox.models import ForwardNQEMap
|
|
16
|
+
from forward_netbox.models import ForwardSource
|
|
17
|
+
from forward_netbox.models import ForwardSync
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class EmptySerializer(serializers.Serializer):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ForwardNQEMapSerializer(NestedGroupModelSerializer):
|
|
25
|
+
netbox_model = ContentTypeField(
|
|
26
|
+
queryset=ContentType.objects.filter(FORWARD_SUPPORTED_SYNC_MODELS)
|
|
27
|
+
)
|
|
28
|
+
execution_mode = serializers.CharField(read_only=True)
|
|
29
|
+
execution_value = serializers.CharField(read_only=True)
|
|
30
|
+
|
|
31
|
+
class Meta:
|
|
32
|
+
model = ForwardNQEMap
|
|
33
|
+
fields = (
|
|
34
|
+
"id",
|
|
35
|
+
"name",
|
|
36
|
+
"display",
|
|
37
|
+
"netbox_model",
|
|
38
|
+
"query_id",
|
|
39
|
+
"query",
|
|
40
|
+
"commit_id",
|
|
41
|
+
"parameters",
|
|
42
|
+
"execution_mode",
|
|
43
|
+
"execution_value",
|
|
44
|
+
"enabled",
|
|
45
|
+
"built_in",
|
|
46
|
+
"weight",
|
|
47
|
+
"created",
|
|
48
|
+
"last_updated",
|
|
49
|
+
)
|
|
50
|
+
brief_fields = (
|
|
51
|
+
"id",
|
|
52
|
+
"name",
|
|
53
|
+
"display",
|
|
54
|
+
"netbox_model",
|
|
55
|
+
"execution_mode",
|
|
56
|
+
"execution_value",
|
|
57
|
+
"enabled",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ForwardSourceSerializer(NestedGroupModelSerializer):
|
|
62
|
+
status = ChoiceField(choices=ForwardSourceStatusChoices, read_only=True)
|
|
63
|
+
type = ChoiceField(choices=ForwardSourceDeploymentChoices)
|
|
64
|
+
|
|
65
|
+
class Meta:
|
|
66
|
+
model = ForwardSource
|
|
67
|
+
fields = (
|
|
68
|
+
"id",
|
|
69
|
+
"display",
|
|
70
|
+
"name",
|
|
71
|
+
"type",
|
|
72
|
+
"url",
|
|
73
|
+
"status",
|
|
74
|
+
"parameters",
|
|
75
|
+
"description",
|
|
76
|
+
"comments",
|
|
77
|
+
"last_synced",
|
|
78
|
+
"created",
|
|
79
|
+
"last_updated",
|
|
80
|
+
)
|
|
81
|
+
brief_fields = (
|
|
82
|
+
"id",
|
|
83
|
+
"display",
|
|
84
|
+
"name",
|
|
85
|
+
"type",
|
|
86
|
+
"url",
|
|
87
|
+
"status",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def to_representation(self, instance):
|
|
91
|
+
data = super().to_representation(instance)
|
|
92
|
+
data["parameters"] = instance.get_masked_parameters()
|
|
93
|
+
return data
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ForwardSyncSerializer(NestedGroupModelSerializer):
|
|
97
|
+
status = ChoiceField(choices=ForwardSyncStatusChoices, read_only=True)
|
|
98
|
+
source = ForwardSourceSerializer(nested=True)
|
|
99
|
+
enabled_models = serializers.SerializerMethodField(read_only=True)
|
|
100
|
+
|
|
101
|
+
class Meta:
|
|
102
|
+
model = ForwardSync
|
|
103
|
+
fields = (
|
|
104
|
+
"id",
|
|
105
|
+
"display",
|
|
106
|
+
"name",
|
|
107
|
+
"source",
|
|
108
|
+
"enabled_models",
|
|
109
|
+
"status",
|
|
110
|
+
"parameters",
|
|
111
|
+
"auto_merge",
|
|
112
|
+
"last_synced",
|
|
113
|
+
"scheduled",
|
|
114
|
+
"interval",
|
|
115
|
+
"user",
|
|
116
|
+
"created",
|
|
117
|
+
"last_updated",
|
|
118
|
+
)
|
|
119
|
+
brief_fields = (
|
|
120
|
+
"id",
|
|
121
|
+
"display",
|
|
122
|
+
"name",
|
|
123
|
+
"source",
|
|
124
|
+
"enabled_models",
|
|
125
|
+
"status",
|
|
126
|
+
"auto_merge",
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def get_enabled_models(self, obj):
|
|
130
|
+
return obj.enabled_models()
|
|
131
|
+
|
|
132
|
+
def to_representation(self, instance):
|
|
133
|
+
data = super().to_representation(instance)
|
|
134
|
+
data["parameters"] = instance.get_display_parameters()
|
|
135
|
+
return data
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class ForwardIngestionSerializer(NestedGroupModelSerializer):
|
|
139
|
+
branch = BranchSerializer(read_only=True)
|
|
140
|
+
sync = ForwardSyncSerializer(nested=True)
|
|
141
|
+
|
|
142
|
+
class Meta:
|
|
143
|
+
model = ForwardIngestion
|
|
144
|
+
fields = (
|
|
145
|
+
"id",
|
|
146
|
+
"display",
|
|
147
|
+
"name",
|
|
148
|
+
"branch",
|
|
149
|
+
"sync",
|
|
150
|
+
"snapshot_selector",
|
|
151
|
+
"snapshot_id",
|
|
152
|
+
"snapshot_info",
|
|
153
|
+
"snapshot_metrics",
|
|
154
|
+
"created",
|
|
155
|
+
)
|
|
156
|
+
brief_fields = ("id", "display", "name", "branch", "sync", "snapshot_id")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ForwardIngestionIssueSerializer(NestedGroupModelSerializer):
|
|
160
|
+
phase = ChoiceField(choices=ForwardIngestionPhaseChoices, read_only=True)
|
|
161
|
+
ingestion = ForwardIngestionSerializer(nested=True)
|
|
162
|
+
|
|
163
|
+
class Meta:
|
|
164
|
+
model = ForwardIngestionIssue
|
|
165
|
+
fields = (
|
|
166
|
+
"id",
|
|
167
|
+
"ingestion",
|
|
168
|
+
"timestamp",
|
|
169
|
+
"phase",
|
|
170
|
+
"model",
|
|
171
|
+
"message",
|
|
172
|
+
"raw_data",
|
|
173
|
+
"exception",
|
|
174
|
+
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from netbox.api.routers import NetBoxRouter
|
|
2
|
+
|
|
3
|
+
from forward_netbox.api.views import ForwardIngestionIssueViewSet
|
|
4
|
+
from forward_netbox.api.views import ForwardIngestionViewSet
|
|
5
|
+
from forward_netbox.api.views import ForwardNQEMapViewSet
|
|
6
|
+
from forward_netbox.api.views import ForwardSourceViewSet
|
|
7
|
+
from forward_netbox.api.views import ForwardSyncViewSet
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
router = NetBoxRouter()
|
|
11
|
+
router.register("source", ForwardSourceViewSet)
|
|
12
|
+
router.register("sync", ForwardSyncViewSet)
|
|
13
|
+
router.register("ingestion", ForwardIngestionViewSet)
|
|
14
|
+
router.register("ingestion-issues", ForwardIngestionIssueViewSet)
|
|
15
|
+
router.register("nqe-map", ForwardNQEMapViewSet)
|
|
16
|
+
urlpatterns = router.urls
|