Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display matching ValidatedSoftware objects on DeviceType page #194

Merged
merged 1 commit into from Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion nautobot_device_lifecycle_mgmt/models.py
Expand Up @@ -9,7 +9,7 @@
from nautobot.extras.utils import extras_features
from nautobot.extras.models.statuses import StatusField
from nautobot.core.models.generics import PrimaryModel, OrganizationalModel
from nautobot.dcim.models import Device, InventoryItem
from nautobot.dcim.models import Device, DeviceType, InventoryItem
from nautobot.utilities.querysets import RestrictedQuerySet

from nautobot_device_lifecycle_mgmt import choices
Expand Down Expand Up @@ -335,6 +335,8 @@ def get_for_object(self, obj):
qs = DeviceValidatedSoftwareFilter(qs=self, item_obj=obj).filter_qs()
elif isinstance(obj, InventoryItem):
qs = InventoryItemValidatedSoftwareFilter(qs=self, item_obj=obj).filter_qs()
elif isinstance(obj, DeviceType):
qs = ValidatedSoftwareLCM.objects.filter(device_types=obj)
else:
qs = self

Expand Down
37 changes: 36 additions & 1 deletion nautobot_device_lifecycle_mgmt/template_content.py
Expand Up @@ -5,11 +5,12 @@

from nautobot.extras.plugins import PluginTemplateExtension
from nautobot.dcim.models import InventoryItem
from .models import HardwareLCM
from .models import HardwareLCM, ValidatedSoftwareLCM
from .software import (
DeviceSoftware,
InventoryItemSoftware,
)
from .tables import ValidatedSoftwareLCMTable


class DeviceTypeHWLCM(PluginTemplateExtension, metaclass=ABCMeta):
Expand All @@ -27,6 +28,39 @@ def right_page(self):
)


class DeviceTypeValidatedSoftwareLCM(
PluginTemplateExtension,
): # pylint: disable=abstract-method
"""Class to add table for ValidatedSoftwareLCM related to device type."""

model = "dcim.devicetype"

def __init__(self, context):
"""Init setting up the DeviceTypeValidatedSoftwareLCM object."""
super().__init__(context)
self.device_type_validated_software = ValidatedSoftwareLCM.objects.get_for_object(self.context["object"])
self.validated_software_table = ValidatedSoftwareLCMTable(
list(self.device_type_validated_software),
orderable=False,
exclude=(
"software",
"start",
"actions",
),
)

def right_page(self):
"""Display table on right side of page."""
extra_context = {
"validsoft_table": self.validated_software_table,
}

return self.render(
"nautobot_device_lifecycle_mgmt/inc/software_and_validatedsoftware_info.html",
extra_context=extra_context,
)


class DeviceHWLCM(PluginTemplateExtension, metaclass=ABCMeta):
"""Class to add table for DeviceHWLCM related to device type."""

Expand Down Expand Up @@ -120,6 +154,7 @@ def right_page(self):

template_extensions = [
DeviceTypeHWLCM,
DeviceTypeValidatedSoftwareLCM,
DeviceHWLCM,
InventoryItemHWLCM,
DeviceSoftwareLCMAndValidatedSoftwareLCM,
Expand Down
6 changes: 3 additions & 3 deletions nautobot_device_lifecycle_mgmt/tests/conftest.py
Expand Up @@ -10,9 +10,9 @@ def create_devices():
"""Create devices for tests."""
device_platform, _ = Platform.objects.get_or_create(name="Cisco IOS", slug="cisco_ios")
manufacturer, _ = Manufacturer.objects.get_or_create(slug="cisco")
device_type = DeviceType.objects.create(manufacturer=manufacturer, model="6509-E", slug="6509-e")
device_role = DeviceRole.objects.create(name="Core Switch", slug="core-switch")
site = Site.objects.create(name="Test 1", slug="test-1")
device_type, _ = DeviceType.objects.get_or_create(manufacturer=manufacturer, model="6509-E", slug="6509-e")
device_role, _ = DeviceRole.objects.get_or_create(name="Core Switch", slug="core-switch")
site, _ = Site.objects.get_or_create(name="Test 1", slug="test-1")
status_active = Status.objects.get(slug="active")

return (
Expand Down
61 changes: 60 additions & 1 deletion nautobot_device_lifecycle_mgmt/tests/test_model.py
Expand Up @@ -180,7 +180,7 @@ def test_create_softwarelcm_all(self):
self.assertEqual(str(softwarelcm_full), f"{self.device_platform.name} - {softwarelcm_full.version}")


class ValidatedSoftwareLCMTestCase(TestCase):
class ValidatedSoftwareLCMTestCase(TestCase): # pylint: disable=too-many-instance-attributes
"""Tests for the ValidatedSoftwareLCM model."""

def setUp(self):
Expand All @@ -195,6 +195,8 @@ def setUp(self):
self.device_type_1 = DeviceType.objects.create(manufacturer=manufacturer, model="ASR-1000", slug="asr-1000")
self.device_type_2 = DeviceType.objects.create(manufacturer=manufacturer, model="CAT-3750", slug="cat-3750")
self.content_type_devicetype = ContentType.objects.get(app_label="dcim", model="devicetype")
self.device_1, self.device_2 = create_devices()[:2]
self.inventoryitem_1, self.inventoryitem_2 = create_inventory_items()[:2]

def test_create_validatedsoftwarelcm_required_only(self):
"""Successfully create ValidatedSoftwareLCM with required fields only."""
Expand Down Expand Up @@ -268,6 +270,63 @@ def test_validatedsoftwarelcm_valid_property(self):
self.assertEqual(validatedsoftwarelcm_start_only.valid, True)
self.assertEqual(validatedsoftwarelcm_start_end.valid, True)

def test_get_for_object_device(self):
validatedsoftwarelcm_1 = ValidatedSoftwareLCM(
software=self.software,
start=date(2019, 1, 10),
)
validatedsoftwarelcm_1.devices.set([self.device_1])
validatedsoftwarelcm_1.save()

validatedsoftwarelcm_2 = ValidatedSoftwareLCM(
software=self.software,
start=date(2018, 1, 10),
)
validatedsoftwarelcm_2.devices.set([self.device_2])
validatedsoftwarelcm_2.save()

validated_software_for_device = ValidatedSoftwareLCM.objects.get_for_object(self.device_1)
self.assertEqual(validated_software_for_device.count(), 1)
self.assertTrue(self.device_1 in validated_software_for_device.first().devices.all())

def test_get_for_object_devicetype(self):
validatedsoftwarelcm_1 = ValidatedSoftwareLCM(
software=self.software,
start=date(2019, 1, 10),
)
validatedsoftwarelcm_1.device_types.set([self.device_type_1])
validatedsoftwarelcm_1.save()

validatedsoftwarelcm_2 = ValidatedSoftwareLCM(
software=self.software,
start=date(2018, 1, 10),
)
validatedsoftwarelcm_2.device_types.set([self.device_type_2])
validatedsoftwarelcm_2.save()

validated_software_for_device_type = ValidatedSoftwareLCM.objects.get_for_object(self.device_type_1)
self.assertEqual(validated_software_for_device_type.count(), 1)
self.assertTrue(self.device_type_1 in validated_software_for_device_type.first().device_types.all())

def test_get_for_object_inventoryitem(self):
validatedsoftwarelcm_1 = ValidatedSoftwareLCM(
software=self.software,
start=date(2019, 1, 10),
)
validatedsoftwarelcm_1.inventory_items.set([self.inventoryitem_1])
validatedsoftwarelcm_1.save()

validatedsoftwarelcm_2 = ValidatedSoftwareLCM(
software=self.software,
start=date(2018, 1, 10),
)
validatedsoftwarelcm_2.inventory_items.set([self.inventoryitem_2])
validatedsoftwarelcm_2.save()

validated_software_for_inventoryitem = ValidatedSoftwareLCM.objects.get_for_object(self.inventoryitem_1)
self.assertEqual(validated_software_for_inventoryitem.count(), 1)
self.assertTrue(self.inventoryitem_1 in validated_software_for_inventoryitem.first().inventory_items.all())


class DeviceSoftwareValidationResultTestCase(TestCase): # pylint: disable=too-many-instance-attributes
"""Tests for the DeviceSoftwareValidationResult model."""
Expand Down