Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Yates committed Apr 4, 2022
1 parent 55da2fc commit 98b7880
Show file tree
Hide file tree
Showing 30 changed files with 1,289 additions and 0 deletions.
107 changes: 107 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/

# MacOS FS
.DS_Store
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include README.md
include LICENSE
recursive-include netbox_documents/templates *
Binary file added docs/img/addcircuit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/devicedocuments.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/sitedocuments.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/siteview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions netbox_documents/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from extras.plugins import PluginConfig

class NetboxDocuments(PluginConfig):
name = 'netbox_documents'
verbose_name = 'Document Storage'
description = 'Manage site, circuit and device diagrams and documents in Netbox'
version = '0.2'
base_url = 'documents'
default_settings = {
"enable_site_documents": True,
"enable_circuit_documents": True,
"enable_device_documents": True,
"enable_navigation_menu": True,
"site_documents_location": "left",
"circuit_documents_location": "left",
"device_documents_location": "left",
}

config = NetboxDocuments
Empty file.
51 changes: 51 additions & 0 deletions netbox_documents/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from rest_framework import serializers

from netbox.api.serializers import NetBoxModelSerializer
from ..models import SiteDocument, DeviceDocument, CircuitDocument
from dcim.api.nested_serializers import NestedSiteSerializer, NestedDeviceSerializer
from circuits.api.nested_serializers import NestedCircuitSerializer

class SiteDocumentSerializer(NetBoxModelSerializer):

url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_documents-api:sitedocument-detail'
)

site = NestedSiteSerializer()

class Meta:
model = SiteDocument
fields = (
'id', 'url', 'display', 'name', 'document', 'document_type', 'filename', 'site', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
)

class DeviceDocumentSerializer(NetBoxModelSerializer):

url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_documents-api:devicedocument-detail'
)

device = NestedDeviceSerializer()

class Meta:
model = DeviceDocument
fields = (
'id', 'url', 'display', 'name', 'document', 'document_type', 'filename', 'device', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
)

class CircuitDocumentSerializer(NetBoxModelSerializer):

url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_documents-api:circuitdocument-detail'
)

circuit = NestedCircuitSerializer()

class Meta:
model = CircuitDocument
fields = (
'id', 'url', 'display', 'name', 'document', 'document_type', 'filename', 'circuit', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
)
11 changes: 11 additions & 0 deletions netbox_documents/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from netbox.api.routers import NetBoxRouter
from . import views

app_name = 'netbox_documents'

router = NetBoxRouter()
router.register('site-documents', views.SiteDocumentViewSet)
router.register('device-documents', views.DeviceDocumentViewSet)
router.register('circuit-documents', views.CircuitDocumentViewSet)

urlpatterns = router.urls
16 changes: 16 additions & 0 deletions netbox_documents/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from netbox.api.viewsets import NetBoxModelViewSet

from .. import models
from .serializers import SiteDocumentSerializer, DeviceDocumentSerializer, CircuitDocumentSerializer

class SiteDocumentViewSet(NetBoxModelViewSet):
queryset = models.SiteDocument.objects.prefetch_related('tags')
serializer_class = SiteDocumentSerializer

class DeviceDocumentViewSet(NetBoxModelViewSet):
queryset = models.DeviceDocument.objects.prefetch_related('tags')
serializer_class = DeviceDocumentSerializer

class CircuitDocumentViewSet(NetBoxModelViewSet):
queryset = models.CircuitDocument.objects.prefetch_related('tags')
serializer_class = CircuitDocumentSerializer
45 changes: 45 additions & 0 deletions netbox_documents/filtersets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from netbox.filtersets import NetBoxModelFilterSet
from .models import SiteDocument, DeviceDocument, CircuitDocument
from django.db.models import Q

class SiteDocumentFilterSet(NetBoxModelFilterSet):

class Meta:
model = SiteDocument
fields = ('id', 'name', 'document_type', 'site')

def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(document__icontains=value)
)

class DeviceDocumentFilterSet(NetBoxModelFilterSet):

class Meta:
model = DeviceDocument
fields = ('id', 'name', 'document_type', 'device')

def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(document__icontains=value)
)

class CircuitDocumentFilterSet(NetBoxModelFilterSet):

class Meta:
model = CircuitDocument
fields = ('id', 'name', 'document_type', 'circuit')

def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(document__icontains=value)
)
102 changes: 102 additions & 0 deletions netbox_documents/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from django import forms
from netbox.forms import NetBoxModelForm, NetBoxModelFilterSetForm
from dcim.models import Site, Device
from circuits.models import Circuit
from utilities.forms import TagFilterField, CommentField, DynamicModelChoiceField
from .models import SiteDocument, DeviceDocument, CircuitDocument, DocTypeChoices


#### Site Document Form & Filter Form
class SiteDocumentForm(NetBoxModelForm):
comments = CommentField()

site = DynamicModelChoiceField(
queryset=Site.objects.all()
)

class Meta:
model = SiteDocument
fields = ('name', 'document', 'document_type', 'site', 'comments', 'tags')

class SiteDocumentFilterForm(NetBoxModelFilterSetForm):
model = SiteDocument

name = forms.CharField(
required=False
)

site = forms.ModelMultipleChoiceField(
queryset=Site.objects.all(),
required=False
)

document_type = forms.MultipleChoiceField(
choices=DocTypeChoices,
required=False
)

tag = TagFilterField(model)


#### Device Document Form & Filter Form
class DeviceDocumentForm(NetBoxModelForm):
comments = CommentField()

device = DynamicModelChoiceField(
queryset=Device.objects.all()
)

class Meta:
model = DeviceDocument
fields = ('name', 'document', 'document_type', 'device', 'comments', 'tags')

class DeviceDocumentFilterForm(NetBoxModelFilterSetForm):
model = DeviceDocument

name = forms.CharField(
required=False
)

device = forms.ModelMultipleChoiceField(
queryset=Device.objects.all(),
required=False
)

document_type = forms.MultipleChoiceField(
choices=DocTypeChoices,
required=False
)

tag = TagFilterField(model)


#### Circuit Document Form & Filter Form
class CircuitDocumentForm(NetBoxModelForm):
comments = CommentField()

circuit = DynamicModelChoiceField(
queryset=Circuit.objects.all()
)

class Meta:
model = CircuitDocument
fields = ('name', 'document', 'document_type', 'circuit', 'comments', 'tags')

class CircuitDocumentFilterForm(NetBoxModelFilterSetForm):
model = CircuitDocument

name = forms.CharField(
required=False
)

circuit = forms.ModelMultipleChoiceField(
queryset=Circuit.objects.all(),
required=False
)

document_type = forms.MultipleChoiceField(
choices=DocTypeChoices,
required=False
)

tag = TagFilterField(model)
Loading

0 comments on commit 98b7880

Please sign in to comment.