Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce39c98396 | ||
|
|
faf156a6b2 | ||
|
|
1b36b9e7df | ||
|
|
652a44437e | ||
|
|
76141e70ce | ||
|
|
76b4f6ac9a | ||
|
|
953d7480af | ||
|
|
f323278f00 | ||
|
|
56a6f22bf6 |
@@ -0,0 +1,93 @@
|
|||||||
|
name: Docker
|
||||||
|
|
||||||
|
# This workflow uses actions that are not certified by GitHub.
|
||||||
|
# They are provided by a third-party and are governed by
|
||||||
|
# separate terms of service, privacy policy, and support
|
||||||
|
# documentation.
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '35 10 * * *'
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
# Publish semver tags as releases.
|
||||||
|
tags: [ 'v*.*.*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Use docker.io for Docker Hub if empty
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
# github.repository as <account>/<repo>
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
# This is used to complete the identity challenge
|
||||||
|
# with sigstore/fulcio when running outside of PRs.
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Install the cosign tool except on PR
|
||||||
|
# https://github.com/sigstore/cosign-installer
|
||||||
|
- name: Install cosign
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: sigstore/cosign-installer@7e0881f8fe90b25e305bbf0309761e9314607e25
|
||||||
|
with:
|
||||||
|
cosign-release: 'v1.9.0'
|
||||||
|
|
||||||
|
|
||||||
|
# Workaround: https://github.com/docker/build-push-action/issues/461
|
||||||
|
- name: Setup Docker buildx
|
||||||
|
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
|
||||||
|
|
||||||
|
# Login against a Docker registry except on PR
|
||||||
|
# https://github.com/docker/login-action
|
||||||
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# Extract metadata (tags, labels) for Docker
|
||||||
|
# https://github.com/docker/metadata-action
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
|
# Build and push Docker image with Buildx (don't push on PR)
|
||||||
|
# https://github.com/docker/build-push-action
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
# Sign the resulting Docker image digest except on PRs.
|
||||||
|
# This will only write to the public Rekor transparency log when the Docker
|
||||||
|
# repository is public to avoid leaking data. If you would like to publish
|
||||||
|
# transparency data even for private images, pass --force to cosign below.
|
||||||
|
# https://github.com/sigstore/cosign
|
||||||
|
- name: Sign the published Docker image
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
env:
|
||||||
|
COSIGN_EXPERIMENTAL: "true"
|
||||||
|
# This step uses the identity token to provision an ephemeral certificate
|
||||||
|
# against the sigstore community Fulcio instance.
|
||||||
|
run: cosign sign ${{ steps.meta.outputs.tags }}@${{ steps.build-and-push.outputs.digest }}
|
||||||
@@ -5,7 +5,7 @@ name: Upload Python Package
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [published]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
@@ -13,19 +13,19 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v3
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install setuptools wheel twine
|
pip install build
|
||||||
- name: Build and publish
|
- name: Build package
|
||||||
env:
|
run: python -m build
|
||||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
- name: Publish package
|
||||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
|
||||||
run: |
|
with:
|
||||||
python setup.py sdist bdist_wheel
|
user: __token__
|
||||||
twine upload dist/*
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
FROM netboxcommunity/netbox:latest
|
||||||
|
|
||||||
|
COPY ./docker/plugin_requirements.txt /
|
||||||
|
RUN /opt/netbox/venv/bin/pip install --no-warn-script-location -r /plugin_requirements.txt
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| > 2.0 | :white_check_mark: |
|
||||||
|
| < 2.0 | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Please create an issue when you encounter a Security issue.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
netbox-topology-views
|
||||||
@@ -4,7 +4,7 @@ class TopologyViewsConfig(PluginConfig):
|
|||||||
name = 'netbox_topology_views'
|
name = 'netbox_topology_views'
|
||||||
verbose_name = 'Topology views'
|
verbose_name = 'Topology views'
|
||||||
description = 'An plugin to render topology maps'
|
description = 'An plugin to render topology maps'
|
||||||
version = '2.0.0'
|
version = '2.0.2'
|
||||||
author = 'Mattijs Vanhaverbeke'
|
author = 'Mattijs Vanhaverbeke'
|
||||||
author_email = 'author@example.com'
|
author_email = 'author@example.com'
|
||||||
base_url = 'netbox_topology_views'
|
base_url = 'netbox_topology_views'
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
var graph=null,container=null,downloadButton=null,MIME_TYPE="image/png",canvas=null,csrftoken=null,nodes=new vis.DataSet,edges=new vis.DataSet,options={interaction:{hover:!0,hoverConnectedEdges:!0,multiselect:!1},nodes:{shape:"image",brokenImage:"../../static/netbox_topology_views/img/role-unknown.png",size:35,font:{multi:"md",face:"helvetica"}},edges:{length:100,width:2,font:{face:"helvetica"},shadow:{enabled:!0}},physics:{solver:"forceAtlas2Based"}},selected_regions=[],selected_sites=[],coord_save_checkbox=null,htmlElement=null;function getCookie(e){var t=null;if(document.cookie&&""!==document.cookie)for(var o=document.cookie.split(";"),n=0;n<o.length;n++){var d=o[n].trim();if(d.substring(0,e.length+1)===e+"="){t=decodeURIComponent(d.substring(e.length+1));break}}return t}function htmlTitle(e){return(container=document.createElement("div")).innerHTML=e,container}function addEdge(e){e.title=htmlTitle(e.title),edges.add(e)}function addNode(e){e.title=htmlTitle(e.title),nodes.add(e)}function iniPlotboxIndex(){document.addEventListener("DOMContentLoaded",function(){csrftoken=getCookie("csrftoken"),container=document.getElementById("visgraph"),htmlElement=document.getElementsByTagName("html")[0],downloadButton=document.getElementById("btnDownloadImage"),handleLoadData(),btnFullView=document.getElementById("btnFullView"),coord_save_checkbox=document.getElementById("id_save_coords")},!1)}function performGraphDownload(){var e=document.createElement("a"),t=canvas.toDataURL(MIME_TYPE);e.href=t,e.download="topology",document.body.appendChild(e),e.click(),document.body.removeChild(e)}function handleLoadData(){null!==topology_data&&("dark"==htmlElement.dataset.netboxColorMode&&(options.nodes.font.color="#fff"),graph=null,nodes=new vis.DataSet,edges=new vis.DataSet,graph=new vis.Network(container,{nodes:nodes,edges:edges},options),topology_data.edges.forEach(addEdge),topology_data.nodes.forEach(addNode),graph.fit(),canvas=document.getElementById("visgraph").getElementsByTagName("canvas")[0],downloadButton.onclick=function(e){return performGraphDownload(),!1},graph.on("dragEnd",function(e){if(dragged=this.getPositions(e.nodes),coord_save_checkbox.checked&&0!==Object.keys(dragged).length)for(dragged_device in dragged){var t=dragged_device,o=new XMLHttpRequest;o.open("PATCH","/api/plugins/netbox_topology_views/save-coords/save_coords/"),o.setRequestHeader("X-CSRFToken",csrftoken),o.setRequestHeader("Accept","application/json"),o.setRequestHeader("Content-Type","application/json"),o.onreadystatechange=function(){4===o.readyState&&(console.log(o.status),console.log(o.responseText))};var n=JSON.stringify({node_id:t,x:dragged[t].x,y:dragged[t].y});o.send(n)}}))}
|
var graph=null,container=null,downloadButton=null,MIME_TYPE="image/png",canvas=null,csrftoken=null,nodes=new vis.DataSet,edges=new vis.DataSet,options={interaction:{hover:!0,hoverConnectedEdges:!0,multiselect:!1},nodes:{shape:"image",brokenImage:"../../static/netbox_topology_views/img/role-unknown.png",size:35,font:{multi:"md",face:"helvetica"}},edges:{length:100,width:2,font:{face:"helvetica"},shadow:{enabled:!0}},physics:{solver:"forceAtlas2Based"}},selected_regions=[],selected_sites=[],coord_save_checkbox=null,htmlElement=null;function getCookie(e){var o=null;if(document.cookie&&""!==document.cookie)for(var t=document.cookie.split(";"),n=0;n<t.length;n++){var d=t[n].trim();if(d.substring(0,e.length+1)===e+"="){o=decodeURIComponent(d.substring(e.length+1));break}}return o}function htmlTitle(e){return(container=document.createElement("div")).innerHTML=e,container}function addEdge(e){e.title=htmlTitle(e.title),edges.add(e)}function addNode(e){e.title=htmlTitle(e.title),nodes.add(e)}function iniPlotboxIndex(){document.addEventListener("DOMContentLoaded",function(){csrftoken=getCookie("csrftoken"),container=document.getElementById("visgraph"),htmlElement=document.getElementsByTagName("html")[0],downloadButton=document.getElementById("btnDownloadImage"),handleLoadData(),btnFullView=document.getElementById("btnFullView"),coord_save_checkbox=document.getElementById("id_save_coords")},!1)}function performGraphDownload(){var e=document.createElement("a"),o=canvas.toDataURL(MIME_TYPE);e.href=o,e.download="topology",document.body.appendChild(e),e.click(),document.body.removeChild(e)}function handleLoadData(){null!==topology_data&&("dark"==htmlElement.dataset.netboxColorMode&&(options.nodes.font.color="#fff"),graph=null,nodes=new vis.DataSet,edges=new vis.DataSet,graph=new vis.Network(container,{nodes:nodes,edges:edges},options),topology_data.edges.forEach(addEdge),topology_data.nodes.forEach(addNode),graph.fit(),canvas=document.getElementById("visgraph").getElementsByTagName("canvas")[0],downloadButton.onclick=function(e){return performGraphDownload(),!1},graph.on("dragEnd",function(e){if(dragged=this.getPositions(e.nodes),coord_save_checkbox.checked&&0!==Object.keys(dragged).length)for(dragged_device in dragged){var o=dragged_device,t=new XMLHttpRequest;t.open("PATCH","/api/plugins/netbox_topology_views/save-coords/save_coords/"),t.setRequestHeader("X-CSRFToken",csrftoken),t.setRequestHeader("Accept","application/json"),t.setRequestHeader("Content-Type","application/json"),t.onreadystatechange=function(){4===t.readyState&&(console.log(t.status),console.log(t.responseText))};var n=JSON.stringify({node_id:o,x:dragged[o].x,y:dragged[o].y});t.send(n)}}),graph.on("doubleClick",function(e){for(selected_device in console.log(e.nodes),selected_devices=e.nodes,selected_devices)console.log(selected_device),console.log(selected_devices[selected_device]),url="/dcim/devices/"+selected_devices[selected_device]+"/",console.log(url),window.open(url,"_blank")}))}
|
||||||
@@ -147,5 +147,15 @@ function handleLoadData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
graph.on("doubleClick", function (params) {
|
||||||
|
console.log(params.nodes);
|
||||||
|
selected_devices = params.nodes;
|
||||||
|
for (selected_device in selected_devices) {
|
||||||
|
url = "/dcim/devices/" + selected_devices[selected_device] + "/";
|
||||||
|
window.open(url, "_blank");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,17 @@ def create_node(device):
|
|||||||
node_content += "<tr><th>Serial: </th><td>" + device.serial + "</td></tr>"
|
node_content += "<tr><th>Serial: </th><td>" + device.serial + "</td></tr>"
|
||||||
if device.primary_ip is not None:
|
if device.primary_ip is not None:
|
||||||
node_content += "<tr><th>IP Address: </th><td>" + str(device.primary_ip.address) + "</td></tr>"
|
node_content += "<tr><th>IP Address: </th><td>" + str(device.primary_ip.address) + "</td></tr>"
|
||||||
|
if device.site is not None:
|
||||||
|
node_content += "<tr><th>Site: </th><td>" + device.site.name + "</td></tr>"
|
||||||
|
if device.location is not None:
|
||||||
|
node_content += "<tr><th>Location: </th><td>" + device.location.name + "</td></tr>"
|
||||||
|
if device.rack is not None:
|
||||||
|
node_content += "<tr><th>Rack: </th><td>" + device.rack.name + "</td></tr>"
|
||||||
|
if device.position is not None:
|
||||||
|
if device.face is not None:
|
||||||
|
node_content += "<tr><th>Position: </th><td> {} ({}) </td></tr>".format(device.position, device.face)
|
||||||
|
else:
|
||||||
|
node_content += "<tr><th>Position: </th><td>" + device.position + "</td></tr>"
|
||||||
|
|
||||||
dev_title = "<table> %s </table>" % (node_content)
|
dev_title = "<table> %s </table>" % (node_content)
|
||||||
|
|
||||||
@@ -125,6 +136,11 @@ def get_topology_data(queryset, hide_unconnected, intermediate_dev_role_ids, end
|
|||||||
if path_destination is not None and path_destination.provider_network is None:
|
if path_destination is not None and path_destination.provider_network is None:
|
||||||
# ProviderNetwork not supported at the moment
|
# ProviderNetwork not supported at the moment
|
||||||
# $path_destination.cable would be none : there is no cable between a CircuitTermination and ProviderNetwork
|
# $path_destination.cable would be none : there is no cable between a CircuitTermination and ProviderNetwork
|
||||||
|
|
||||||
|
if not hasattr(link.termination_b, 'device'):
|
||||||
|
#CircuitTermination B Missing Device
|
||||||
|
continue
|
||||||
|
|
||||||
origin_device = link.termination_b.device
|
origin_device = link.termination_b.device
|
||||||
destination_device = path_destination.cable.termination_b.device
|
destination_device = path_destination.cable.termination_b.device
|
||||||
|
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "netbox_topology_views",
|
"name": "netbox_topology_views",
|
||||||
"version": "2.0.0",
|
"version": "2.0.2",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "netbox_topology_views",
|
"name": "netbox_topology_views",
|
||||||
"version": "2.0.0",
|
"version": "2.0.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"resources": "gulp build",
|
"resources": "gulp build",
|
||||||
"resources_dev": "gulp build_dev"
|
"resources_dev": "gulp build_dev"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='netbox-topology-views',
|
name='netbox-topology-views',
|
||||||
version='2.0.0',
|
version='2.0.2',
|
||||||
description='An NetBox plugin to create Topology maps',
|
description='An NetBox plugin to create Topology maps',
|
||||||
url='https://github.com/mattieserver/netbox-topology-views',
|
url='https://github.com/mattieserver/netbox-topology-views',
|
||||||
author='Mattijs Vanhaverbeke',
|
author='Mattijs Vanhaverbeke',
|
||||||
|
|||||||
Reference in New Issue
Block a user