Assorted fixes (#25)

* Updated imports for Netbox 3.6.1

Closes #21 and #23

* Changed Fieldtypes of Start and Expiration Date

Closes #22

* Bump to NetBox v3.6.1

* Add pyproject.toml and python workflow

---------

Co-authored-by: Manuel Hartung <manuel.hartung@atos.net>
This commit is contained in:
wkoot
2023-09-15 09:41:36 +02:00
co-authored by Manuel Hartung
parent 6c512e0e9b
commit aa41f8a402
26 changed files with 492 additions and 565 deletions
+10 -10
View File
@@ -1,18 +1,18 @@
from extras.plugins import PluginConfig
__version__ = "1.4"
class SLMConfig(PluginConfig):
name = 'netbox_slm'
verbose_name = 'Software Lifecycle Management'
description = 'Software Lifecycle Management Netbox Plugin.'
version = '1.4'
author = 'ICTU'
author_email = 'open-source-projects@ictu.nl'
base_url = 'slm'
name = "netbox_slm"
verbose_name = "Software Lifecycle Management"
description = "Software Lifecycle Management Netbox Plugin."
version = __version__
author = "ICTU"
author_email = "open-source-projects@ictu.nl"
base_url = "slm"
required_settings = []
default_settings = {
'version_info': False
}
default_settings = {"version_info": False}
config = SLMConfig
+47 -18
View File
@@ -6,15 +6,19 @@ from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareP
class SoftwareProductSerializer(NetBoxModelSerializer):
display = serializers.SerializerMethodField()
url = serializers.HyperlinkedIdentityField(
view_name="plugins-api:netbox_slm-api:softwareproduct-detail"
)
url = serializers.HyperlinkedIdentityField(view_name="plugins-api:netbox_slm-api:softwareproduct-detail")
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):
@@ -23,15 +27,20 @@ class SoftwareProductSerializer(NetBoxModelSerializer):
class SoftwareProductVersionSerializer(NetBoxModelSerializer):
display = serializers.SerializerMethodField()
url = serializers.HyperlinkedIdentityField(
view_name="plugins-api:netbox_slm-api:softwareproductversion-detail"
)
url = serializers.HyperlinkedIdentityField(view_name="plugins-api:netbox_slm-api:softwareproductversion-detail")
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):
@@ -47,8 +56,17 @@ 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):
@@ -57,16 +75,27 @@ class SoftwareProductInstallationSerializer(NetBoxModelSerializer):
class SoftwareLicenseSerializer(NetBoxModelSerializer):
display = serializers.SerializerMethodField()
url = serializers.HyperlinkedIdentityField(
view_name="plugins-api:netbox_slm-api:softwarelicense-detail"
)
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',
"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):
+19 -17
View File
@@ -24,17 +24,17 @@ class SoftwareProductVersionFilterSet(NetBoxModelFilterSet):
class Meta:
model = SoftwareProductVersion
fields = (
"software_product",
)
fields = ("software_product",)
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)
qs_filter = (
Q(name__icontains=value)
| Q(software_product__name__icontains=value)
| Q(software_product__manufacturer__name__icontains=value)
)
return queryset.filter(qs_filter)
@@ -43,17 +43,17 @@ class SoftwareProductInstallationFilterSet(NetBoxModelFilterSet):
class Meta:
model = SoftwareProductInstallation
fields = (
"software_product",
)
fields = ("software_product",)
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)
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)
@@ -68,9 +68,11 @@ class SoftwareLicenseFilterSet(NetBoxModelFilterSet):
"""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)
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)
+24 -4
View File
@@ -1,4 +1,24 @@
from .software_license import *
from .software_product import *
from .software_product_installation import *
from .software_product_version import *
from .software_license import (
SoftwareLicenseForm,
SoftwareLicenseFilterForm,
SoftwareLicenseImportForm,
SoftwareLicenseBulkEditForm,
)
from .software_product import (
SoftwareProductForm,
SoftwareProductFilterForm,
SoftwareProductImportForm,
SoftwareProductBulkEditForm,
)
from .software_product_installation import (
SoftwareProductInstallationForm,
SoftwareProductInstallationFilterForm,
SoftwareProductInstallationImportForm,
SoftwareProductInstallationBulkEditForm,
)
from .software_product_version import (
SoftwareProductVersionForm,
SoftwareProductVersionFilterForm,
SoftwareProductVersionImportForm,
SoftwareProductVersionBulkEditForm,
)
+50 -28
View File
@@ -1,8 +1,11 @@
from django.forms import DateField
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelForm, NetBoxModelImportForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation, SoftwareLicense
from utilities.forms import DynamicModelChoiceField, APISelect, TagFilterField
from utilities.forms.fields import DynamicModelChoiceField, TagFilterField
from utilities.forms.widgets import APISelect, DatePicker
class SoftwareLicenseForm(NetBoxModelForm):
@@ -11,19 +14,15 @@ class SoftwareLicenseForm(NetBoxModelForm):
software_product = DynamicModelChoiceField(
queryset=SoftwareProduct.objects.all(),
required=True,
widget=APISelect(
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}
),
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")}
),
widget=APISelect(attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductversion-list")}),
query_params={
'software_product': '$software_product',
}
"software_product": "$software_product",
},
)
installation = DynamicModelChoiceField(
queryset=SoftwareProductInstallation.objects.all(),
@@ -32,20 +31,38 @@ class SoftwareLicenseForm(NetBoxModelForm):
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductinstallation-list")}
),
query_params={
'software_product': '$software_product',
}
"software_product": "$software_product",
},
)
start_date = DateField(label=_("Start date"), required=False, widget=DatePicker())
expiration_date = DateField(label=_("Expiration date"), required=False, widget=DatePicker())
class Meta:
model = SoftwareLicense
fields = ("name", "description", "type", "stored_location", "start_date", "expiration_date",
"software_product", "version", "installation", "tags")
fields = (
"name",
"description",
"type",
"stored_location",
"start_date",
"expiration_date",
"software_product",
"version",
"installation",
"tags",
)
class SoftwareLicenseFilterForm(NetBoxModelFilterSetForm):
model = SoftwareLicense
fieldsets = (
(None, ('q', 'tag',)),
(
None,
(
"q",
"tag",
),
),
)
tag = TagFilterField(model)
@@ -54,23 +71,28 @@ class SoftwareLicenseFilterForm(NetBoxModelFilterSetForm):
class SoftwareLicenseImportForm(NetBoxModelImportForm):
class Meta:
model = SoftwareLicense
fields = ("name", "description", "type", "stored_location", "start_date", "expiration_date",)
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
)
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',)),
(
None,
(
"software_product",
"version",
"installation",
),
),
)
+6 -5
View File
@@ -3,7 +3,7 @@ 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
from utilities.forms.fields import DynamicModelChoiceField, TagFilterField
class SoftwareProductForm(NetBoxModelForm):
@@ -21,9 +21,7 @@ class SoftwareProductForm(NetBoxModelForm):
class SoftwareProductFilterForm(NetBoxModelFilterSetForm):
model = SoftwareProduct
fieldsets = (
(None, ('q', 'tag')),
)
fieldsets = ((None, ("q", "tag")),)
tag = TagFilterField(model)
@@ -31,7 +29,10 @@ class SoftwareProductFilterForm(NetBoxModelFilterSetForm):
class SoftwareProductImportForm(NetBoxModelImportForm):
class Meta:
model = SoftwareProduct
fields = ("name", "manufacturer",)
fields = (
"name",
"manufacturer",
)
class SoftwareProductBulkEditForm(NetBoxModelBulkEditForm):
@@ -5,37 +5,28 @@ from django.utils.translation import gettext as _
from dcim.models import Device
from netbox.forms import NetBoxModelForm, NetBoxModelImportForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
from netbox_slm.models import SoftwareProductInstallation, SoftwareProduct, SoftwareProductVersion
from utilities.forms import DynamicModelChoiceField, APISelect, TagFilterField
from utilities.forms.fields import DynamicModelChoiceField, TagFilterField
from utilities.forms.widgets import APISelect
from virtualization.models import VirtualMachine
class SoftwareProductInstallationForm(NetBoxModelForm):
"""Form for creating a new SoftwareProductInstallation object."""
device = DynamicModelChoiceField(
queryset=Device.objects.all(),
required=False,
)
virtualmachine = DynamicModelChoiceField(
queryset=VirtualMachine.objects.all(),
required=False,
)
device = DynamicModelChoiceField(queryset=Device.objects.all(), required=False)
virtualmachine = DynamicModelChoiceField(queryset=VirtualMachine.objects.all(), required=False)
software_product = DynamicModelChoiceField(
queryset=SoftwareProduct.objects.all(),
required=True,
widget=APISelect(
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}
),
widget=APISelect(attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}),
)
version = DynamicModelChoiceField(
queryset=SoftwareProductVersion.objects.all(),
required=True,
widget=APISelect(
attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductversion-list")}
),
widget=APISelect(attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproductversion-list")}),
query_params={
'software_product': '$software_product',
}
"software_product": "$software_product",
},
)
class Meta:
@@ -43,15 +34,19 @@ class SoftwareProductInstallationForm(NetBoxModelForm):
fields = ("device", "virtualmachine", "software_product", "version", "tags")
def clean_version(self):
version = self.cleaned_data['version']
software_product = self.cleaned_data['software_product']
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."))
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']]):
if not any([self.cleaned_data["device"], self.cleaned_data["virtualmachine"]]):
raise forms.ValidationError(_("Installation requires atleast one virtualmachine or device destination."))
return super(SoftwareProductInstallationForm, self).clean()
@@ -59,7 +54,13 @@ class SoftwareProductInstallationForm(NetBoxModelForm):
class SoftwareProductInstallationFilterForm(NetBoxModelFilterSetForm):
model = SoftwareProductInstallation
fieldsets = (
(None, ('q', 'tag',)),
(
None,
(
"q",
"tag",
),
),
)
tag = TagFilterField(model)
@@ -72,15 +73,15 @@ class SoftwareProductInstallationImportForm(NetBoxModelImportForm):
class SoftwareProductInstallationBulkEditForm(NetBoxModelBulkEditForm):
software_product = DynamicModelChoiceField(
queryset=SoftwareProduct.objects.all(),
required=False
)
version = DynamicModelChoiceField(
queryset=SoftwareProductVersion.objects.all(),
required=False
)
software_product = DynamicModelChoiceField(queryset=SoftwareProduct.objects.all(), required=False)
version = DynamicModelChoiceField(queryset=SoftwareProductVersion.objects.all(), required=False)
model = SoftwareProductInstallation
fieldsets = (
(None, ('software_product', 'version',)),
(
None,
(
"software_product",
"version",
),
),
)
+5 -7
View File
@@ -4,18 +4,18 @@ 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
from utilities.forms.fields import DynamicModelChoiceField, TagFilterField
from utilities.forms.widgets import APISelect
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")}
),
widget=APISelect(attrs={"data-url": reverse_lazy("plugins-api:netbox_slm-api:softwareproduct-list")}),
)
class Meta:
@@ -25,9 +25,7 @@ class SoftwareProductVersionForm(NetBoxModelForm):
class SoftwareProductVersionFilterForm(NetBoxModelFilterSetForm):
model = SoftwareProductVersion
fieldsets = (
(None, ('q', 'tag')),
)
fieldsets = ((None, ("q", "tag")),)
tag = TagFilterField(model)
+30 -47
View File
@@ -10,11 +10,7 @@ class SoftwareProduct(NetBoxModel):
name = models.CharField(max_length=128)
description = models.CharField(max_length=255, null=True, blank=True)
manufacturer = models.ForeignKey(
to='dcim.Manufacturer',
on_delete=models.PROTECT,
null=True, blank=True
)
manufacturer = models.ForeignKey(to="dcim.Manufacturer", on_delete=models.PROTECT, null=True, blank=True)
objects = RestrictedQuerySet.as_manager()
@@ -26,17 +22,23 @@ class SoftwareProduct(NetBoxModel):
def get_installation_count(self):
count = SoftwareProductInstallation.objects.filter(software_product_id=self.pk).count()
return safestring.mark_safe("<a href=\"{url}\">{count}</a>".format(
url=reverse_lazy("plugins:netbox_slm:softwareproductinstallation_list") + f"?q={self.name}",
count=count
)) if count else "0"
return (
safestring.mark_safe(
'<a href="{url}">{count}</a>'.format(
url=reverse_lazy("plugins:netbox_slm:softwareproductinstallation_list") + f"?q={self.name}",
count=count,
)
)
if count
else "0"
)
class SoftwareProductVersion(NetBoxModel):
name = models.CharField(max_length=64)
software_product = models.ForeignKey(
to='netbox_slm.SoftwareProduct',
to="netbox_slm.SoftwareProduct",
on_delete=models.PROTECT,
)
@@ -50,33 +52,25 @@ class SoftwareProductVersion(NetBoxModel):
def get_installation_count(self):
count = SoftwareProductInstallation.objects.filter(version_id=self.pk).count()
return safestring.mark_safe("<a href=\"{url}\">{count}</a>".format(
url=reverse_lazy("plugins:netbox_slm:softwareproductinstallation_list") + f"?q={self.name}",
count=count
)) if count else "0"
return (
safestring.mark_safe(
'<a href="{url}">{count}</a>'.format(
url=reverse_lazy("plugins:netbox_slm:softwareproductinstallation_list") + f"?q={self.name}",
count=count,
)
)
if count
else "0"
)
class SoftwareProductInstallation(NetBoxModel):
device = models.ForeignKey(
to='dcim.Device',
on_delete=models.PROTECT,
null=True,
blank=True
)
device = models.ForeignKey(to="dcim.Device", on_delete=models.PROTECT, null=True, blank=True)
virtualmachine = models.ForeignKey(
to='virtualization.VirtualMachine',
on_delete=models.PROTECT,
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,
to="virtualization.VirtualMachine", on_delete=models.PROTECT, 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)
objects = RestrictedQuerySet.as_manager()
@@ -91,7 +85,7 @@ class SoftwareProductInstallation(NetBoxModel):
return self.device or self.virtualmachine
def render_type(self):
return 'device' if self.device else 'virtualmachine'
return "device" if self.device else "virtualmachine"
class SoftwareLicense(NetBoxModel):
@@ -103,21 +97,10 @@ class SoftwareLicense(NetBoxModel):
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
)
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
to="netbox_slm.SoftwareProductInstallation", on_delete=models.PROTECT, null=True, blank=True
)
objects = RestrictedQuerySet.as_manager()
+12 -12
View File
@@ -3,8 +3,8 @@ from utilities.choices import ButtonColorChoices
menu_items = (
PluginMenuItem(
link='plugins:netbox_slm:softwareproduct_list',
link_text='Software Products',
link="plugins:netbox_slm:softwareproduct_list",
link_text="Software Products",
buttons=(
PluginMenuButton(
"plugins:netbox_slm:softwareproduct_add",
@@ -20,11 +20,11 @@ menu_items = (
ButtonColorChoices.CYAN,
permissions=["netbox_slm.add_softwareproduct"],
),
)
),
),
PluginMenuItem(
link='plugins:netbox_slm:softwareproductversion_list',
link_text='Versions',
link="plugins:netbox_slm:softwareproductversion_list",
link_text="Versions",
buttons=(
PluginMenuButton(
"plugins:netbox_slm:softwareproductversion_add",
@@ -40,11 +40,11 @@ menu_items = (
ButtonColorChoices.CYAN,
permissions=["netbox_slm.add_softwareproductversion"],
),
)
),
),
PluginMenuItem(
link='plugins:netbox_slm:softwareproductinstallation_list',
link_text='Installations',
link="plugins:netbox_slm:softwareproductinstallation_list",
link_text="Installations",
buttons=(
PluginMenuButton(
"plugins:netbox_slm:softwareproductinstallation_add",
@@ -60,11 +60,11 @@ menu_items = (
ButtonColorChoices.CYAN,
permissions=["netbox_slm.add_softwareproductinstallation"],
),
)
),
),
PluginMenuItem(
link='plugins:netbox_slm:softwarelicense_list',
link_text='Licenses',
link="plugins:netbox_slm:softwarelicense_list",
link_text="Licenses",
buttons=(
PluginMenuButton(
"plugins:netbox_slm:softwarelicense_add",
@@ -80,6 +80,6 @@ menu_items = (
ButtonColorChoices.CYAN,
permissions=["netbox_slm.add_softwarelicense"],
),
)
),
),
)
+26 -67
View File
@@ -11,15 +11,10 @@ class SoftwareProductTable(NetBoxTable):
pk = ToggleColumn()
name = tables.LinkColumn()
manufacturer = tables.Column(
accessor=Accessor('manufacturer'),
linkify=True
)
installations = tables.Column(accessor='get_installation_count', verbose_name='Installations')
manufacturer = tables.Column(accessor=Accessor("manufacturer"), linkify=True)
installations = tables.Column(accessor="get_installation_count", verbose_name="Installations")
tags = columns.TagColumn(
url_name="plugins:netbox_slm:softwareproduct_list",
)
tags = columns.TagColumn(url_name="plugins:netbox_slm:softwareproduct_list")
class Meta(NetBoxTable.Meta):
model = SoftwareProduct
@@ -47,9 +42,9 @@ class SoftwareProductTable(NetBoxTable):
)
def order_installations(self, queryset, is_descending):
queryset = queryset.annotate(
count=Count('softwareproductinstallation__id')
).order_by(("-" if is_descending else "") + "count")
queryset = queryset.annotate(count=Count("softwareproductinstallation__id")).order_by(
("-" if is_descending else "") + "count"
)
return queryset, True
@@ -57,20 +52,12 @@ class SoftwareProductVersionTable(NetBoxTable):
"""Table for displaying SoftwareProductVersion objects."""
pk = ToggleColumn()
name = tables.LinkColumn(verbose_name='Version')
software_product = tables.Column(
accessor=Accessor('software_product'),
linkify=True
)
manufacturer = tables.Column(
accessor=Accessor('software_product__manufacturer'),
linkify=True
)
installations = tables.Column(accessor='get_installation_count', verbose_name='Installations')
name = tables.LinkColumn(verbose_name="Version")
software_product = tables.Column(accessor=Accessor("software_product"), linkify=True)
manufacturer = tables.Column(accessor=Accessor("software_product__manufacturer"), linkify=True)
installations = tables.Column(accessor="get_installation_count", verbose_name="Installations")
tags = columns.TagColumn(
url_name="plugins:netbox_slm:softwareproductversion_list",
)
tags = columns.TagColumn(url_name="plugins:netbox_slm:softwareproductversion_list")
class Meta(NetBoxTable.Meta):
model = SoftwareProductVersion
@@ -98,9 +85,9 @@ class SoftwareProductVersionTable(NetBoxTable):
)
def order_installations(self, queryset, is_descending):
queryset = queryset.annotate(
count=Count('softwareproductinstallation__id')
).order_by(("-" if is_descending else "") + "count")
queryset = queryset.annotate(count=Count("softwareproductinstallation__id")).order_by(
("-" if is_descending else "") + "count"
)
return queryset, True
@@ -109,31 +96,14 @@ class SoftwareProductInstallationTable(NetBoxTable):
pk = ToggleColumn()
name = tables.LinkColumn()
device = tables.Column(
accessor=Accessor('device'),
linkify=True
)
virtualmachine = tables.Column(
accessor=Accessor('virtualmachine'),
linkify=True
)
platform = tables.Column(
accessor=Accessor('platform'),
linkify=True
)
type = tables.Column(accessor='render_type')
software_product = tables.Column(
accessor=Accessor('software_product'),
linkify=True
)
version = tables.Column(
accessor=Accessor('version'),
linkify=True
)
device = tables.Column(accessor=Accessor("device"), linkify=True)
virtualmachine = tables.Column(accessor=Accessor("virtualmachine"), linkify=True)
platform = tables.Column(accessor=Accessor("platform"), linkify=True)
type = tables.Column(accessor="render_type")
software_product = tables.Column(accessor=Accessor("software_product"), linkify=True)
version = tables.Column(accessor=Accessor("version"), linkify=True)
tags = columns.TagColumn(
url_name="plugins:netbox_slm:softwareproductinstallation_list",
)
tags = columns.TagColumn(url_name="plugins:netbox_slm:softwareproductinstallation_list")
class Meta(NetBoxTable.Meta):
model = SoftwareProductInstallation
@@ -173,23 +143,12 @@ class SoftwareLicenseTable(NetBoxTable):
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
)
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",
)
tags = columns.TagColumn(url_name="plugins:netbox_slm:softwarelicense_list")
class Meta(NetBoxTable.Meta):
model = SoftwareLicense
+4 -2
View File
@@ -17,8 +17,10 @@ class ModelTestCase(TestCase):
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
name=self.l_name,
software_product=self.software_product,
version=self.software_product_version,
installation=self.software_product_installation,
)
def test_model_name(self):
+78 -67
View File
@@ -6,94 +6,105 @@ from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareP
urlpatterns = [
# 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>/delete/", views.SoftwareProductDeleteView.as_view(),
name="softwareproduct_delete"),
path("software-products/<int:pk>/edit/", views.SoftwareProductEditView.as_view(),
name="softwareproduct_edit"),
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>/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>/changelog/",
ObjectChangeLogView.as_view(),
name="softwareproduct_changelog",
kwargs={"model": SoftwareProduct},
),
# 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/delete/", views.SoftwareProductVersionBulkDeleteView.as_view(),
name="softwareproductversion_bulk_delete"),
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/", 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/delete/",
views.SoftwareProductVersionBulkDeleteView.as_view(),
name="softwareproductversion_bulk_delete",
),
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>/changelog/",
ObjectChangeLogView.as_view(),
name="softwareproductversion_changelog",
kwargs={"model": SoftwareProductVersion},
),
# SoftwareProductInstallation
path("installations/", views.SoftwareProductInstallationListView.as_view(),
name='softwareproductinstallation_list'),
path("installations/add/", views.SoftwareProductInstallationEditView.as_view(),
name='softwareproductinstallation_add'),
path("installations/import/", views.SoftwareProductInstallationBulkImportView.as_view(),
name="softwareproductinstallation_import"),
path("installations/edit/", views.SoftwareProductInstallationBulkEditView.as_view(),
name="softwareproductinstallation_bulk_edit"),
path("installations/delete/", views.SoftwareProductInstallationBulkDeleteView.as_view(),
name="softwareproductinstallation_bulk_delete"),
path("installations/<int:pk>/", views.SoftwareProductInstallationView.as_view(),
name="softwareproductinstallation"),
path("installations/<int:pk>/delete/", views.SoftwareProductInstallationDeleteView.as_view(),
name="softwareproductinstallation_delete"),
path("installations/<int:pk>/edit/", views.SoftwareProductInstallationEditView.as_view(),
name="softwareproductinstallation_edit"),
path(
"installations/",
views.SoftwareProductInstallationListView.as_view(),
name="softwareproductinstallation_list",
),
path(
"installations/add/",
views.SoftwareProductInstallationEditView.as_view(),
name="softwareproductinstallation_add",
),
path(
"installations/import/",
views.SoftwareProductInstallationBulkImportView.as_view(),
name="softwareproductinstallation_import",
),
path(
"installations/edit/",
views.SoftwareProductInstallationBulkEditView.as_view(),
name="softwareproductinstallation_bulk_edit",
),
path(
"installations/delete/",
views.SoftwareProductInstallationBulkDeleteView.as_view(),
name="softwareproductinstallation_bulk_delete",
),
path(
"installations/<int:pk>/",
views.SoftwareProductInstallationView.as_view(),
name="softwareproductinstallation",
),
path(
"installations/<int:pk>/delete/",
views.SoftwareProductInstallationDeleteView.as_view(),
name="softwareproductinstallation_delete",
),
path(
"installations/<int:pk>/edit/",
views.SoftwareProductInstallationEditView.as_view(),
name="softwareproductinstallation_edit",
),
path(
"installations/<int:pk>/changelog/",
ObjectChangeLogView.as_view(),
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/", 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(),
+36 -4
View File
@@ -1,4 +1,36 @@
from .software_license import *
from .software_product import *
from .software_product_installation import *
from .software_product_version import *
from .software_license import (
SoftwareLicenseListView,
SoftwareLicenseView,
SoftwareLicenseEditView,
SoftwareLicenseDeleteView,
SoftwareLicenseBulkImportView,
SoftwareLicenseBulkEditView,
SoftwareLicenseBulkDeleteView,
)
from .software_product import (
SoftwareProductListView,
SoftwareProductView,
SoftwareProductEditView,
SoftwareProductDeleteView,
SoftwareProductBulkImportView,
SoftwareProductBulkEditView,
SoftwareProductBulkDeleteView,
)
from .software_product_installation import (
SoftwareProductInstallationListView,
SoftwareProductInstallationView,
SoftwareProductInstallationEditView,
SoftwareProductInstallationDeleteView,
SoftwareProductInstallationBulkImportView,
SoftwareProductInstallationBulkEditView,
SoftwareProductInstallationBulkDeleteView,
)
from .software_product_version import (
SoftwareProductVersionListView,
SoftwareProductVersionView,
SoftwareProductVersionEditView,
SoftwareProductVersionDeleteView,
SoftwareProductVersionBulkImportView,
SoftwareProductVersionBulkEditView,
SoftwareProductVersionBulkDeleteView,
)