Large overhaul of naming conventions and code clean ups
This commit is contained in:
+6
-3
@@ -6,11 +6,14 @@ Software Lifecycle Management
|
||||
|
||||
--------------
|
||||
|
||||
Known Issues
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
- WARNING: This plugin is only tested with Netbox 3.2 at this time.
|
||||
- CSV/Bulk imports for SoftwareProduct, Version and Installation are currently broken (WIP)
|
||||
|
||||
Installation Guide
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
WARNING: This plugin is only tested with Netbox 3.2 at this time.
|
||||
|
||||
When using the Docker version of Netbox, first follow the `netbox-docker
|
||||
quickstart <https://github.com/netbox-community/netbox-docker#quickstart>`__
|
||||
instructions to clone the netbox-docker repo and set up the
|
||||
@@ -22,7 +25,7 @@ to install the Netbox SLM plugin:
|
||||
|
||||
1. Add ``netbox_slm`` to the ``PLUGINS`` list in
|
||||
``configuration/extra.py``.
|
||||
2. Create a ``plugin_requirements.txt`` with ``netbox-slm==0.98`` as
|
||||
2. Create a ``plugin_requirements.txt`` with ``netbox-slm==0.99`` as
|
||||
contents.
|
||||
3. Create a ``Dockerfile-SLM`` with contents:
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Security Policy
|
||||
|
||||
## Current status
|
||||
|
||||
Netbox SLM is a plugin for Netbox with mostly default configuration. We advise to monitor Netbox security findings and update accordingly.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Only the latest version of Netbox SLM is currently being supported with security updates. We aim to keep the plugin compatible with the latest Netbox version, but have no incentive to patch older tags at this point.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report security vulnerabilities by opening a ticket. The aim is to get back to you within 24 hours with a confirmation of the issue and a brief action plan or a request for more information.
|
||||
@@ -5,7 +5,7 @@ class SLMConfig(PluginConfig):
|
||||
name = 'netbox_slm'
|
||||
verbose_name = 'Software Lifecycle Management'
|
||||
description = 'Software Lifecycle Management'
|
||||
version = '0.98'
|
||||
version = '0.99'
|
||||
author = 'Hedde van der Heide'
|
||||
author_email = 'hedde.vanderheide@ictu.nl'
|
||||
base_url = 'slm'
|
||||
@@ -14,4 +14,4 @@ class SLMConfig(PluginConfig):
|
||||
'version_info': False
|
||||
}
|
||||
|
||||
config = SLMConfig
|
||||
config = SLMConfig
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
from rest_framework import serializers
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from netbox_slm.api.serializers import (
|
||||
SoftwareProductSerializer, SoftwareProductVersionSerializer, SoftwareProductInstallationSerializer,
|
||||
)
|
||||
from netbox_slm.filters import (
|
||||
SoftwareProductFilter, SoftwareProductVersionFilter, SoftwareProductInstallationFilter,
|
||||
from netbox_slm.filtersets import (
|
||||
SoftwareProductFilterSet, SoftwareProductVersionFilterSet, SoftwareProductInstallationFilterSet,
|
||||
)
|
||||
from netbox_slm.models import (
|
||||
SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation,
|
||||
@@ -27,16 +24,16 @@ class NetboxSLMRootView(APIRootView):
|
||||
class SoftwareProductViewSet(NetBoxModelViewSet):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
serializer_class = SoftwareProductSerializer
|
||||
filterset_class = SoftwareProductFilter
|
||||
filterset_class = SoftwareProductFilterSet
|
||||
|
||||
|
||||
class SoftwareProductVersionViewSet(NetBoxModelViewSet):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
serializer_class = SoftwareProductVersionSerializer
|
||||
filterset_class = SoftwareProductVersionFilter
|
||||
filterset_class = SoftwareProductVersionFilterSet
|
||||
|
||||
|
||||
class SoftwareProductInstallationViewSet(NetBoxModelViewSet):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
serializer_class = SoftwareProductInstallationSerializer
|
||||
filterset_class = SoftwareProductInstallationFilter
|
||||
filterset_class = SoftwareProductInstallationFilterSet
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
from django.forms import BoundField
|
||||
from django.urls import reverse
|
||||
|
||||
from utilities.forms import DynamicModelMultipleChoiceField
|
||||
|
||||
|
||||
class CustomDynamicModelMultipleChoiceField(DynamicModelMultipleChoiceField):
|
||||
def get_bound_field(self, form, field_name):
|
||||
bound_field = BoundField(form, self, field_name)
|
||||
|
||||
# Set initial value based on prescribed child fields (if not already set)
|
||||
if not self.initial and self.initial_params:
|
||||
filter_kwargs = {}
|
||||
for kwarg, child_field in self.initial_params.items():
|
||||
value = form.initial.get(child_field.lstrip("$"))
|
||||
if value:
|
||||
filter_kwargs[kwarg] = value
|
||||
if filter_kwargs:
|
||||
self.initial = self.queryset.filter(**filter_kwargs).first()
|
||||
|
||||
# Modify the QuerySet of the field before we return it. Limit choices to any data already bound: Options
|
||||
# will be populated on-demand via the APISelect widget.
|
||||
data = bound_field.value()
|
||||
|
||||
if data:
|
||||
field_name = getattr(self, "to_field_name") or "pk"
|
||||
filter = self.filter(field_name=field_name)
|
||||
try:
|
||||
self.queryset = filter.filter(self.queryset, data)
|
||||
except (TypeError, ValueError):
|
||||
# Catch any error caused by invalid initial data passed from the user
|
||||
self.queryset = self.queryset.none()
|
||||
else:
|
||||
self.queryset = self.queryset.none()
|
||||
|
||||
# Set the data URL on the APISelect widget (if not already set)
|
||||
widget = bound_field.field.widget
|
||||
if not widget.attrs.get("data-url"):
|
||||
app_label = self.queryset.model._meta.app_label
|
||||
model_name = self.queryset.model._meta.model_name
|
||||
|
||||
#
|
||||
# Custom url for work with plugin api
|
||||
#
|
||||
data_url = reverse(
|
||||
"plugins-api:{}-api:{}-list".format(app_label, model_name)
|
||||
)
|
||||
widget.attrs["data-url"] = data_url
|
||||
|
||||
return bound_field
|
||||
@@ -1,75 +0,0 @@
|
||||
import django_filters
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import gettext as _
|
||||
from extras.filters import TagFilter
|
||||
from netbox.filtersets import NetBoxModelFilterSet
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from utilities.forms import DynamicModelMultipleChoiceField
|
||||
|
||||
|
||||
class BaseFilter(NetBoxModelFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method="search",
|
||||
label="Search",
|
||||
)
|
||||
|
||||
|
||||
class SoftwareProductFilter(BaseFilter):
|
||||
"""Filter capabilities for SoftwareProduct instances."""
|
||||
|
||||
name = django_filters.CharFilter(
|
||||
lookup_expr="icontains",
|
||||
)
|
||||
# tag = TagFilter()
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = ("name",) # "tag")
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(name__icontains=value) # | Q(status__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareProductVersionFilter(BaseFilter):
|
||||
name = django_filters.CharFilter(
|
||||
lookup_expr="icontains", label="Version"
|
||||
)
|
||||
# software_product_id = django_filters.ModelMultipleChoiceFilter(
|
||||
# queryset=SoftwareProduct.objects.all(),
|
||||
# label='SoftwareProduct (ID)',
|
||||
# )
|
||||
# software_product = django_filters.ModelMultipleChoiceFilter(
|
||||
# field_name='software_product__name',
|
||||
# queryset=SoftwareProduct.objects.all(),
|
||||
# to_field_name='name',
|
||||
# label='SoftwareProduct (name)',
|
||||
# )
|
||||
# tag = TagFilter()
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = ("name", "software_product") # "tag")
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(name__icontains=value) # | Q(status__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareProductInstallationFilter(BaseFilter):
|
||||
class Meta:
|
||||
model = SoftwareProductInstallation
|
||||
fields = tuple() # "tag")
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(software_product__name__icontains=value) | Q(version__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
@@ -0,0 +1,23 @@
|
||||
from netbox.filtersets import NetBoxModelFilterSet
|
||||
from netbox_slm.models import *
|
||||
|
||||
|
||||
class SoftwareProductFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareProduct instances."""
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = tuple()
|
||||
|
||||
|
||||
class SoftwareProductVersionFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareProductVersion instances."""
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = tuple()
|
||||
|
||||
|
||||
class SoftwareProductInstallationFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareProductInstallation instances."""
|
||||
class Meta:
|
||||
model = SoftwareProductInstallation
|
||||
fields = tuple()
|
||||
+48
-39
@@ -1,16 +1,18 @@
|
||||
from django import forms
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from dcim.models import Manufacturer, Device
|
||||
from netbox.forms import (
|
||||
NetBoxModelForm,
|
||||
NetBoxModelCSVForm,
|
||||
NetBoxModelBulkEditForm,
|
||||
NetBoxModelFilterSetForm,
|
||||
)
|
||||
from dcim.models import Manufacturer, Device
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from utilities.forms import (
|
||||
BootstrapMixin, DynamicModelChoiceField, APISelect, DynamicModelMultipleChoiceField
|
||||
DynamicModelChoiceField, APISelect, TagFilterField
|
||||
)
|
||||
from virtualization.models import VirtualMachine
|
||||
|
||||
@@ -21,9 +23,6 @@ class SoftwareProductForm(NetBoxModelForm):
|
||||
manufacturer = DynamicModelChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=False,
|
||||
# initial_params={
|
||||
# 'device_types': 'device_type'
|
||||
# }
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -32,24 +31,26 @@ class SoftwareProductForm(NetBoxModelForm):
|
||||
|
||||
|
||||
class SoftwareProductFilterForm(NetBoxModelFilterSetForm):
|
||||
"""Form for filtering SoftwareProduct instances."""
|
||||
|
||||
model = SoftwareProduct
|
||||
|
||||
q = forms.CharField(required=False, label="Search")
|
||||
|
||||
name = forms.CharField(
|
||||
required=False,
|
||||
label="Name",
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
# tag = TagFilterField(SoftwareProduct)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(name__icontains=value) | \
|
||||
Q(manufacturer__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareProductCSVForm(NetBoxModelCSVForm):
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = ("name",)
|
||||
fields = ("name", "manufacturer",)
|
||||
|
||||
|
||||
class SoftwareProductBulkEditForm(NetBoxModelBulkEditForm):
|
||||
@@ -78,24 +79,23 @@ class SoftwareProductVersionForm(NetBoxModelForm):
|
||||
model = SoftwareProductVersion
|
||||
fields = ("name", "software_product", "tags")
|
||||
|
||||
# def clean(self):
|
||||
# import pdb;pdb.set_trace()
|
||||
# return super(SoftwareProductVersionForm, self).clean()
|
||||
|
||||
|
||||
class SoftwareProductVersionFilterForm(NetBoxModelFilterSetForm):
|
||||
"""Form for filtering SoftwareProductVersion instances."""
|
||||
|
||||
model = SoftwareProductVersion
|
||||
|
||||
q = forms.CharField(required=False, label="Search")
|
||||
|
||||
name = forms.CharField(
|
||||
required=False,
|
||||
label="Name",
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
# tag = TagFilterField(SoftwareProduct)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(name__icontains=value) | \
|
||||
Q(software_product__name__icontains=value) | \
|
||||
Q(software_product__manufacturer__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareProductVersionCSVForm(NetBoxModelCSVForm):
|
||||
@@ -121,16 +121,10 @@ class SoftwareProductInstallationForm(NetBoxModelForm):
|
||||
device = DynamicModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
required=False,
|
||||
# initial_params={
|
||||
# 'device_types': 'device_type'
|
||||
# }
|
||||
)
|
||||
virtualmachine = DynamicModelChoiceField(
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
required=False,
|
||||
# initial_params={
|
||||
# 'device_types': 'device_type'
|
||||
# }
|
||||
)
|
||||
software_product = DynamicModelChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
@@ -154,6 +148,14 @@ class SoftwareProductInstallationForm(NetBoxModelForm):
|
||||
model = SoftwareProductInstallation
|
||||
fields = ("device", "virtualmachine", "software_product", "version", "tags")
|
||||
|
||||
def clean_version(self):
|
||||
version = self.cleaned_data['version']
|
||||
software_product = self.cleaned_data['software_product']
|
||||
if version not in software_product.softwareproductversion_set.all():
|
||||
raise forms.ValidationError(_(f"Version `{version}` doesn't exist on {software_product}, make sure you've "
|
||||
f"selected a compatible version or first select the software product."))
|
||||
return version
|
||||
|
||||
def clean(self):
|
||||
if not any([self.cleaned_data['device'], self.cleaned_data['virtualmachine']]):
|
||||
raise forms.ValidationError(_("Installation requires atleast one virtualmachine or device destination."))
|
||||
@@ -161,13 +163,21 @@ class SoftwareProductInstallationForm(NetBoxModelForm):
|
||||
|
||||
|
||||
class SoftwareProductInstallationFilterForm(NetBoxModelFilterSetForm):
|
||||
"""Form for filtering SoftwareProductInstallation instances."""
|
||||
|
||||
model = SoftwareProductInstallation
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
q = forms.CharField(required=False, label="Search")
|
||||
tag = TagFilterField(model)
|
||||
|
||||
# tag = TagFilterField(SoftwareProduct)
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(software_product__name__icontains=value) | \
|
||||
Q(software_product__manufacturer__name__icontains=value) | \
|
||||
Q(version__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareProductInstallationCSVForm(NetBoxModelCSVForm):
|
||||
@@ -189,4 +199,3 @@ class SoftwareProductInstallationBulkEditForm(NetBoxModelBulkEditForm):
|
||||
fieldsets = (
|
||||
(None, ('software_product', 'version',)),
|
||||
)
|
||||
# nullable_fields = ('',)
|
||||
@@ -1,16 +1,12 @@
|
||||
from django.db import models
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils import safestring
|
||||
# from extras.utils import extras_features # todo this changed in netbox 3.1.X and higher, currently not used but checkout why
|
||||
|
||||
from netbox.models import NetBoxModel
|
||||
from utilities.querysets import RestrictedQuerySet
|
||||
|
||||
|
||||
# @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
|
||||
class SoftwareProduct(NetBoxModel):
|
||||
"""
|
||||
A SoftwareProduct represents ...
|
||||
"""
|
||||
name = models.CharField(max_length=128)
|
||||
description = models.CharField(max_length=255, null=True, blank=True)
|
||||
|
||||
@@ -36,7 +32,6 @@ class SoftwareProduct(NetBoxModel):
|
||||
)) if count else "0"
|
||||
|
||||
|
||||
# @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
|
||||
class SoftwareProductVersion(NetBoxModel):
|
||||
software_product = models.ForeignKey(
|
||||
to='netbox_slm.SoftwareProduct',
|
||||
@@ -60,7 +55,6 @@ class SoftwareProductVersion(NetBoxModel):
|
||||
)) if count else "0"
|
||||
|
||||
|
||||
# @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
|
||||
class SoftwareProductInstallation(NetBoxModel):
|
||||
device = models.ForeignKey(
|
||||
to='dcim.Device',
|
||||
@@ -71,8 +65,8 @@ class SoftwareProductInstallation(NetBoxModel):
|
||||
virtualmachine = models.ForeignKey(
|
||||
to='virtualization.VirtualMachine',
|
||||
on_delete=models.PROTECT,
|
||||
null = True,
|
||||
blank = True
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
software_product = models.ForeignKey(
|
||||
to='netbox_slm.SoftwareProduct',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from extras.plugins import PluginMenuButton, PluginMenuItem
|
||||
from utilities.choices import ButtonColorChoices
|
||||
|
||||
|
||||
menu_items = (
|
||||
PluginMenuItem(
|
||||
link='plugins:netbox_slm:softwareproduct_list',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from django.urls import path
|
||||
from netbox.views.generic import ObjectChangeLogView
|
||||
|
||||
from netbox_slm import views
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
+34
-45
@@ -1,25 +1,19 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm.filters import SoftwareProductFilter, SoftwareProductVersionFilter, SoftwareProductInstallationFilter
|
||||
from netbox_slm.forms import (
|
||||
SoftwareProductForm, SoftwareProductFilterForm, SoftwareProductCSVForm, SoftwareProductBulkEditForm,
|
||||
SoftwareProductVersionForm, SoftwareProductVersionFilterForm, SoftwareProductVersionCSVForm,
|
||||
SoftwareProductVersionBulkEditForm, SoftwareProductInstallationForm, SoftwareProductInstallationFilterForm,
|
||||
SoftwareProductInstallationCSVForm, SoftwareProductInstallationBulkEditForm
|
||||
)
|
||||
from netbox_slm import filtersets
|
||||
from netbox_slm import forms
|
||||
from netbox_slm import tables
|
||||
from netbox_slm.models import (
|
||||
SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
)
|
||||
from netbox_slm.tables import SoftwareProductTable, SoftwareProductVersionTable, SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProducts."""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
filterset = SoftwareProductFilter
|
||||
filterset_form = SoftwareProductFilterForm
|
||||
table = SoftwareProductTable
|
||||
# template_name = "netbox_slm/object_list.html"
|
||||
filterset = filtersets.SoftwareProductFilterSet
|
||||
filterset_form = forms.SoftwareProductFilterForm
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductView(generic.ObjectView):
|
||||
@@ -36,7 +30,7 @@ class SoftwareProductEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProduct instance."""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
form = SoftwareProductForm
|
||||
form = forms.SoftwareProductForm
|
||||
|
||||
|
||||
class SoftwareProductDeleteView(generic.ObjectDeleteView):
|
||||
@@ -47,30 +41,30 @@ class SoftwareProductDeleteView(generic.ObjectDeleteView):
|
||||
|
||||
class SoftwareProductBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
model_form = SoftwareProductCSVForm
|
||||
table = SoftwareProductTable
|
||||
model_form = forms.SoftwareProductCSVForm
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
filterset = SoftwareProductFilter
|
||||
table = SoftwareProductTable
|
||||
form = SoftwareProductBulkEditForm
|
||||
filterset = filtersets.SoftwareProductFilterSet
|
||||
filterset_form = forms.SoftwareProductFilterForm
|
||||
table = tables.SoftwareProductTable
|
||||
form = forms.SoftwareProductBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
table = SoftwareProductTable
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductVersionListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProductVersions."""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
filterset = SoftwareProductVersionFilter
|
||||
filterset_form = SoftwareProductVersionFilterForm
|
||||
table = SoftwareProductVersionTable
|
||||
# template_name = "netbox_slm/object_list.html"
|
||||
filterset = filtersets.SoftwareProductVersionFilterSet
|
||||
filterset_form = forms.SoftwareProductVersionFilterForm
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductVersionView(generic.ObjectView):
|
||||
@@ -87,7 +81,7 @@ class SoftwareProductVersionEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProductVersion instance."""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
form = SoftwareProductVersionForm
|
||||
form = forms.SoftwareProductVersionForm
|
||||
|
||||
|
||||
class SoftwareProductVersionDeleteView(generic.ObjectDeleteView):
|
||||
@@ -98,30 +92,29 @@ class SoftwareProductVersionDeleteView(generic.ObjectDeleteView):
|
||||
|
||||
class SoftwareProductVersionBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
model_form = SoftwareProductVersionCSVForm
|
||||
table = SoftwareProductVersionTable
|
||||
model_form = forms.SoftwareProductVersionCSVForm
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
filterset = SoftwareProductVersionFilter
|
||||
table = SoftwareProductVersionTable
|
||||
form = SoftwareProductVersionBulkEditForm
|
||||
filterset = filtersets.SoftwareProductVersionFilterSet
|
||||
table = tables.SoftwareProductVersionTable
|
||||
form = forms.SoftwareProductVersionBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
table = SoftwareProductVersionTable
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProductInstallations."""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
filterset = SoftwareProductInstallationFilter
|
||||
filterset_form = SoftwareProductInstallationFilterForm
|
||||
table = SoftwareProductInstallationTable
|
||||
# template_name = "netbox_slm/object_list.html"
|
||||
filterset = filtersets.SoftwareProductInstallationFilterSet
|
||||
filterset_form = forms.SoftwareProductInstallationFilterForm
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationView(generic.ObjectView):
|
||||
@@ -129,16 +122,12 @@ class SoftwareProductInstallationView(generic.ObjectView):
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
|
||||
# def get_extra_context(self, request, instance):
|
||||
# records = instance.record_set.all()
|
||||
# return {"records": records}
|
||||
|
||||
|
||||
class SoftwareProductInstallationEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProductInstallation instance."""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
form = SoftwareProductInstallationForm
|
||||
form = forms.SoftwareProductInstallationForm
|
||||
|
||||
|
||||
class SoftwareProductInstallationDeleteView(generic.ObjectDeleteView):
|
||||
@@ -149,17 +138,17 @@ class SoftwareProductInstallationDeleteView(generic.ObjectDeleteView):
|
||||
|
||||
class SoftwareProductInstallationBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
model_form = SoftwareProductInstallationCSVForm
|
||||
table = SoftwareProductInstallationTable
|
||||
model_form = forms.SoftwareProductInstallationCSVForm
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
filterset = SoftwareProductInstallationFilter
|
||||
table = SoftwareProductInstallationTable
|
||||
form = SoftwareProductInstallationBulkEditForm
|
||||
filterset = filtersets.SoftwareProductInstallationFilterSet
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
form = forms.SoftwareProductInstallationBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
table = SoftwareProductInstallationTable
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[metadata]
|
||||
name = netbox-slm
|
||||
version = 0.98
|
||||
version = 0.99
|
||||
description = Software Lifecycle Management Netbox Plugin.
|
||||
# long_description = file: README.rst
|
||||
# long_description_content_type='text/x-rst'
|
||||
|
||||
Reference in New Issue
Block a user