Add SoftwareLicense (#20)
This commit is contained in:
@@ -9,3 +9,4 @@
|
||||
ci/docker-compose.override.yml
|
||||
ci/reports
|
||||
out/production
|
||||
*.iml
|
||||
|
||||
@@ -129,6 +129,7 @@ CSRF_TRUSTED_ORIGINS = list(filter(None, environ.get('CSRF_TRUSTED_ORIGINS', '')
|
||||
# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging
|
||||
# on a production system.
|
||||
DEBUG = environ.get('DEBUG', 'False').lower() == 'true'
|
||||
DEVELOPER = environ.get('DEVELOPER', 'False').lower() == 'true'
|
||||
|
||||
# Email settings
|
||||
EMAIL = {
|
||||
|
||||
@@ -5,7 +5,7 @@ class SLMConfig(PluginConfig):
|
||||
name = 'netbox_slm'
|
||||
verbose_name = 'Software Lifecycle Management'
|
||||
description = 'Software Lifecycle Management Netbox Plugin.'
|
||||
version = '1.3'
|
||||
version = '1.4'
|
||||
author = 'ICTU'
|
||||
author_email = 'open-source-projects@ictu.nl'
|
||||
base_url = 'slm'
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
|
||||
if settings.DEBUG:
|
||||
for model in apps.get_app_config("netbox_slm").get_models():
|
||||
admin.site.register(model)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from netbox.api.serializers import NetBoxModelSerializer
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
|
||||
|
||||
class SoftwareProductSerializer(NetBoxModelSerializer):
|
||||
@@ -13,7 +13,8 @@ class SoftwareProductSerializer(NetBoxModelSerializer):
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = [
|
||||
'id', 'display', 'url', 'name', 'tags', 'custom_field_data', 'created', 'last_updated',
|
||||
'id', 'display', 'url', 'name',
|
||||
'tags', 'custom_field_data', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
@@ -29,7 +30,8 @@ class SoftwareProductVersionSerializer(NetBoxModelSerializer):
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = [
|
||||
'id', 'display', 'url', 'name', 'software_product', 'tags', 'custom_field_data', 'created', 'last_updated',
|
||||
'id', 'display', 'url', 'name', 'software_product',
|
||||
'tags', 'custom_field_data', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
@@ -45,8 +47,26 @@ class SoftwareProductInstallationSerializer(NetBoxModelSerializer):
|
||||
class Meta:
|
||||
model = SoftwareProductInstallation
|
||||
fields = [
|
||||
'id', 'display', 'url', 'device', 'virtualmachine', 'software_product', 'version', 'tags',
|
||||
'custom_field_data', 'created', 'last_updated',
|
||||
'id', 'display', 'url', 'device', 'virtualmachine', 'software_product', 'version',
|
||||
'tags', 'custom_field_data', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
return f"{obj}"
|
||||
|
||||
|
||||
class SoftwareLicenseSerializer(NetBoxModelSerializer):
|
||||
display = serializers.SerializerMethodField()
|
||||
url = serializers.HyperlinkedIdentityField(
|
||||
view_name="plugins-api:netbox_slm-api:softwarelicense-detail"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareLicense
|
||||
fields = [
|
||||
'id', 'display', 'url', 'name', 'description', 'type', 'stored_location',
|
||||
'start_date', 'expiration_date', 'software_product', 'version', 'installation',
|
||||
'tags', 'custom_field_data', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
|
||||
@@ -4,6 +4,7 @@ from netbox_slm.api.views import (
|
||||
SoftwareProductViewSet,
|
||||
SoftwareProductVersionViewSet,
|
||||
SoftwareProductInstallationViewSet,
|
||||
SoftwareLicenseViewSet,
|
||||
)
|
||||
|
||||
router = NetBoxRouter()
|
||||
@@ -12,4 +13,5 @@ router.APIRootView = NetboxSLMRootView
|
||||
router.register("softwareproducts", SoftwareProductViewSet)
|
||||
router.register("softwareproductversions", SoftwareProductVersionViewSet)
|
||||
router.register("softwareproductinstallations", SoftwareProductInstallationViewSet)
|
||||
router.register("softwarelicenses", SoftwareLicenseViewSet)
|
||||
urlpatterns = router.urls
|
||||
|
||||
+15
-3
@@ -2,12 +2,18 @@ from rest_framework.routers import APIRootView
|
||||
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from netbox_slm.api.serializers import (
|
||||
SoftwareProductSerializer, SoftwareProductVersionSerializer, SoftwareProductInstallationSerializer,
|
||||
SoftwareProductSerializer,
|
||||
SoftwareProductVersionSerializer,
|
||||
SoftwareProductInstallationSerializer,
|
||||
SoftwareLicenseSerializer,
|
||||
)
|
||||
from netbox_slm.filtersets import (
|
||||
SoftwareProductFilterSet, SoftwareProductVersionFilterSet, SoftwareProductInstallationFilterSet,
|
||||
SoftwareProductFilterSet,
|
||||
SoftwareProductVersionFilterSet,
|
||||
SoftwareProductInstallationFilterSet,
|
||||
SoftwareLicenseFilterSet,
|
||||
)
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
|
||||
|
||||
class NetboxSLMRootView(APIRootView):
|
||||
@@ -35,3 +41,9 @@ class SoftwareProductInstallationViewSet(NetBoxModelViewSet):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
serializer_class = SoftwareProductInstallationSerializer
|
||||
filterset_class = SoftwareProductInstallationFilterSet
|
||||
|
||||
|
||||
class SoftwareLicenseViewSet(NetBoxModelViewSet):
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
serializer_class = SoftwareLicenseSerializer
|
||||
filterset_class = SoftwareLicenseFilterSet
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.db.models import Q
|
||||
|
||||
from netbox.filtersets import NetBoxModelFilterSet
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
|
||||
|
||||
class SoftwareProductFilterSet(NetBoxModelFilterSet):
|
||||
@@ -43,7 +43,9 @@ class SoftwareProductInstallationFilterSet(NetBoxModelFilterSet):
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductInstallation
|
||||
fields = tuple()
|
||||
fields = (
|
||||
"software_product",
|
||||
)
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
"""Perform the filtered search."""
|
||||
@@ -53,3 +55,22 @@ class SoftwareProductInstallationFilterSet(NetBoxModelFilterSet):
|
||||
Q(software_product__manufacturer__name__icontains=value) | \
|
||||
Q(version__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareLicenseFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareLicense instances."""
|
||||
|
||||
class Meta:
|
||||
model = SoftwareLicense
|
||||
fields = tuple()
|
||||
|
||||
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(version__name__icontains=value) | \
|
||||
Q(installation__device__name__icontains=value) | \
|
||||
Q(installation__virtualmachine__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
from .software_license import *
|
||||
from .software_product import *
|
||||
from .software_product_installation import *
|
||||
from .software_product_version import *
|
||||
@@ -0,0 +1,76 @@
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from netbox.forms import NetBoxModelForm, NetBoxModelImportForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
from utilities.forms import DynamicModelChoiceField, APISelect, TagFilterField
|
||||
|
||||
|
||||
class SoftwareLicenseForm(NetBoxModelForm):
|
||||
"""Form for creating a new SoftwareLicense object."""
|
||||
|
||||
software_product = DynamicModelChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
required=True,
|
||||
widget=APISelect(
|
||||
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}
|
||||
),
|
||||
)
|
||||
version = DynamicModelChoiceField(
|
||||
queryset=SoftwareProductVersion.objects.all(),
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductversion-list")}
|
||||
),
|
||||
query_params={
|
||||
'software_product': '$software_product',
|
||||
}
|
||||
)
|
||||
installation = DynamicModelChoiceField(
|
||||
queryset=SoftwareProductInstallation.objects.all(),
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductinstallation-list")}
|
||||
),
|
||||
query_params={
|
||||
'software_product': '$software_product',
|
||||
}
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareLicense
|
||||
fields = ("name", "description", "type", "stored_location", "start_date", "expiration_date",
|
||||
"software_product", "version", "installation", "tags")
|
||||
|
||||
|
||||
class SoftwareLicenseFilterForm(NetBoxModelFilterSetForm):
|
||||
model = SoftwareLicense
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag',)),
|
||||
)
|
||||
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class SoftwareLicenseImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = SoftwareLicense
|
||||
fields = ("name", "description", "type", "stored_location", "start_date", "expiration_date",)
|
||||
|
||||
|
||||
class SoftwareLicenseBulkEditForm(NetBoxModelBulkEditForm):
|
||||
software_product = DynamicModelChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
required=False
|
||||
)
|
||||
version = DynamicModelChoiceField(
|
||||
queryset=SoftwareProductVersion.objects.all(),
|
||||
required=False
|
||||
)
|
||||
installation = DynamicModelChoiceField(
|
||||
queryset=SoftwareProductInstallation.objects.all(),
|
||||
required=False
|
||||
)
|
||||
model = SoftwareLicense
|
||||
fieldsets = (
|
||||
(None, ('software_product', 'version', 'installation',)),
|
||||
)
|
||||
@@ -0,0 +1,45 @@
|
||||
from django import forms
|
||||
|
||||
from dcim.models import Manufacturer
|
||||
from netbox.forms import NetBoxModelForm, NetBoxModelImportForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
|
||||
from netbox_slm.models import SoftwareProduct
|
||||
from utilities.forms import DynamicModelChoiceField, TagFilterField
|
||||
|
||||
|
||||
class SoftwareProductForm(NetBoxModelForm):
|
||||
"""Form for creating a new SoftwareProduct object."""
|
||||
|
||||
manufacturer = DynamicModelChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = ("name", "manufacturer", "description", "tags")
|
||||
|
||||
|
||||
class SoftwareProductFilterForm(NetBoxModelFilterSetForm):
|
||||
model = SoftwareProduct
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class SoftwareProductImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = ("name", "manufacturer",)
|
||||
|
||||
|
||||
class SoftwareProductBulkEditForm(NetBoxModelBulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
widget=forms.MultipleHiddenInput(),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
nullable_fields = []
|
||||
@@ -2,94 +2,13 @@ from django import forms
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from dcim.models import Manufacturer, Device
|
||||
from dcim.models import Device
|
||||
from netbox.forms import NetBoxModelForm, NetBoxModelImportForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProductInstallation, SoftwareProduct, SoftwareProductVersion
|
||||
from utilities.forms import DynamicModelChoiceField, APISelect, TagFilterField
|
||||
from virtualization.models import VirtualMachine
|
||||
|
||||
|
||||
class SoftwareProductForm(NetBoxModelForm):
|
||||
"""Form for creating a new SoftwareProduct object."""
|
||||
|
||||
manufacturer = DynamicModelChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = ("name", "manufacturer", "description", "tags")
|
||||
|
||||
|
||||
class SoftwareProductFilterForm(NetBoxModelFilterSetForm):
|
||||
model = SoftwareProduct
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class SoftwareProductImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = ("name", "manufacturer",)
|
||||
|
||||
|
||||
class SoftwareProductBulkEditForm(NetBoxModelBulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
widget=forms.MultipleHiddenInput(),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
nullable_fields = []
|
||||
|
||||
|
||||
class SoftwareProductVersionForm(NetBoxModelForm):
|
||||
"""Form for creating a new SoftwareProductVersion object."""
|
||||
name = forms.CharField(label=_("Version"))
|
||||
|
||||
software_product = DynamicModelChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
widget=APISelect(
|
||||
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}
|
||||
),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = ("name", "software_product", "tags")
|
||||
|
||||
|
||||
class SoftwareProductVersionFilterForm(NetBoxModelFilterSetForm):
|
||||
model = SoftwareProductVersion
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class SoftwareProductVersionImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = ("name",)
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkEditForm(NetBoxModelBulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
widget=forms.MultipleHiddenInput(),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
nullable_fields = []
|
||||
|
||||
|
||||
class SoftwareProductInstallationForm(NetBoxModelForm):
|
||||
"""Form for creating a new SoftwareProductInstallation object."""
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
from django import forms
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from netbox.forms import NetBoxModelForm, NetBoxModelImportForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion
|
||||
from utilities.forms import DynamicModelChoiceField, APISelect, TagFilterField
|
||||
|
||||
|
||||
class SoftwareProductVersionForm(NetBoxModelForm):
|
||||
"""Form for creating a new SoftwareProductVersion object."""
|
||||
name = forms.CharField(label=_("Version"))
|
||||
|
||||
software_product = DynamicModelChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
widget=APISelect(
|
||||
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}
|
||||
),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = ("name", "software_product", "tags")
|
||||
|
||||
|
||||
class SoftwareProductVersionFilterForm(NetBoxModelFilterSetForm):
|
||||
model = SoftwareProductVersion
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
)
|
||||
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class SoftwareProductVersionImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = ("name",)
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkEditForm(NetBoxModelBulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=SoftwareProduct.objects.all(),
|
||||
widget=forms.MultipleHiddenInput(),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
nullable_fields = []
|
||||
@@ -0,0 +1,54 @@
|
||||
# Generated by Django 4.1.8 on 2023-06-27 08:10
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import taggit.managers
|
||||
import utilities.json
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('extras', '0084_staging'),
|
||||
('netbox_slm', '0004_auto_20220415_0705'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='softwareproduct',
|
||||
name='custom_field_data',
|
||||
field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='softwareproductinstallation',
|
||||
name='custom_field_data',
|
||||
field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='softwareproductversion',
|
||||
name='custom_field_data',
|
||||
field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SoftwareLicense',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
|
||||
('name', models.CharField(max_length=128)),
|
||||
('description', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('type', models.CharField(max_length=128)),
|
||||
('stored_location', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('start_date', models.DateField(blank=True, null=True)),
|
||||
('expiration_date', models.DateField(blank=True, null=True)),
|
||||
('installation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='netbox_slm.softwareproductinstallation')),
|
||||
('software_product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='netbox_slm.softwareproduct')),
|
||||
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
|
||||
('version', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='netbox_slm.softwareproductversion')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
+40
-3
@@ -33,11 +33,12 @@ class SoftwareProduct(NetBoxModel):
|
||||
|
||||
|
||||
class SoftwareProductVersion(NetBoxModel):
|
||||
name = models.CharField(max_length=64)
|
||||
|
||||
software_product = models.ForeignKey(
|
||||
to='netbox_slm.SoftwareProduct',
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
name = models.CharField(max_length=64)
|
||||
|
||||
objects = RestrictedQuerySet.as_manager()
|
||||
|
||||
@@ -80,13 +81,49 @@ class SoftwareProductInstallation(NetBoxModel):
|
||||
objects = RestrictedQuerySet.as_manager()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.pk}"
|
||||
return f"{self.pk} ({self.platform})"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("plugins:netbox_slm:softwareproductinstallation", kwargs={"pk": self.pk})
|
||||
|
||||
def get_platform(self):
|
||||
@property
|
||||
def platform(self):
|
||||
return self.device or self.virtualmachine
|
||||
|
||||
def render_type(self):
|
||||
return 'device' if self.device else 'virtualmachine'
|
||||
|
||||
|
||||
class SoftwareLicense(NetBoxModel):
|
||||
name = models.CharField(max_length=128)
|
||||
description = models.CharField(max_length=255, null=True, blank=True)
|
||||
type = models.CharField(max_length=128)
|
||||
|
||||
stored_location = models.CharField(max_length=255, null=True, blank=True)
|
||||
start_date = models.DateField(null=True, blank=True)
|
||||
expiration_date = models.DateField(null=True, blank=True)
|
||||
|
||||
software_product = models.ForeignKey(
|
||||
to='netbox_slm.SoftwareProduct',
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
version = models.ForeignKey(
|
||||
to='netbox_slm.SoftwareProductVersion',
|
||||
on_delete=models.PROTECT,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
installation = models.ForeignKey(
|
||||
to='netbox_slm.SoftwareProductInstallation',
|
||||
on_delete=models.PROTECT,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
|
||||
objects = RestrictedQuerySet.as_manager()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("plugins:netbox_slm:softwarelicense", kwargs={"pk": self.pk})
|
||||
|
||||
@@ -62,4 +62,24 @@ menu_items = (
|
||||
),
|
||||
)
|
||||
),
|
||||
PluginMenuItem(
|
||||
link='plugins:netbox_slm:softwarelicense_list',
|
||||
link_text='Licenses',
|
||||
buttons=(
|
||||
PluginMenuButton(
|
||||
"plugins:netbox_slm:softwarelicense_add",
|
||||
"Add",
|
||||
"mdi mdi-plus-thick",
|
||||
ButtonColorChoices.GREEN,
|
||||
permissions=["netbox_slm.add_softwarelicense"],
|
||||
),
|
||||
PluginMenuButton(
|
||||
"plugins:netbox_slm:softwarelicense_import",
|
||||
"Import",
|
||||
"mdi mdi-upload",
|
||||
ButtonColorChoices.CYAN,
|
||||
permissions=["netbox_slm.add_softwarelicense"],
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
+57
-2
@@ -3,7 +3,7 @@ from django.db.models import Count
|
||||
from django_tables2.utils import Accessor
|
||||
|
||||
from netbox.tables import NetBoxTable, ToggleColumn, columns
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
|
||||
|
||||
class SoftwareProductTable(NetBoxTable):
|
||||
@@ -118,7 +118,7 @@ class SoftwareProductInstallationTable(NetBoxTable):
|
||||
linkify=True
|
||||
)
|
||||
platform = tables.Column(
|
||||
accessor='get_platform',
|
||||
accessor=Accessor('platform'),
|
||||
linkify=True
|
||||
)
|
||||
type = tables.Column(accessor='render_type')
|
||||
@@ -165,3 +165,58 @@ class SoftwareProductInstallationTable(NetBoxTable):
|
||||
|
||||
def render_software_product(self, value, **kwargs):
|
||||
return f"{kwargs['record'].software_product.manufacturer.name} - {value}"
|
||||
|
||||
|
||||
class SoftwareLicenseTable(NetBoxTable):
|
||||
"""Table for displaying SoftwareLicense objects."""
|
||||
|
||||
pk = ToggleColumn()
|
||||
name = tables.LinkColumn()
|
||||
|
||||
type = tables.Column(accessor='render_type')
|
||||
software_product = tables.Column(
|
||||
accessor=Accessor('software_product'),
|
||||
linkify=True
|
||||
)
|
||||
version = tables.Column(
|
||||
accessor=Accessor('version'),
|
||||
linkify=True
|
||||
)
|
||||
installation = tables.Column(
|
||||
accessor=Accessor('installation'),
|
||||
linkify=True
|
||||
)
|
||||
|
||||
tags = columns.TagColumn(
|
||||
url_name="plugins:netbox_slm:softwarelicense_list",
|
||||
)
|
||||
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = SoftwareLicense
|
||||
fields = (
|
||||
"pk",
|
||||
"name",
|
||||
"description",
|
||||
"type",
|
||||
"stored_location",
|
||||
"start_date",
|
||||
"expiration_date",
|
||||
"software_product",
|
||||
"version",
|
||||
"installation",
|
||||
"tags",
|
||||
)
|
||||
default_columns = (
|
||||
"pk",
|
||||
"name",
|
||||
"expiration_date",
|
||||
"software_product",
|
||||
"installation",
|
||||
"tags",
|
||||
)
|
||||
|
||||
def render_software_product(self, value, **kwargs):
|
||||
return f"{kwargs['record'].software_product.manufacturer.name} - {value}"
|
||||
|
||||
def render_installation(self, **kwargs):
|
||||
return f"{kwargs['record'].installation.platform}"
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load buttons %}
|
||||
{% load static %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row my-3">
|
||||
<div class="col col-md-6">
|
||||
<div class="card">
|
||||
<h5 class="card-header">
|
||||
Software License
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<table class="table table-hover attr-table">
|
||||
<tr>
|
||||
<th scope="row">Name</th>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Description</th>
|
||||
<td>{{ object.description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Type</th>
|
||||
<td>{{ object.type }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Stored location</th>
|
||||
<td>{{ object.stored_location }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Start date</th>
|
||||
<td>{{ object.start_date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Expiration date</th>
|
||||
<td>{{ object.expiration_date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Software Product</th>
|
||||
<td>{{ object.software_product }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Version</th>
|
||||
<td>{{ object.version }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Installation</th>
|
||||
<td>{{ object.installation }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'inc/panels/custom_fields.html' %}
|
||||
{% include 'inc/panels/tags.html' %}
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -15,7 +15,15 @@
|
||||
<table class="table table-hover attr-table">
|
||||
<tr>
|
||||
<th scope="row">Name</th>
|
||||
<td>{{ object }}</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Description</th>
|
||||
<td>{{ object.description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Manufacturer</th>
|
||||
<td>{{ object.manufacturer }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Versions</th>
|
||||
@@ -34,7 +42,6 @@
|
||||
</div>
|
||||
{% include 'inc/panels/custom_fields.html' %}
|
||||
{% include 'inc/panels/tags.html' %}
|
||||
{# {% include 'inc/panels/comments.html' %}#}
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
</div>
|
||||
{% include 'inc/panels/custom_fields.html' %}
|
||||
{% include 'inc/panels/tags.html' %}
|
||||
{# {% include 'inc/panels/comments.html' %}#}
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
</div>
|
||||
{% include 'inc/panels/custom_fields.html' %}
|
||||
{% include 'inc/panels/tags.html' %}
|
||||
{# {% include 'inc/panels/comments.html' %}#}
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
|
||||
|
||||
class ModelTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.p_name = "test product"
|
||||
self.v_name = "test version"
|
||||
self.l_name = "test license"
|
||||
|
||||
self.software_product = SoftwareProduct.objects.create(name=self.p_name)
|
||||
self.software_product_version = SoftwareProductVersion.objects.create(
|
||||
@@ -15,16 +16,22 @@ class ModelTestCase(TestCase):
|
||||
self.software_product_installation = SoftwareProductInstallation.objects.create(
|
||||
software_product=self.software_product, version=self.software_product_version
|
||||
)
|
||||
self.software_license = SoftwareLicense.objects.create(
|
||||
name=self.l_name, software_product=self.software_product,
|
||||
version=self.software_product_version, installation=self.software_product_installation
|
||||
)
|
||||
|
||||
def test_model_name(self):
|
||||
self.assertEqual(self.p_name, str(self.software_product))
|
||||
self.assertEqual(self.v_name, str(self.software_product_version))
|
||||
self.assertTrue(str(self.software_product_installation).isnumeric()) # should be PK
|
||||
self.assertTrue(str(self.software_product_installation)[0].isdigit()) # starts with PK
|
||||
self.assertEqual(self.l_name, str(self.software_license))
|
||||
|
||||
def test_absolute_url(self):
|
||||
self.assertEqual("/plugins/slm/software-products/1/", self.software_product.get_absolute_url())
|
||||
self.assertEqual("/plugins/slm/versions/1/", self.software_product_version.get_absolute_url())
|
||||
self.assertEqual("/plugins/slm/installations/1/", self.software_product_installation.get_absolute_url())
|
||||
self.assertEqual("/plugins/slm/licenses/1/", self.software_license.get_absolute_url())
|
||||
|
||||
def test_get_installation_count(self):
|
||||
installation_ss = '<a href="/plugins/slm/installations/?q={}">1</a>'
|
||||
@@ -33,4 +40,4 @@ class ModelTestCase(TestCase):
|
||||
|
||||
def test_product_installation_methods(self):
|
||||
self.assertEqual("virtualmachine", self.software_product_installation.render_type())
|
||||
self.assertIsNone(self.software_product_installation.get_platform())
|
||||
self.assertIsNone(self.software_product_installation.platform)
|
||||
|
||||
+50
-15
@@ -2,20 +2,26 @@ from django.urls import path
|
||||
|
||||
from netbox.views.generic import ObjectChangeLogView
|
||||
from netbox_slm import views
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
|
||||
|
||||
urlpatterns = [
|
||||
# Software Products
|
||||
path("software-products/", views.SoftwareProductListView.as_view(), name='softwareproduct_list'),
|
||||
path("software-products/add/", views.SoftwareProductEditView.as_view(), name='softwareproduct_add'),
|
||||
path("software-products/import/", views.SoftwareProductBulkImportView.as_view(), name="softwareproduct_import"),
|
||||
path("software-products/edit/", views.SoftwareProductBulkEditView.as_view(), name="softwareproduct_bulk_edit"),
|
||||
# SoftwareProduct
|
||||
path("software-products/", views.SoftwareProductListView.as_view(),
|
||||
name='softwareproduct_list'),
|
||||
path("software-products/add/", views.SoftwareProductEditView.as_view(),
|
||||
name='softwareproduct_add'),
|
||||
path("software-products/import/", views.SoftwareProductBulkImportView.as_view(),
|
||||
name="softwareproduct_import"),
|
||||
path("software-products/edit/", views.SoftwareProductBulkEditView.as_view(),
|
||||
name="softwareproduct_bulk_edit"),
|
||||
path("software-products/delete/", views.SoftwareProductBulkDeleteView.as_view(),
|
||||
name="softwareproduct_bulk_delete"),
|
||||
path("software-products/<int:pk>/", views.SoftwareProductView.as_view(), name="softwareproduct"),
|
||||
path("software-products/<int:pk>/", views.SoftwareProductView.as_view(),
|
||||
name="softwareproduct"),
|
||||
path("software-products/<int:pk>/delete/", views.SoftwareProductDeleteView.as_view(),
|
||||
name="softwareproduct_delete"),
|
||||
path("software-products/<int:pk>/edit/", views.SoftwareProductEditView.as_view(), name="softwareproduct_edit"),
|
||||
path("software-products/<int:pk>/edit/", views.SoftwareProductEditView.as_view(),
|
||||
name="softwareproduct_edit"),
|
||||
path(
|
||||
"software-products/<int:pk>/changelog/",
|
||||
ObjectChangeLogView.as_view(),
|
||||
@@ -23,18 +29,23 @@ urlpatterns = [
|
||||
kwargs={"model": SoftwareProduct},
|
||||
),
|
||||
|
||||
# Software Product Versions
|
||||
path("versions/", views.SoftwareProductVersionListView.as_view(), name='softwareproductversion_list'),
|
||||
path("versions/add/", views.SoftwareProductVersionEditView.as_view(), name='softwareproductversion_add'),
|
||||
# SoftwareProductVersion
|
||||
path("versions/", views.SoftwareProductVersionListView.as_view(),
|
||||
name='softwareproductversion_list'),
|
||||
path("versions/add/", views.SoftwareProductVersionEditView.as_view(),
|
||||
name='softwareproductversion_add'),
|
||||
path("versions/import/", views.SoftwareProductVersionBulkImportView.as_view(),
|
||||
name="softwareproductversion_import"),
|
||||
path("versions/edit/", views.SoftwareProductVersionBulkEditView.as_view(), name="softwareproductversion_bulk_edit"),
|
||||
path("versions/edit/", views.SoftwareProductVersionBulkEditView.as_view(),
|
||||
name="softwareproductversion_bulk_edit"),
|
||||
path("versions/delete/", views.SoftwareProductVersionBulkDeleteView.as_view(),
|
||||
name="softwareproductversion_bulk_delete"),
|
||||
path("versions/<int:pk>/", views.SoftwareProductVersionView.as_view(), name="softwareproductversion"),
|
||||
path("versions/<int:pk>/", views.SoftwareProductVersionView.as_view(),
|
||||
name="softwareproductversion"),
|
||||
path("versions/<int:pk>/delete/", views.SoftwareProductVersionDeleteView.as_view(),
|
||||
name="softwareproductversion_delete"),
|
||||
path("versions/<int:pk>/edit/", views.SoftwareProductVersionEditView.as_view(), name="softwareproductversion_edit"),
|
||||
path("versions/<int:pk>/edit/", views.SoftwareProductVersionEditView.as_view(),
|
||||
name="softwareproductversion_edit"),
|
||||
path(
|
||||
"versions/<int:pk>/changelog/",
|
||||
ObjectChangeLogView.as_view(),
|
||||
@@ -42,7 +53,7 @@ urlpatterns = [
|
||||
kwargs={"model": SoftwareProductVersion},
|
||||
),
|
||||
|
||||
# Software Product Versions
|
||||
# SoftwareProductInstallation
|
||||
path("installations/", views.SoftwareProductInstallationListView.as_view(),
|
||||
name='softwareproductinstallation_list'),
|
||||
path("installations/add/", views.SoftwareProductInstallationEditView.as_view(),
|
||||
@@ -65,4 +76,28 @@ urlpatterns = [
|
||||
name="softwareproductinstallation_changelog",
|
||||
kwargs={"model": SoftwareProductInstallation},
|
||||
),
|
||||
|
||||
# SoftwareLicense
|
||||
path("licenses/", views.SoftwareLicenseListView.as_view(),
|
||||
name='softwarelicense_list'),
|
||||
path("licenses/add/", views.SoftwareLicenseEditView.as_view(),
|
||||
name='softwarelicense_add'),
|
||||
path("licenses/import/", views.SoftwareLicenseBulkImportView.as_view(),
|
||||
name="softwarelicense_import"),
|
||||
path("licenses/edit/", views.SoftwareLicenseBulkEditView.as_view(),
|
||||
name="softwarelicense_bulk_edit"),
|
||||
path("licenses/delete/", views.SoftwareLicenseBulkDeleteView.as_view(),
|
||||
name="softwarelicense_bulk_delete"),
|
||||
path("licenses/<int:pk>/", views.SoftwareLicenseView.as_view(),
|
||||
name="softwarelicense"),
|
||||
path("licenses/<int:pk>/delete/", views.SoftwareLicenseDeleteView.as_view(),
|
||||
name="softwarelicense_delete"),
|
||||
path("licenses/<int:pk>/edit/", views.SoftwareLicenseEditView.as_view(),
|
||||
name="softwarelicense_edit"),
|
||||
path(
|
||||
"licenses/<int:pk>/changelog/",
|
||||
ObjectChangeLogView.as_view(),
|
||||
name="softwarelicense_changelog",
|
||||
kwargs={"model": SoftwareLicense},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm import filtersets, forms, tables
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class SoftwareProductListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProducts."""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
filterset = filtersets.SoftwareProductFilterSet
|
||||
filterset_form = forms.SoftwareProductFilterForm
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductView(generic.ObjectView):
|
||||
"""Display SoftwareProduct details"""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
versions = instance.softwareproductversion_set.all()
|
||||
return {"versions": versions}
|
||||
|
||||
|
||||
class SoftwareProductEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProduct instance."""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
form = forms.SoftwareProductForm
|
||||
|
||||
|
||||
class SoftwareProductDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareProduct instance"""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
model_form = forms.SoftwareProductImportForm
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
filterset = filtersets.SoftwareProductFilterSet
|
||||
filterset_form = forms.SoftwareProductFilterForm
|
||||
table = tables.SoftwareProductTable
|
||||
form = forms.SoftwareProductBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductVersionListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProductVersions."""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
filterset = filtersets.SoftwareProductVersionFilterSet
|
||||
filterset_form = forms.SoftwareProductVersionFilterForm
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductVersionView(generic.ObjectView):
|
||||
"""Display SoftwareProductVersion details"""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
installation_count = instance.get_installation_count()
|
||||
return {"installations": installation_count}
|
||||
|
||||
|
||||
class SoftwareProductVersionEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProductVersion instance."""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
form = forms.SoftwareProductVersionForm
|
||||
|
||||
|
||||
class SoftwareProductVersionDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareProductVersion instance"""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
model_form = forms.SoftwareProductVersionImportForm
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
filterset = filtersets.SoftwareProductVersionFilterSet
|
||||
table = tables.SoftwareProductVersionTable
|
||||
form = forms.SoftwareProductVersionBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProductInstallations."""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
filterset = filtersets.SoftwareProductInstallationFilterSet
|
||||
filterset_form = forms.SoftwareProductInstallationFilterForm
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationView(generic.ObjectView):
|
||||
"""Display SoftwareProductInstallation details"""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductInstallationEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProductInstallation instance."""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
form = forms.SoftwareProductInstallationForm
|
||||
|
||||
|
||||
class SoftwareProductInstallationDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareProductInstallation instance"""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
model_form = forms.SoftwareProductInstallationImportForm
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
filterset = filtersets.SoftwareProductInstallationFilterSet
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
form = forms.SoftwareProductInstallationBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
@@ -0,0 +1,4 @@
|
||||
from .software_license import *
|
||||
from .software_product import *
|
||||
from .software_product_installation import *
|
||||
from .software_product_version import *
|
||||
@@ -0,0 +1,49 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm import filtersets, forms, tables
|
||||
from netbox_slm.models import SoftwareLicense
|
||||
|
||||
|
||||
class SoftwareLicenseListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareLicenses."""
|
||||
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
filterset = filtersets.SoftwareLicenseFilterSet
|
||||
filterset_form = forms.SoftwareLicenseFilterForm
|
||||
table = tables.SoftwareLicenseTable
|
||||
|
||||
|
||||
class SoftwareLicenseView(generic.ObjectView):
|
||||
"""Display SoftwareLicense details"""
|
||||
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
|
||||
|
||||
class SoftwareLicenseEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareLicense instance."""
|
||||
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
form = forms.SoftwareLicenseForm
|
||||
|
||||
|
||||
class SoftwareLicenseDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareLicense instance"""
|
||||
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
|
||||
|
||||
class SoftwareLicenseBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
model_form = forms.SoftwareLicenseImportForm
|
||||
table = tables.SoftwareLicenseTable
|
||||
|
||||
|
||||
class SoftwareLicenseBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
filterset = filtersets.SoftwareLicenseFilterSet
|
||||
table = tables.SoftwareLicenseTable
|
||||
form = forms.SoftwareLicenseBulkEditForm
|
||||
|
||||
|
||||
class SoftwareLicenseBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareLicense.objects.all()
|
||||
table = tables.SoftwareLicenseTable
|
||||
@@ -0,0 +1,54 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm import filtersets, forms, tables
|
||||
from netbox_slm.models import SoftwareProduct
|
||||
|
||||
|
||||
class SoftwareProductListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProducts."""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
filterset = filtersets.SoftwareProductFilterSet
|
||||
filterset_form = forms.SoftwareProductFilterForm
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductView(generic.ObjectView):
|
||||
"""Display SoftwareProduct details"""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
versions = instance.softwareproductversion_set.all()
|
||||
return {"versions": versions}
|
||||
|
||||
|
||||
class SoftwareProductEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProduct instance."""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
form = forms.SoftwareProductForm
|
||||
|
||||
|
||||
class SoftwareProductDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareProduct instance"""
|
||||
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
model_form = forms.SoftwareProductImportForm
|
||||
table = tables.SoftwareProductTable
|
||||
|
||||
|
||||
class SoftwareProductBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
filterset = filtersets.SoftwareProductFilterSet
|
||||
filterset_form = forms.SoftwareProductFilterForm
|
||||
table = tables.SoftwareProductTable
|
||||
form = forms.SoftwareProductBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProduct.objects.all()
|
||||
table = tables.SoftwareProductTable
|
||||
@@ -0,0 +1,49 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm import filtersets, forms, tables
|
||||
from netbox_slm.models import SoftwareProductInstallation
|
||||
|
||||
|
||||
class SoftwareProductInstallationListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProductInstallations."""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
filterset = filtersets.SoftwareProductInstallationFilterSet
|
||||
filterset_form = forms.SoftwareProductInstallationFilterForm
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationView(generic.ObjectView):
|
||||
"""Display SoftwareProductInstallation details"""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductInstallationEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProductInstallation instance."""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
form = forms.SoftwareProductInstallationForm
|
||||
|
||||
|
||||
class SoftwareProductInstallationDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareProductInstallation instance"""
|
||||
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
model_form = forms.SoftwareProductInstallationImportForm
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
filterset = filtersets.SoftwareProductInstallationFilterSet
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
form = forms.SoftwareProductInstallationBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductInstallationBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProductInstallation.objects.all()
|
||||
table = tables.SoftwareProductInstallationTable
|
||||
@@ -0,0 +1,53 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm import filtersets, forms, tables
|
||||
from netbox_slm.models import SoftwareProductVersion
|
||||
|
||||
|
||||
class SoftwareProductVersionListView(generic.ObjectListView):
|
||||
"""View for listing all existing SoftwareProductVersions."""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
filterset = filtersets.SoftwareProductVersionFilterSet
|
||||
filterset_form = forms.SoftwareProductVersionFilterForm
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductVersionView(generic.ObjectView):
|
||||
"""Display SoftwareProductVersion details"""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
installation_count = instance.get_installation_count()
|
||||
return {"installations": installation_count}
|
||||
|
||||
|
||||
class SoftwareProductVersionEditView(generic.ObjectEditView):
|
||||
"""View for editing and creating a SoftwareProductVersion instance."""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
form = forms.SoftwareProductVersionForm
|
||||
|
||||
|
||||
class SoftwareProductVersionDeleteView(generic.ObjectDeleteView):
|
||||
"""View for deleting a SoftwareProductVersion instance"""
|
||||
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkImportView(generic.BulkImportView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
model_form = forms.SoftwareProductVersionImportForm
|
||||
table = tables.SoftwareProductVersionTable
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkEditView(generic.BulkEditView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
filterset = filtersets.SoftwareProductVersionFilterSet
|
||||
table = tables.SoftwareProductVersionTable
|
||||
form = forms.SoftwareProductVersionBulkEditForm
|
||||
|
||||
|
||||
class SoftwareProductVersionBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = SoftwareProductVersion.objects.all()
|
||||
table = tables.SoftwareProductVersionTable
|
||||
@@ -1,6 +1,6 @@
|
||||
[metadata]
|
||||
name = netbox-slm
|
||||
version = 1.3
|
||||
version = 1.4
|
||||
description = Software Lifecycle Management Netbox Plugin.
|
||||
author = ICTU
|
||||
author_email = open-source-projects@ictu.nl
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
sonar.organization=ictu
|
||||
sonar.projectKey=ICTU_netbox_slm
|
||||
sonar.projectName=netbox-slm
|
||||
sonar.projectVersion=1.3
|
||||
sonar.projectVersion=1.4
|
||||
|
||||
# Path is relative to the sonar-project.properties file
|
||||
sonar.sources=netbox_slm
|
||||
sonar.python.version=3.9
|
||||
sonar.python.version=3.9, 3.10, 3.11
|
||||
|
||||
# Unit tests
|
||||
sonar.python.xunit.reportPath=ci/reports/junit.xml
|
||||
|
||||
Reference in New Issue
Block a user