Compare commits

...
7 Commits
Author SHA1 Message Date
mattieserver 91a690f1c8 add filter by locations (#63)
* frontend for locations

* locations filter backend
2021-05-01 19:22:28 +02:00
mattieserver 5f498f9ce2 Hide unconnected (#61)
* #57 hide unconnected devices
2021-05-01 18:34:50 +02:00
mattieserver 195ac47542 added docs to setup dev (#60) 2021-05-01 17:05:32 +02:00
julianze a25be917ee Update __init__.py (#55)
fix typo toplogoy
2021-03-28 11:40:03 +02:00
mattieserver 079361b190 Update README.md 2021-02-17 11:02:58 +01:00
mattieserverandmattieserver a314d2b307 netbox v2.10 (#52)
* small changes

* removed print

* fix coords

* fix saving coords

* update readme

* fixed icons

* bump version

Co-authored-by: mattieserver <mattijs@DESKTOP-618OSU1.localdomain>
2021-02-11 19:22:41 +01:00
mattieserver 0340522f59 update jquery version to match netbox v2.9.1 (#43)
* Update full.html

* Update setup.py

* Update package.json

* Update __init__.py
2020-08-23 11:53:52 +02:00
16 changed files with 641 additions and 224 deletions
+10 -1
View File
@@ -1,5 +1,7 @@
# Netbox Topology Views Plugin
![Version](https://img.shields.io/pypi/v/netbox-topology-views) ![Downloads](https://img.shields.io/pypi/dm/netbox-topology-views)
Create topology views/maps from your devices in netbox.
The connections are based on the cables you created in netbox.
Support to filter on name, site, tag and device role.
@@ -29,9 +31,16 @@ PLUGINS = ["netbox_topology_views"]
Then run `python3 manage.py collectstatic --no-input`
### Versions
| netbox version | netbox-topology-views version |
| ------------- |-------------|
| >= 2.10.0 | >= v0.5.0 |
| < 2.10.0 | =< v0.4.10 |
### Custom field: coordinates
There is also support for custom fiels.
There is also support for custom fields.
If you create a custom field "coordinates" for "dcim > device" with type "text" and name "coordinates" you will see the same layout every time.
+22
View File
@@ -0,0 +1,22 @@
# Setup Dev
+ install docker
+ install docker compose
+ install npm
+ 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`
# Build
+ build the package: `python3 setup.py develop`
+ build the resources `npm run resources`
# 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
+40
View File
@@ -0,0 +1,40 @@
###################################################################
# This file serves as a base configuration for testing purposes #
# only. It is not intended for production use. #
###################################################################
ALLOWED_HOSTS = ['*']
DATABASE = {
'NAME': 'netbox',
'USER': 'netbox',
'PASSWORD': 'J5brHrAXFLQSif0K',
'HOST': 'localhost',
'PORT': '',
'CONN_MAX_AGE': 300,
}
DEBUG = True
PLUGINS = [
'netbox_topology_views',
]
REDIS = {
'tasks': {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': 't4Ph722qJ5QHeQ1qfu36',
'DATABASE': 0,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6378,
'PASSWORD': 'H733Kdjndks81',
'DATABASE': 1,
'SSL': False,
}
}
SECRET_KEY = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
+41
View File
@@ -0,0 +1,41 @@
version: '3.4'
services:
postgres:
image: postgres:12-alpine
environment:
POSTGRES_PASSWORD: J5brHrAXFLQSif0K #just for local dev
POSTGRES_DB: netbox
POSTGRES_USER: netbox
ports:
- "5432:5432"
volumes:
- netbox-postgres-data:/var/lib/postgresql/data
redis:
image: redis:6-alpine
command:
- sh
- -c # this is to evaluate the $REDIS_PASSWORD from the env
- redis-server --appendonly yes --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose
environment:
REDIS_PASSWORD: t4Ph722qJ5QHeQ1qfu36 #just for local dev
volumes:
- netbox-redis-data:/data
ports:
- "6379:6379"
redis-cache:
image: redis:6-alpine
command:
- sh
- -c # this is to evaluate the $REDIS_PASSWORD from the env
- redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose
environment:
REDIS_PASSWORD: H733Kdjndks81 #just for local dev
ports:
- "6378:6379"
volumes:
netbox-postgres-data:
driver: local
netbox-redis-data:
driver: local
+2 -2
View File
@@ -3,8 +3,8 @@ from extras.plugins import PluginConfig
class TopologyViewsConfig(PluginConfig):
name = 'netbox_topology_views'
verbose_name = 'Topology views'
description = 'An plugin to render toplogoy maps'
version = '0.4.9'
description = 'An plugin to render topology maps'
version = '0.5.1'
author = 'Mattijs Vanhaverbeke'
author_email = 'author@example.com'
base_url = 'topology-views'
+1
View File
@@ -0,0 +1 @@
"""REST API"""
+9 -7
View File
@@ -1,11 +1,13 @@
from rest_framework import routers
from netbox.api import OrderedDefaultRouter
from . import views
from .views import PreSelectDeviceRolesViewSet, SearchViewSet, SaveCoordsViewSet, PreSelectTagsViewSet
router = OrderedDefaultRouter()
router.APIRootView = views.TopologyViewsRootView
router = routers.DefaultRouter()
router.register('preselectdeviceroles', PreSelectDeviceRolesViewSet)
router.register('preselecttags', PreSelectTagsViewSet)
router.register('search', SearchViewSet, basename='search')
router.register('save-coords', SaveCoordsViewSet, basename='save_coords')
router.register('preselectdeviceroles', views.PreSelectDeviceRolesViewSet)
router.register('preselecttags', views.PreSelectTagsViewSet)
router.register('search', views.SearchViewSet, basename='search')
router.register('save-coords', views.SaveCoordsViewSet, basename='save_coords')
urlpatterns = router.urls
+143 -131
View File
@@ -2,15 +2,15 @@ from rest_framework.viewsets import ModelViewSet, ViewSet, ReadOnlyModelViewSet,
from rest_framework.decorators import action
from rest_framework.response import Response
from django.contrib.contenttypes.models import ContentType
from rest_framework.routers import APIRootView
from .serializers import PreDeviceRoleSerializer, TopologyDummySerializer, PreTagSerializer
from django.conf import settings
from utilities.api import IsAuthenticatedOrLoginNotRequired
from dcim.models import DeviceRole, Device, Cable
from circuits.models import Circuit
from extras.models import Tag, CustomField, CustomFieldValue
from extras.models import Tag
ignore_cable_type_raw = settings.PLUGINS_CONFIG["netbox_topology_views"]["ignore_cable_type"]
ignore_cable_type = ignore_cable_type_raw.split(",")
@@ -21,6 +21,9 @@ preselected_device_roles = preselected_device_roles_raw.split(",")
preselected_tags_raw = settings.PLUGINS_CONFIG["netbox_topology_views"]["preselected_tags"]
preselected_tags = preselected_tags_raw.split(",")
class TopologyViewsRootView(APIRootView):
def get_view_name(self):
return 'TopologyViews'
class PreSelectDeviceRolesViewSet(ReadOnlyModelViewSet):
queryset = DeviceRole.objects.filter(name__in=preselected_device_roles)
@@ -38,14 +41,6 @@ class SaveCoordsViewSet(ReadOnlyModelViewSet):
def save_coords(self, request):
results = {}
if settings.PLUGINS_CONFIG["netbox_topology_views"]["allow_coordinates_saving"]:
try:
cfCoords = CustomField.objects.get(name='coordinates')
except CustomField.DoesNotExist:
results["status"] = "coords custom field not created"
return Response(status=500)
obj_type = ContentType.objects.get_for_model(Device)
device_id = None
x_coord = None
y_coord = None
@@ -60,30 +55,30 @@ class SaveCoordsViewSet(ReadOnlyModelViewSet):
y_coord = request.data["y"]
actual_device= Device.objects.get(id=device_id)
try:
cfvCoords = CustomFieldValue.objects.get(obj_type=obj_type, obj_id=actual_device.pk, field__name='coordinates')
cfvCoords.value = "%s;%s" % (x_coord,y_coord)
cfvCoords.save()
results["status"] = "coords set"
except CustomFieldValue.DoesNotExist:
cfvCoords = CustomFieldValue(field=cfCoords, obj_type=obj_type, obj_id=actual_device.id)
cfvCoords.value = "%s;%s" % (x_coord,y_coord)
cfvCoords.save()
results["status"] = "coords set for first time"
if "coordinates" in actual_device.custom_field_data:
actual_device.custom_field_data["coordinates"] = "%s;%s" % (x_coord,y_coord)
actual_device.save()
results["status"] = "saved coords"
else:
try:
actual_device.custom_field_data["coordinates"] = "%s;%s" % (x_coord,y_coord)
actual_device.save()
results["status"] = "saved coords"
except :
results["status"] = "coords custom field not created"
return Response(status=500)
return Response(results)
else:
results["status"] = "not allowed to save coords"
return Response(results, status=500)
class SearchViewSet(ReadOnlyModelViewSet):
#_ignore_model_permissions = True
#permission_classes = [IsAuthenticatedOrLoginNotRequired]
queryset = Device.objects.all()
serializer_class = TopologyDummySerializer
def _filter(self, site, role, name, tags, region):
def _filter(self, site, role, name, tags, region, location):
filter_devices = Device.objects.all()
if name is not None:
filter_devices = filter_devices.filter(name__contains=name)
@@ -95,6 +90,8 @@ class SearchViewSet(ReadOnlyModelViewSet):
filter_devices = filter_devices.filter(tags__id__in=tags)
if region is not None:
filter_devices = filter_devices.filter(site__region__id__in=region)
if location is not None:
filter_devices = filter_devices.filter(location__id__in=location)
return filter_devices
@@ -120,7 +117,15 @@ class SearchViewSet(ReadOnlyModelViewSet):
if regions == []:
regions = None
devices = self._filter(sites, devicerole, name, tags, regions)
locations = request.query_params.getlist('locations[]', None)
if locations == []:
locations = None
hide_unconnected = request.query_params.get('hide_unconnected', None)
if hide_unconnected == "":
hide_unconnected = None
devices = self._filter(sites, devicerole, name, tags, regions, locations)
nodes = []
edges = []
@@ -129,41 +134,21 @@ class SearchViewSet(ReadOnlyModelViewSet):
circuit_ids = []
for device in devices:
cables = device.get_cables()
for cable in cables:
if cable.termination_a_type.name != "circuit termination" and cable.termination_b_type.name != "circuit termination":
if cable.id not in cable_ids:
if cable.termination_a_type.name not in ignore_cable_type and cable.termination_b_type.name not in ignore_cable_type:
cable_ids.append(cable.id)
edge_ids += 1
cable_a_dev_name = cable.termination_a.device.name
if cable_a_dev_name is None:
cable_a_dev_name = "device A name unknown"
cable_a_name = cable.termination_a.name
if cable_a_name is None:
cable_a_name = "cable A name unknown"
cable_b_dev_name = cable.termination_b.device.name
if cable_b_dev_name is None:
cable_b_dev_name = "device B name unknown"
cable_b_name = cable.termination_b.name
if cable_b_name is None:
cable_b_name = "cable B name unknown"
edge = {}
edge["id"] = edge_ids
edge["from"] = cable.termination_a.device.id
edge["to"] = cable.termination_b.device.id
edge["title"] = "Cable between <br> " + cable_a_dev_name + " [" + cable_a_name + "]<br>" + cable_b_dev_name + " [" + cable_b_name + "]"
if cable.color != "":
edge["color"] = "#" + cable.color
edges.append(edge)
else:
if cable.termination_a_type.name == "circuit termination":
if settings.PLUGINS_CONFIG["netbox_topology_views"]["enable_circuit_terminations"]:
if cable.termination_a.circuit.id not in circuit_ids:
circuit_ids.append(cable.termination_a.circuit.id)
if cables.exists():
device_has_connections = True
for cable in cables:
if cable.termination_a_type.name != "circuit termination" and cable.termination_b_type.name != "circuit termination":
if cable.id not in cable_ids:
if cable.termination_a_type.name not in ignore_cable_type and cable.termination_b_type.name not in ignore_cable_type:
cable_ids.append(cable.id)
edge_ids += 1
cable_a_dev_name = cable.termination_a.device.name
if cable_a_dev_name is None:
cable_a_dev_name = "device A name unknown"
cable_a_name = cable.termination_a.name
if cable_a_name is None:
cable_a_name = "cable A name unknown"
cable_b_dev_name = cable.termination_b.device.name
if cable_b_dev_name is None:
cable_b_dev_name = "device B name unknown"
@@ -173,89 +158,116 @@ class SearchViewSet(ReadOnlyModelViewSet):
edge = {}
edge["id"] = edge_ids
edge["from"] = cable.termination_a.device.id
edge["to"] = cable.termination_b.device.id
edge["dashes"] = True
title = ""
edge["title"] = "Cable between <br> " + cable_a_dev_name + " [" + cable_a_name + "]<br>" + cable_b_dev_name + " [" + cable_b_name + "]"
if cable.color != "":
edge["color"] = "#" + cable.color
edges.append(edge)
else:
if cable.termination_a_type.name == "circuit termination":
if settings.PLUGINS_CONFIG["netbox_topology_views"]["enable_circuit_terminations"]:
if cable.termination_a.circuit.id not in circuit_ids:
circuit_ids.append(cable.termination_a.circuit.id)
edge_ids += 1
title += "Circuit provider: " + cable.termination_a.circuit.provider.name + "<br>"
title += "Termination between <br>"
title += cable_b_dev_name + " [" + cable_b_name + "]<br>"
# To Many if's
if cable.termination_a.circuit.termination_a is not None:
if cable.termination_a.circuit.termination_a.cable is not None:
if cable.termination_a.circuit.termination_a.cable.id != cable.id:
if cable.termination_a.circuit.termination_a.cable.termination_b is not None:
if cable.termination_a.circuit.termination_a.cable.termination_b.device is not None:
edge["from"] = cable.termination_a.circuit.termination_a.cable.termination_b.device.id
cable_b_dev_name = cable.termination_b.device.name
if cable_b_dev_name is None:
cable_b_dev_name = "device B name unknown"
cable_b_name = cable.termination_b.name
if cable_b_name is None:
cable_b_name = "cable B name unknown"
cable_a_dev_name = cable.termination_a.circuit.termination_a.cable.termination_b.device.name
if cable_a_dev_name is None:
cable_a_dev_name = "device B name unknown"
cable_b_name = cable.termination_a.circuit.termination_a.cable.termination_b.name
if cable_a_name is None:
cable_a_name = "cable B name unknown"
title += cable_a_dev_name + " [" + cable_a_name + "]<br>"
edge["title"] = title
edges.append(edge)
# To Many if's
if cable.termination_a.circuit.termination_z is not None:
if cable.termination_a.circuit.termination_z.cable is not None:
if cable.termination_a.circuit.termination_z.cable.id != cable.id:
if cable.termination_a.circuit.termination_z.cable.termination_b is not None:
if cable.termination_a.circuit.termination_z.cable.termination_b.device is not None:
edge["from"] = cable.termination_a.circuit.termination_z.cable.termination_b.device.id
edge = {}
edge["id"] = edge_ids
edge["to"] = cable.termination_b.device.id
edge["dashes"] = True
title = ""
cable_a_dev_name = cable.termination_a.circuit.termination_z.cable.termination_b.device.name
if cable_a_dev_name is None:
cable_a_dev_name = "device B name unknown"
cable_a_name = cable.termination_a.circuit.termination_z.cable.termination_b.name
if cable_a_name is None:
cable_a_name = "cable B name unknown"
title += cable_a_dev_name + " [" + cable_a_name + "]<br>"
edge["title"] = title
edges.append(edge)
dev_name = device.name
if dev_name is None:
dev_name = "device name unknown"
title += "Circuit provider: " + cable.termination_a.circuit.provider.name + "<br>"
title += "Termination between <br>"
title += cable_b_dev_name + " [" + cable_b_name + "]<br>"
# To Many if's
if cable.termination_a.circuit.termination_a is not None:
if cable.termination_a.circuit.termination_a.cable is not None:
if cable.termination_a.circuit.termination_a.cable.id != cable.id:
if cable.termination_a.circuit.termination_a.cable.termination_b is not None:
if cable.termination_a.circuit.termination_a.cable.termination_b.device is not None:
edge["from"] = cable.termination_a.circuit.termination_a.cable.termination_b.device.id
node_content = ""
cable_a_dev_name = cable.termination_a.circuit.termination_a.cable.termination_b.device.name
if cable_a_dev_name is None:
cable_a_dev_name = "device B name unknown"
cable_b_name = cable.termination_a.circuit.termination_a.cable.termination_b.name
if cable_a_name is None:
cable_a_name = "cable B name unknown"
title += cable_a_dev_name + " [" + cable_a_name + "]<br>"
edge["title"] = title
edges.append(edge)
# To Many if's
if cable.termination_a.circuit.termination_z is not None:
if cable.termination_a.circuit.termination_z.cable is not None:
if cable.termination_a.circuit.termination_z.cable.id != cable.id:
if cable.termination_a.circuit.termination_z.cable.termination_b is not None:
if cable.termination_a.circuit.termination_z.cable.termination_b.device is not None:
edge["from"] = cable.termination_a.circuit.termination_z.cable.termination_b.device.id
if device.device_type.display_name is not None:
node_content += "<tr><th>Type: </th><td>" + device.device_type.display_name + "</td></tr>"
if device.device_role.name is not None:
node_content += "<tr><th>Role: </th><td>" + device.device_role.name + "</td></tr>"
if device.serial != "":
node_content += "<tr><th>Serial: </th><td>" + device.serial + "</td></tr>"
if device.primary_ip is not None:
node_content += "<tr><th>IP Address: </th><td>" + str(device.primary_ip.address) + "</td></tr>"
dev_title = "<table> %s </table>" % (node_content)
node = {}
node["id"] = device.id
node["name"] = dev_name
node["label"] = dev_name
node["title"] = dev_title
node["shape"] = 'image'
if device.device_role.slug in settings.PLUGINS_CONFIG["netbox_topology_views"]["device_img"]:
node["image"] = '../../static/netbox_topology_views/img/' + device.device_role.slug + ".png"
cable_a_dev_name = cable.termination_a.circuit.termination_z.cable.termination_b.device.name
if cable_a_dev_name is None:
cable_a_dev_name = "device B name unknown"
cable_a_name = cable.termination_a.circuit.termination_z.cable.termination_b.name
if cable_a_name is None:
cable_a_name = "cable B name unknown"
title += cable_a_dev_name + " [" + cable_a_name + "]<br>"
edge["title"] = title
edges.append(edge)
else:
node["image"] = "../../static/netbox_topology_views/img/role-unknown.png"
device_has_connections = False
if device.device_role.color != "":
node["color.border"] = "#" + device.device_role.color
if hide_unconnected == 'false' or (hide_unconnected == 'true' and device_has_connections is True):
dev_name = device.name
if dev_name is None:
dev_name = "device name unknown"
for device_custom_field in device.custom_field_values.all():
if device_custom_field.field.name == "coordinates":
cords = device_custom_field.serialized_value.split(";")
node["x"] = int(cords[0])
node["y"] = int(cords[1])
node["physics"] = False
nodes.append(node)
node_content = ""
if device.device_type.display_name is not None:
node_content += "<tr><th>Type: </th><td>" + device.device_type.display_name + "</td></tr>"
if device.device_role.name is not None:
node_content += "<tr><th>Role: </th><td>" + device.device_role.name + "</td></tr>"
if device.serial != "":
node_content += "<tr><th>Serial: </th><td>" + device.serial + "</td></tr>"
if device.primary_ip is not None:
node_content += "<tr><th>IP Address: </th><td>" + str(device.primary_ip.address) + "</td></tr>"
dev_title = "<table> %s </table>" % (node_content)
node = {}
node["id"] = device.id
node["name"] = dev_name
node["label"] = dev_name
node["title"] = dev_title
node["shape"] = 'image'
if device.device_role.slug in settings.PLUGINS_CONFIG["netbox_topology_views"]["device_img"]:
node["image"] = '../../static/netbox_topology_views/img/' + device.device_role.slug + ".png"
else:
node["image"] = "../../static/netbox_topology_views/img/role-unknown.png"
if device.device_role.color != "":
node["color.border"] = "#" + device.device_role.color
if "coordinates" in device.custom_field_data:
if device.custom_field_data["coordinates"] != "":
cords = device.custom_field_data["coordinates"].split(";")
node["x"] = int(cords[0])
node["y"] = int(cords[1])
node["physics"] = False
nodes.append(node)
results = {}
results["nodes"] = nodes
results["edges"] = edges
return Response(results)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+66 -2
View File
@@ -33,6 +33,7 @@ var options = {
}
};
var selected_regions = [];
var selected_sites = [];
function iniPlotboxIndex() {
document.addEventListener('DOMContentLoaded', function () {
@@ -113,6 +114,25 @@ function startLoadSearchBar() {
}
}
});
$('#sites').on('select2:select', function (e) {
var data = e.params.data;
var index = selected_sites.indexOf(data.id.toString());
if (index == -1) {
selected_sites.push(data.id.toString());
}
});
$('#sites').on('select2:unselect', function (e) {
var data = e.params.data;
var index = selected_sites.indexOf(data.id.toString());
if (index > -1) {
selected_sites.splice(index, 1);
}
});
$('#sites').on('select2:clear', function (e) {
selected_sites = [];
});
$('#tags').select2({
allowClear: true,
placeholder: "---------",
@@ -178,7 +198,6 @@ function startLoadSearchBar() {
$('#regions').on('select2:unselect', function (e) {
var data = e.params.data;
var index = selected_regions.indexOf(data.id.toString());
console.log(index);
if (index > -1) {
selected_regions.splice(index, 1);
}
@@ -187,6 +206,47 @@ function startLoadSearchBar() {
selected_regions = [];
});
$('#locations').select2({
allowClear: true,
placeholder: "---------",
theme: "bootstrap",
multiple: true,
ajax: {
url: function (params) {
var base_url = "../../api/dcim/locations/?brief=true";
if (selected_sites.length == 0) {
return base_url;
}
else {
for (var i = 0; i < selected_sites.length; i++) {
var tmp = "&site_id=" + selected_sites[i];
base_url = base_url + tmp;
}
return base_url;
}
},
dataType: "json",
type: "GET",
data: function (params) {
var queryParameters = {
q: params.term
}
return queryParameters;
},
processResults: function (data) {
return {
results: $.map(data.results, function (item) {
return {
text: item.name,
id: item.id
}
})
};
}
}
});
var deviceRolesSelect = $('#device-roles');
$.ajax({
@@ -232,6 +292,8 @@ function handleButtonPress() {
var value3 = $("#sites").val();
var value4 = $("#tags").val();
var value5 = $("#regions").val();
var value6 = $('#checkHideUnconnected').is(":checked");
var value7 = $("#locations").val();
$.ajax({
type: "GET",
url: "../../api/plugins/topology-views/search/search/",
@@ -240,7 +302,9 @@ function handleButtonPress() {
'devicerole[]': value2,
'sites[]': value3,
'tags[]': value4,
'regions[]': value5
'regions[]': value5,
'hide_unconnected': value6,
'locations[]': value7
},
headers: { "X-CSRFToken": csrftoken },
contentType: "application/json; charset=utf-8",
@@ -16,9 +16,9 @@
{% endblock %}
{% block javascript %}
<script src="{% static 'jquery/jquery-3.4.1.min.js' %}"></script>
<script src="{% static 'jquery/jquery-3.5.1.min.js' %}"></script>
<script src="{% static 'netbox_topology_views/js/vendor.js' %}"></script>
<script src="{% static 'netbox_topology_views/js/app.js' %}"></script>
<script type="application/javascript"> iniPlotboxFull()</script>
{% endblock %}
{% endblock %}
@@ -14,10 +14,10 @@
<strong>Network</strong> <span id="status"></span>
<div class="buttons pull-right">
<a id="btnDownloadImage" class="btn btn-xs btn-info">
<i class="fa fa-download"></i>
<i class="mdi mdi-download"></i>
</a>
<a id="btnFullView" class="btn btn-xs btn-info disabled" target="_blank">
<i class="fa fa-share"></i>
<i class="mdi mdi-share"></i>
</a>
</div>
</div>
@@ -41,18 +41,28 @@
<div class="form-group">
<label for="device-roles">Device roles</label>
<select class="form-control" multiple="multiple" id="device-roles"></select>
</div>
<div class="form-group">
<label for="regions">Regions</label>
<select class="form-control" multiple="multiple" id="regions"></select>
</div>
<div class="form-group">
<label for="sites">Sites</label>
<select class="form-control" multiple="multiple" id="sites"></select>
</div>
<div class="form-group">
<label for="locations">Locations</label>
<select class="form-control" multiple="multiple" id="locations"></select>
</div>
<div class="form-group">
<label for="tags">Tags</label>
<select class="form-control" multiple="multiple" id="tags"></select>
</div>
<div class="form-group">
<label for="regions">Regions</label>
<select class="form-control" multiple="multiple" id="regions"></select>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="checkHideUnconnected">
<label class="custom-control-label" for="checkHideUnconnected">Hide Unconnected</label>
</div>
</div>
<hr class="mb-4">
<button class="btn btn-primary btn-lg btn-block" type="submit" id="start-search">Search</button>
+282 -64
View File
@@ -1,9 +1,24 @@
{
"name": "netbox_topology_views",
"version": "0.4.8",
"version": "0.5.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@egjs/hammerjs": {
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
"dev": true,
"requires": {
"@types/hammerjs": "^2.0.36"
}
},
"@types/hammerjs": {
"version": "2.0.38",
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.38.tgz",
"integrity": "sha512-wuwDzWW1JWh3BZoRftBlKcctjNzR75QFY4/b4zAz7sH1EesA8HBJzke+bF5dxCATNdHHs3X1P5UWanbbUT6chw==",
"dev": true
},
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -11,9 +26,9 @@
"dev": true
},
"ajv": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -295,9 +310,9 @@
"dev": true
},
"aws4": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
"dev": true
},
"bach": {
@@ -1503,6 +1518,12 @@
"safer-buffer": "^2.1.0"
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -1743,9 +1764,9 @@
}
},
"fast-deep-equal": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
@@ -2054,13 +2075,13 @@
}
},
"globule": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
"integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz",
"integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==",
"dev": true,
"requires": {
"glob": "~7.1.1",
"lodash": "~4.17.12",
"lodash": "~4.17.10",
"minimatch": "~3.0.2"
}
},
@@ -2154,13 +2175,13 @@
}
},
"gulp-sass": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.0.2.tgz",
"integrity": "sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.1.0.tgz",
"integrity": "sha512-xIiwp9nkBLcJDpmYHbEHdoWZv+j+WtYaKD6Zil/67F3nrAaZtWYN5mDwerdo7EvcdBenSAj7Xb2hx2DqURLGdA==",
"dev": true,
"requires": {
"chalk": "^2.3.0",
"lodash.clonedeep": "^4.3.2",
"lodash": "^4.17.11",
"node-sass": "^4.8.3",
"plugin-error": "^1.0.1",
"replace-ext": "^1.0.0",
@@ -2220,12 +2241,12 @@
"dev": true
},
"har-validator": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"dev": true,
"requires": {
"ajv": "^6.5.5",
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
@@ -2355,9 +2376,9 @@
"dev": true
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true
},
"interpret": {
@@ -2600,9 +2621,9 @@
"dev": true
},
"js-base64": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
"integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==",
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
"dev": true
},
"jsbn": {
@@ -2653,6 +2674,12 @@
"integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
"dev": true
},
"keycharm": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.3.1.tgz",
"integrity": "sha512-zn47Ti4FJT9zdF+YBBLWJsfKF/fYQHkrYlBeB5Ez5e2PjW7SoIxr43yehAne2HruulIoid4NKZZxO0dHBygCtQ==",
"dev": true
},
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -2725,16 +2752,28 @@
"strip-bom": "^2.0.0"
}
},
"lodash": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
},
"dependencies": {
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
"dev": true
}
}
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"loud-rejection": {
@@ -2877,18 +2916,18 @@
}
},
"mime-db": {
"version": "1.43.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
"integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
"version": "1.45.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
"dev": true
},
"mime-types": {
"version": "2.1.26",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
"integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
"version": "2.1.28",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
"dev": true,
"requires": {
"mime-db": "1.43.0"
"mime-db": "1.45.0"
}
},
"minimatch": {
@@ -2936,6 +2975,12 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"dev": true
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -3008,9 +3053,9 @@
}
},
"node-sass": {
"version": "4.13.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz",
"integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==",
"version": "4.14.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz",
"integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
"dev": true,
"requires": {
"async-foreach": "^0.1.3",
@@ -3027,7 +3072,7 @@
"node-gyp": "^3.8.0",
"npmlog": "^4.0.0",
"request": "^2.88.0",
"sass-graph": "^2.2.4",
"sass-graph": "2.2.5",
"stdout-stream": "^1.4.0",
"true-case-path": "^1.0.2"
},
@@ -3276,6 +3321,30 @@
"os-tmpdir": "^1.0.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"parse-filepath": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
@@ -3636,6 +3705,14 @@
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
},
"dependencies": {
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"dev": true
}
}
},
"require-directory": {
@@ -3721,15 +3798,138 @@
"dev": true
},
"sass-graph": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
"integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz",
"integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==",
"dev": true,
"requires": {
"glob": "^7.0.0",
"lodash": "^4.0.0",
"scss-tokenizer": "^0.2.3",
"yargs": "^7.0.0"
"yargs": "^13.3.2"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"requires": {
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
},
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
"dev": true
},
"wrap-ansi": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
"strip-ansi": "^5.0.0"
}
},
"y18n": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
"dev": true
},
"yargs": {
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"requires": {
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.1.2"
}
},
"yargs-parser": {
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
"scss-tokenizer": {
@@ -4150,6 +4350,12 @@
"integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
"dev": true
},
"timsort": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true
},
"to-absolute-glob": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
@@ -4370,9 +4576,9 @@
"dev": true
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
@@ -4397,9 +4603,9 @@
"dev": true
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.0.tgz",
"integrity": "sha512-LNUrNsXdI/fUsypJbWM8Jt4DgQdFAZh41p9C7WE9Cn+CULOEkoG2lgQyH68v3wnIy5K3fN4jdSt270K6IFA3MQ==",
"dev": true
},
"v8flags": {
@@ -4501,10 +4707,22 @@
"source-map": "^0.5.1"
}
},
"vis-data": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/vis-data/-/vis-data-6.6.1.tgz",
"integrity": "sha512-xmujDB2Dzf8T04rGFJ9OP4OA6zRVrz8R9hb0CVKryBrZRCljCga9JjSfgctA8S7wdZu7otDtUIwX4ZOgfV/57w==",
"dev": true
},
"vis-network": {
"version": "7.10.0",
"resolved": "https://registry.npmjs.org/vis-network/-/vis-network-7.10.0.tgz",
"integrity": "sha512-SYQ3y+cGqcFpPfaQbpGBXsaQjjbQq5xjt5dVztCD6x5ETQHlAYaFiYiWnVo0qoVI9lspfwoCfp4wOhW+rvId6Q==",
"version": "7.10.2",
"resolved": "https://registry.npmjs.org/vis-network/-/vis-network-7.10.2.tgz",
"integrity": "sha512-KDx2agbDnaiE0Bye4AcCRqTn5mxzDKhdUNpKkzSn0AOLBmdhNtPGjxAFluAmvFVyiSK5R6Q5KIWdLjeIMu/PAQ==",
"dev": true
},
"vis-util": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/vis-util/-/vis-util-4.3.4.tgz",
"integrity": "sha512-hJIZNrwf4ML7FYjs+m+zjJfaNvhjk3/1hbMdQZVnwwpOFJS/8dMG8rdbOHXcKoIEM6U5VOh3HNpaDXxGkOZGpw==",
"dev": true
},
"which": {
@@ -4554,9 +4772,9 @@
"dev": true
},
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
"dev": true
},
"yallist": {
+6 -8
View File
@@ -1,28 +1,26 @@
{
"private": true,
"name": "netbox_topology_views",
"version": "0.4.9",
"version": "0.5.1",
"scripts": {
"resources": "gulp build",
"resources_dev": "gulp build_dev"
},
"dependencies": {},
"devDependencies": {
"@egjs/hammerjs": "^2.0.0",
"gulp": "^4.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-sass": "^4.1.0",
"gulp-uglify": "^3.0.2",
"vis-network": "^7.10.0",
"keycharm": "^0.3.0",
"moment": "^2.24.0",
"timsort": "^0.3.0",
"vis-data": "^6.2.1",
"vis-util": "^4.0.0",
"uuid": "7.0.0",
"@egjs/hammerjs" : "^2.0.0"
"vis-data": "^6.2.1",
"vis-network": "^7.10.2",
"vis-util": "^4.0.0"
},
"peerDependencies": {
}
"peerDependencies": {}
}
+1 -1
View File
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
setup(
name='netbox-topology-views',
version='0.4.9',
version='0.5.1',
description='An NetBox plugin to create Topology maps',
url='https://github.com/mattieserver/netbox-topology-views',
author='Mattijs Vanhaverbeke',