diff --git a/netbox_lifecycle/template_content.py b/netbox_lifecycle/template_content.py new file mode 100644 index 0000000..44837c7 --- /dev/null +++ b/netbox_lifecycle/template_content.py @@ -0,0 +1,76 @@ + +from django.contrib.contenttypes.models import ContentType +from django.template import Template +from netbox.plugins import PluginTemplateExtension + +from .models import hardware, contract + + +class DeviceHardwareInfoExtension(PluginTemplateExtension): + def right_page(self): + object = self.context.get('object') + support_contract = contract.SupportContractAssignment.objects.filter(device_id=self.context['object'].id).first() + match self.kind: + case "device": + content_type = ContentType.objects.get(app_label="dcim", model="devicetype") + lifecycle_info = hardware.HardwareLifecycle.objects.filter(assigned_object_id=self.context['object'].device_type_id, + assigned_object_type_id=content_type.id).first() + case "module": + content_type = ContentType.objects.get(app_label="dcim", model="moduletype") + lifecycle_info = hardware.HardwareLifecycle.objects.filter(assigned_object_id=self.context['object'].module_type_id, + assigned_object_type_id=content_type.id).first() + case "devicetype" | "moduletype": + content_type = ContentType.objects.get(app_label="dcim", model=self.kind) + lifecycle_info = hardware.HardwareLifecycle.objects.filter(assigned_object_id=self.context['object'].id, + assigned_object_type_id=content_type.id).first() + context = {'support_contract': support_contract, 'lifecycle_info': lifecycle_info} + return self.render('netbox_lifecycle/inc/support_contract_info.html', extra_context=context) + + +class TypeInfoExtension(PluginTemplateExtension): + def right_page(self): + object = self.context.get('object') + match self.kind: + case "device": + content_type = ContentType.objects.get(app_label="dcim", model="devicetype") + lifecycle_info = hardware.HardwareLifecycle.objects.filter(assigned_object_id=self.context['object'].device_type_id, + assigned_object_type_id=content_type.id).first() + case "module": + content_type = ContentType.objects.get(app_label="dcim", model="moduletype") + lifecycle_info = hardware.HardwareLifecycle.objects.filter(assigned_object_id=self.context['object'].module_type_id, + assigned_object_type_id=content_type.id).first() + case "devicetype" | "moduletype": + content_type = ContentType.objects.get(app_label="dcim", model=self.kind) + lifecycle_info = hardware.HardwareLifecycle.objects.filter(assigned_object_id=self.context['object'].id, + assigned_object_type_id=content_type.id).first() + + context = {'lifecycle_info': lifecycle_info} + return self.render('netbox_lifecycle/inc/hardware_lifecycle_info.html', extra_context=context) + + +class DeviceHardwareLifecycleInfo(DeviceHardwareInfoExtension): + model = 'dcim.device' + kind = 'device' + + +class ModuleHardwareLifecycleInfo(TypeInfoExtension): + model = 'dcim.module' + kind = 'module' + + +class DeviceTypeHardwareLifecycleInfo(TypeInfoExtension): + model = 'dcim.devicetype' + kind = 'devicetype' + + +class ModuleTypeHardwareLifecycleInfo(TypeInfoExtension): + model = 'dcim.moduletype' + kind = 'moduletype' + + +template_extensions = ( + DeviceHardwareLifecycleInfo, + ModuleHardwareLifecycleInfo, + DeviceTypeHardwareLifecycleInfo, + ModuleTypeHardwareLifecycleInfo, +) diff --git a/netbox_lifecycle/templates/netbox_lifecycle/hardwarelifecycle.html b/netbox_lifecycle/templates/netbox_lifecycle/hardwarelifecycle.html index 862fd84..197ea46 100644 --- a/netbox_lifecycle/templates/netbox_lifecycle/hardwarelifecycle.html +++ b/netbox_lifecycle/templates/netbox_lifecycle/hardwarelifecycle.html @@ -2,6 +2,7 @@ {% load buttons %} {% load custom_links %} {% load helpers %} +{% load filters %} {% load perms %} {% load plugins %} {% load tabs %} @@ -34,23 +35,23 @@
Dates
- + - + - + - + - +
End of Sale{{ object.end_of_sale }}{{ object.end_of_sale }}
End of Maintenance Updates{{ object.end_of_maintenance }}{{ object.end_of_maintenance }}
End of Security Updates{{ object.end_of_security }}{{ object.end_of_security }}
Last Support Contract Purchase Date{{ object.last_contract_date }}{{ object.last_contract_date }}
End of Support{{ object.end_of_support }}{{ object.end_of_support }}
diff --git a/netbox_lifecycle/templates/netbox_lifecycle/inc/hardware_lifecycle_info.html b/netbox_lifecycle/templates/netbox_lifecycle/inc/hardware_lifecycle_info.html new file mode 100644 index 0000000..a639d88 --- /dev/null +++ b/netbox_lifecycle/templates/netbox_lifecycle/inc/hardware_lifecycle_info.html @@ -0,0 +1,34 @@ + +{% load filters %} +{% load helpers %} +{# renders panel on object with lifecycle info assigned to it #} + +
+
Lifecycle Dates
+ {% if lifecycle_info %} + + + + + + + + + + + + + + + + + + + + + +
End of Sale{{ lifecycle_info.end_of_sale }}
End of Maintenance Updates{{ lifecycle_info.end_of_maintenance }}
End of Security Updates{{ lifecycle_info.end_of_security }}
Last Support Contract Purchase Date{{ lifecycle_info.last_contract_date }}
End of Support{{ lifecycle_info.end_of_support }}
+ {% else %} +
No Lifecycle Dates Defined
+ {% endif %} +
diff --git a/netbox_lifecycle/templates/netbox_lifecycle/inc/support_contract_info.html b/netbox_lifecycle/templates/netbox_lifecycle/inc/support_contract_info.html new file mode 100644 index 0000000..3919229 --- /dev/null +++ b/netbox_lifecycle/templates/netbox_lifecycle/inc/support_contract_info.html @@ -0,0 +1,36 @@ + +{% load filters %} +{% load helpers %} +{# renders panel on object (device) with support contract info assigned to it #} + +
+
Support Contract
+ {% if support_contract %} + + + + + + + + + + + + + + + + {% if support_contract.end == None %} + + {% else %} + + {% endif %} + +
Contract Number{{ support_contract.contract.contract_id|linkify|placeholder }}
Support SKU{{ support_contract.sku }}
Start Date{{ support_contract.contract.start }}
End Date{{ support_contract.contract.end }}{{ support_contract.end }}
+ {% else %} +
No Support Contract Assigned
+ {% endif %} +
+ +{% include "netbox_lifecycle/inc/hardware_lifecycle_info.html" %} diff --git a/netbox_lifecycle/templatetags/__init__.py b/netbox_lifecycle/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/netbox_lifecycle/templatetags/filters.py b/netbox_lifecycle/templatetags/filters.py new file mode 100644 index 0000000..7efb587 --- /dev/null +++ b/netbox_lifecycle/templatetags/filters.py @@ -0,0 +1,27 @@ +from datetime import datetime, date +from dateutil.relativedelta import relativedelta +from django import template +from django.utils.safestring import mark_safe + +register = template.Library() + + +def is_expired(value): + return value < datetime.now().date() + + +def expires_within_six_months(value): + return value < (date.today() + relativedelta(months=+6)) + + +@register.filter(is_safe=True) +def date_badge_class(value): + if not value: + return + + if is_expired(value): + return mark_safe('class="badge text-bg-danger"') + elif expires_within_six_months(value): + return mark_safe('class="badge text-bg-warning"') + else: + return mark_safe('class="badge text-bg-success"')