Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41d6afc336 | ||
|
|
2901dbb5c7 | ||
|
|
37122cd76c | ||
|
|
7173564ea9 | ||
|
|
be402b1b5c |
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
description: Report a reproducible bug in the current release of NetBox
|
||||
labels: ["type: bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
**NOTE:** This form is only for reporting _reproducible bugs_. If you're having
|
||||
trouble with installation or just looking for assistance with using NetBox
|
||||
Topology Views, please visit our
|
||||
[discussion forum](https://github.com/mattieserver/netbox-topology-views/discussions) instead.
|
||||
- type: input
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v3.3.9
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Topology Views version
|
||||
description: What version of NetBox Topology Views are you currently running?
|
||||
placeholder: v3.1.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: >
|
||||
Describe in detail the exact steps that someone else can take to
|
||||
reproduce this bug using the current stable release of NetBox Topology Views.
|
||||
placeholder: |
|
||||
1. Click on "create widget"
|
||||
2. Set foo to 12 and bar to G
|
||||
3. Click the "create" button
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: What did you expect to happen?
|
||||
placeholder: A new widget should have been created with the specified attributes
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Observed Behavior
|
||||
description: What happened instead?
|
||||
placeholder: A TypeError exception was raised
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ❓ Discussion
|
||||
url: https://github.com/mattieserver/netbox-topology-views/discussions
|
||||
about: "If you're just looking for help, try starting a discussion instead"
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: ✨ Feature Request
|
||||
description: Propose a new NetBox Topology Views feature or enhancement
|
||||
labels: ["type: feature"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
**NOTE:** This form is only for submitting well-formed proposals to extend or modify
|
||||
NetBox Topology Views in some way. If you're trying to solve a problem but can't figure
|
||||
out how, or if you still need time to work on the details of a proposed new feature,
|
||||
please start a [discussion](https://github.com/mattieserver/netbox-topology-views/discussions) instead.
|
||||
- type: input
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v3.3.9
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Topology Views version
|
||||
description: What version of NetBox Topology Views are you currently running?
|
||||
placeholder: v3.1.0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Feature type
|
||||
options:
|
||||
- New functionality
|
||||
- Change to existing functionality
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposed functionality
|
||||
description: >
|
||||
Describe in detail the new feature or behavior you are proposing. Include any specific changes
|
||||
to work flows and/or the user interface. The more detail you provide here, the
|
||||
greater chance your proposal has of being discussed. Feature requests which don't include an
|
||||
actionable implementation plan will be rejected.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Use case
|
||||
description: >
|
||||
Explain how adding this functionality would benefit NetBox Topology Views users. What need does it address?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: External dependencies
|
||||
description: >
|
||||
List any new dependencies on external libraries or services that this new feature would
|
||||
introduce. For example, does the proposal require the installation of a new Python package?
|
||||
(Not all new features introduce new dependencies.)
|
||||
+138
-18
@@ -1,23 +1,143 @@
|
||||
# Setup Dev
|
||||
+ install docker
|
||||
+ install docker compose
|
||||
+ install npm
|
||||
+ enable yarn
|
||||
+ clone netbox repo
|
||||
+ clone netbox_topology_views repo
|
||||
+ create venv: `/usr/bin/python3 -m venv venv`
|
||||
+ activate venv: `source venv/bin/activate`
|
||||
+ install deps: `pip3 install -r requirements.txt`
|
||||
+ install build tools: `python3 -m pip install --upgrade build setuptools wheel`
|
||||
|
||||
We will assume that you work in the folder `~/code/netbox_plugin/`, change this if you use another folder for your projects/code.
|
||||
|
||||
## Setup native prerequisites
|
||||
**_NOTE:_** these requirements are needed if you want install Postgresql & Redis native. Check the steps for docker & docker-compose if you don't want this.
|
||||
|
||||
Make sure that you have already installed Postgresql and Redis. Also make sure that the database has already been created and privileges has been granted as described in the NetBox installation instructions at https://docs.netbox.dev/en/stable/installation/.
|
||||
|
||||
In short:
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install -y postgresql
|
||||
sudo systemctl start postgresql
|
||||
sudo systemctl enable postgresql
|
||||
|
||||
sudo -u postgres psql
|
||||
CREATE DATABASE netbox;
|
||||
CREATE USER netbox WITH PASSWORD 'J5brHrAXFLQSif0K';
|
||||
GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox;
|
||||
|
||||
sudo apt install -y redis-server
|
||||
```
|
||||
|
||||
## Setup docker prerequisites
|
||||
|
||||
**_NOTE:_** if you used the 'native' prerequisites you can skip these steps below
|
||||
|
||||
### Docker
|
||||
This depends on your OS or how you want to install docker.
|
||||
See https://docs.docker.com/engine/install/ to find the install steps.
|
||||
|
||||
### Docker compose
|
||||
This also depends on your OS, see the link below:
|
||||
https://docs.docker.com/compose/install/linux/
|
||||
|
||||
## Create the base folder
|
||||
```
|
||||
mkdir ~/code/netbox_plugin/
|
||||
cd ~/code/netbox_plugin/
|
||||
```
|
||||
|
||||
## Install requirements
|
||||
### Python + deps
|
||||
You will need the following packages installed:
|
||||
+ python3-venv
|
||||
+ python3
|
||||
|
||||
Install them with your OS package manager (apt, yum, ...)
|
||||
|
||||
|
||||
### NPM (with nvm)
|
||||
Follow the steps on the repo below to install npm:
|
||||
https://github.com/nvm-sh/nvm#installing-and-updating
|
||||
|
||||
|
||||
## Create venv
|
||||
```
|
||||
python3 -m venv ~/code/netbox_plugin/.venvs/netbox
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
```
|
||||
|
||||
## Setup netbox
|
||||
### Clone netbox repo
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
git clone git@github.com:netbox-community/netbox.git netbox
|
||||
```
|
||||
### Install deps
|
||||
```
|
||||
cd netbox
|
||||
python3 -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
|
||||
## Setup plugin
|
||||
### Clone netbox-topology-views repo
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
git clone git@github.com:mattieserver/netbox-topology-views.git plugin
|
||||
```
|
||||
### Install deps
|
||||
```
|
||||
python3 -m pip install --upgrade build setuptools wheel
|
||||
```
|
||||
### Copy netbox config file
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
cp plugin/dev_setup/configuration.py netbox/netbox/netbox/configuration.py
|
||||
```
|
||||
|
||||
## Start netbox
|
||||
### Start docker compose
|
||||
**_NOTE:_** if you used the 'native' prerequisites you can skip to 'Start netbox'
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
cd plugin/dev_setup
|
||||
docker-compose up -d
|
||||
```
|
||||
### Start netbox
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
cd netbox/netbox/
|
||||
python3 manage.py migrate
|
||||
python3 manage.py runserver
|
||||
```
|
||||
You might need to create a superuser if you want to start with an empty database: `python3 manage.py createsuperuser`
|
||||
|
||||
# Build
|
||||
+ build the package: `python3 setup.py develop`
|
||||
+ build the resources `yarn run bundle`
|
||||
|
||||
# Test
|
||||
+ copy configuration.py from dev_setup to the netbox/netbox/ folder
|
||||
+ run in the netbox repo: `python3 netbox/manage.py migrate`
|
||||
+ (first time only) run in the netbox repo: `python3 netbox/manage.py createsuperuser`
|
||||
+ run in the netbox repo: `python3 netbox/manage.py runserver`
|
||||
+ browse to http://127.0.0.1:8000
|
||||
## Build the plugin
|
||||
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
cd plugin/
|
||||
python3 setup.py develop
|
||||
```
|
||||
|
||||
## Build javascript
|
||||
```
|
||||
cd plugin/netbox_topology_views/static_dev
|
||||
npm install
|
||||
npm run bundle
|
||||
```
|
||||
|
||||
### Test
|
||||
You can now browse to http://localhost:8000.
|
||||
The plugin should be available in the menu.
|
||||
|
||||
# Import demo data
|
||||
If you want to add demo data instead of your own data, there's an official Repository you can use. The following example shows how to add demo data for NetBox v3.4. You have to use the json file according to the version you are working on.
|
||||
|
||||
```
|
||||
~/code/netbox_plugin/
|
||||
git clone git@github.com:netbox-community/netbox-demo-data.git demodata
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
cd netbox/netbox/
|
||||
python3 manage.py loaddata -v 3 ~/src/netbox-demo-data/netbox-demo-v3.4.json
|
||||
```
|
||||
|
||||
Please note that the demo data adds a superuser with credentials admin/admin.
|
||||
@@ -5,7 +5,7 @@ class TopologyViewsConfig(PluginConfig):
|
||||
name = "netbox_topology_views"
|
||||
verbose_name = "Topology views"
|
||||
description = "An plugin to render topology maps"
|
||||
version = "3.1.0"
|
||||
version = "3.1.1"
|
||||
author = "Mattijs Vanhaverbeke"
|
||||
author_email = "author@example.com"
|
||||
base_url = "netbox_topology_views"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -70,8 +70,9 @@ const coordSaveCheckbox = document.querySelector('#id_save_coords')
|
||||
graph.fit()
|
||||
|
||||
graph.on('dragEnd', (params) => {
|
||||
if (coordSaveCheckbox == null) return
|
||||
if (!coordSaveCheckbox.checked) return
|
||||
|
||||
|
||||
Promise.allSettled(
|
||||
Object.entries(graph.getPositions(params.nodes)).map(
|
||||
async ([nodeId, nodePosition]) => {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "netbox_topology_views",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "netbox_topology_views",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"scripts": {
|
||||
"bundle": "node bundle.js",
|
||||
"bundle:styles": "node bundle.js --styles",
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
from extras.plugins import PluginTemplateExtension
|
||||
from django.conf import settings
|
||||
from packaging import version
|
||||
|
||||
NETBOX_CURRENT_VERSION = version.parse(settings.VERSION)
|
||||
|
||||
|
||||
class SiteButtons(PluginTemplateExtension):
|
||||
model = 'dcim.site'
|
||||
def buttons(self):
|
||||
return self.render('netbox_topology_views/site_button.html')
|
||||
|
||||
|
||||
template_extensions = [SiteButtons]
|
||||
@@ -0,0 +1,33 @@
|
||||
{% load static %}
|
||||
|
||||
<link rel="stylesheet" href="{% static 'netbox_topology_views/css/vendor.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'netbox_topology_views/css/app.css' %}">
|
||||
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Topology Views</h5>
|
||||
<div class="controls">
|
||||
<div class="control-group">
|
||||
{% block extra_controls %}{% endblock %}
|
||||
<a id="btnDownloadImage" class="btn btn-sm btn-info" href="#">
|
||||
<i class="mdi mdi-download"></i>
|
||||
Download
|
||||
</a>
|
||||
<a class="btn btn-sm btn-danger" data-bs-dismiss="modal">
|
||||
<i class="mdi mdi-close-thick"></i>
|
||||
Close
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" >
|
||||
<div style="width: 500px; height: 500px;">
|
||||
<div id="visgraph" style="width: 100%; height: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
const brokenImage = '{{ broken_image }}';
|
||||
const topologyData = {{ topology_data | safe }};
|
||||
</script>
|
||||
<script src="{% static 'netbox_topology_views/js/app.js' %}?ver={{ epoch }} " defer></script>
|
||||
@@ -0,0 +1,4 @@
|
||||
<a role="button" class="btn btn-sm btn-primary" title="Topology" href="#" hx-get="/plugins/netbox_topology_views/topology/?site_id={{ object.id }}" hx-target="#htmx-modal-content" data-bs-toggle="modal" data-bs-target="#htmx-modal">
|
||||
<i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i>
|
||||
Topology
|
||||
</a>
|
||||
@@ -3,15 +3,26 @@ from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Type
|
||||
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Model
|
||||
from django.templatetags.static import static
|
||||
from django.utils.text import camel_case_to_spaces, re_camel_case
|
||||
|
||||
IMAGE_DIR = Path(settings.STATIC_ROOT) / "netbox_topology_views/img"
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / settings.PLUGINS_CONFIG[
|
||||
"netbox_topology_views"
|
||||
]["static_image_directory"].removeprefix("/")
|
||||
if sys.version_info >= (3,9,0):
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / settings.PLUGINS_CONFIG[
|
||||
"netbox_topology_views"
|
||||
]["static_image_directory"].removeprefix("/")
|
||||
else:
|
||||
prefix = "/"
|
||||
plugin_path = settings.PLUGINS_CONFIG["netbox_topology_views"]["static_image_directory"]
|
||||
if plugin_path.startswith(prefix):
|
||||
plugin_path_new = plugin_path[len(prefix):]
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / plugin_path_new
|
||||
else:
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / plugin_path
|
||||
|
||||
|
||||
def image_static_url(path: Path) -> str:
|
||||
@@ -21,7 +32,15 @@ def image_static_url(path: Path) -> str:
|
||||
|
||||
|
||||
def get_image_from_url(url: str) -> str:
|
||||
return url.removeprefix(settings.BASE_PATH + settings.STATIC_URL)
|
||||
url_path = settings.BASE_PATH + settings.STATIC_URL
|
||||
if sys.version_info >= (3,9,0):
|
||||
return url.removeprefix(url_path)
|
||||
else:
|
||||
if url.startswith(url_path):
|
||||
url_new = url[len(url_path):]
|
||||
return url_new
|
||||
else:
|
||||
return url
|
||||
|
||||
|
||||
IMAGE_FILETYPES = (
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import json
|
||||
from functools import reduce
|
||||
from typing import DefaultDict, Dict, Optional, Union
|
||||
import time
|
||||
|
||||
from utilities.htmx import is_htmx
|
||||
from circuits.models import Circuit, CircuitTermination
|
||||
from dcim.models import (
|
||||
Cable,
|
||||
@@ -609,6 +611,18 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
||||
query_string = q.urlencode()
|
||||
return HttpResponseRedirect(f"{request.path}?{query_string}")
|
||||
|
||||
if is_htmx(request):
|
||||
return render(
|
||||
request,
|
||||
"netbox_topology_views/htmx_topology.html",
|
||||
{
|
||||
"filter_form": DeviceFilterForm(request.GET, label_suffix=""),
|
||||
"topology_data": json.dumps(topo_data),
|
||||
"broken_image": find_image_url("role-unknown"),
|
||||
"epoch": int(time.time()),
|
||||
},
|
||||
)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"netbox_topology_views/index.html",
|
||||
|
||||
Reference in New Issue
Block a user