Skip to content

Commit

Permalink
Merge branch 'DanSheps:master' into eox_data_sync_from_cisco
Browse files Browse the repository at this point in the history
  • Loading branch information
uck9 authored Oct 13, 2024
2 parents 8ffee5c + 751606e commit 2e2a27b
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
path: 'netbox-lifecycle'

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand Down
2 changes: 1 addition & 1 deletion netbox_lifecycle/forms/model_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class VendorForm(NetBoxModelForm):

class Meta:
model = Vendor
fields = ('name', 'tags')
fields = ('name', 'description', 'comments', 'tags', )


class SupportSKUForm(NetBoxModelForm):
Expand Down
25 changes: 13 additions & 12 deletions netbox_lifecycle/tables/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
class VendorTable(NetBoxTable):
name = tables.Column(
linkify=True,
verbose_name='Name'
verbose_name=_('Name')
)

class Meta(NetBoxTable.Meta):
Expand Down Expand Up @@ -44,7 +44,7 @@ class Meta(NetBoxTable.Meta):
class SupportContractTable(NetBoxTable):
contract_id = tables.Column(
linkify=True,
verbose_name='Contract ID'
verbose_name=_('Contract ID')
)

class Meta(NetBoxTable.Meta):
Expand All @@ -59,51 +59,52 @@ class Meta(NetBoxTable.Meta):

class SupportContractAssignmentTable(NetBoxTable):
contract = tables.Column(
linkify=True
verbose_name=_('Contract'),
linkify=True,
)
sku = tables.Column(
verbose_name='SKU',
verbose_name=_('SKU'),
linkify=True,
)
device_name = tables.Column(
verbose_name='Device Name',
verbose_name=_('Device Name'),
accessor='device__name',
linkify=False,
orderable=True,
)
device_serial = tables.Column(
verbose_name='Serial Number',
verbose_name=_('Serial Number'),
accessor='device__serial',
orderable=True,
)
device_model = tables.Column(
verbose_name='Device Model',
verbose_name=_('Device Model'),
accessor='device__device_type__model',
linkify=False,
orderable=True,
)
device_status = ChoiceFieldColumn(
verbose_name='Device Status',
verbose_name=_('Device Status'),
accessor='device__status',
orderable=True,
)
license_name = tables.Column(
verbose_name='License',
verbose_name=_('License'),
accessor='license__license__name',
linkify=False,
orderable=True,
)
quantity = tables.Column(
verbose_name='License Quantity',
verbose_name=_('License Quantity'),
accessor='license__quantity',
orderable=False,
)
renewal = tables.Column(
verbose_name='Renewal Date',
verbose_name=_('Renewal Date'),
accessor='contract__renewal',
)
end = tables.Column(
verbose_name='End Date',
verbose_name=_('End Date'),
accessor='end_date',
orderable=False,
)
Expand Down
11 changes: 7 additions & 4 deletions netbox_lifecycle/tables/hardware.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.utils.translation import gettext as _
import django_tables2 as tables

from netbox.tables import NetBoxTable
Expand All @@ -12,15 +13,17 @@
class HardwareLifecycleTable(NetBoxTable):
name = tables.Column(
linkify=True,
accessor='name'
accessor='name',
orderable=False,
)

assigned_object = tables.Column(
linkify=True,
verbose_name='Hardware'
verbose_name=_('Hardware'),
orderable=False,
)
assigned_object_count = tables.Column(
verbose_name='Assigned Object Count'
verbose_name=_('Assigned Object Count'),
orderable=False,
)

class Meta(NetBoxTable.Meta):
Expand Down
7 changes: 6 additions & 1 deletion netbox_lifecycle/tables/license.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.utils.translation import gettext as _
import django_tables2 as tables

from netbox.tables import NetBoxTable
Expand All @@ -12,10 +13,11 @@

class LicenseTable(NetBoxTable):
name = tables.Column(
verbose_name=_('Name'),
linkify=True,
verbose_name='Name'
)
manufacturer = tables.Column(
verbose_name=_('Manufacturer'),
linkify=True
)

Expand All @@ -31,12 +33,15 @@ class Meta(NetBoxTable.Meta):

class LicenseAssignmentTable(NetBoxTable):
license = tables.Column(
verbose_name=_('License'),
linkify=True
)
vendor = tables.Column(
verbose_name=_('Vendor'),
linkify=True
)
device = tables.Column(
verbose_name=_('Device'),
linkify=True
)

Expand Down
76 changes: 76 additions & 0 deletions netbox_lifecycle/template_content.py
Original file line number Diff line number Diff line change
@@ -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,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{% load buttons %}
{% load custom_links %}
{% load helpers %}
{% load filters %}
{% load perms %}
{% load plugins %}
{% load tabs %}
Expand Down Expand Up @@ -34,23 +35,23 @@ <h5 class="card-header">Dates</h5>
<table class="table table-hover attr-table">
<tr>
<td>End of Sale</td>
<td>{{ object.end_of_sale }}</td>
<td><span {{ object.end_of_sale|date_badge_class }}>{{ object.end_of_sale }}</span></td>
</tr>
<tr>
<td>End of Maintenance Updates</td>
<td>{{ object.end_of_maintenance }}</td>
<td><span {{ object.end_of_maintenance|date_badge_class }}>{{ object.end_of_maintenance }}</span></td>
</tr>
<tr>
<td>End of Security Updates</td>
<td>{{ object.end_of_security }}</td>
<td><span {{ object.end_of_security|date_badge_class }}>{{ object.end_of_security }}</span></td>
</tr>
<tr>
<td>Last Support Contract Purchase Date</td>
<td>{{ object.last_contract_date }}</td>
<td><span {{ object.last_contract_date|date_badge_class }}>{{ object.last_contract_date }}</span></td>
</tr>
<tr>
<td>End of Support</td>
<td>{{ object.end_of_support }}</td>
<td><span {{ object.end_of_support|date_badge_class }}>{{ object.end_of_support }}</span></td>
</tr>
</table>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

{% load filters %}
{% load helpers %}
{# renders panel on object with lifecycle info assigned to it #}

<div class="card">
<h5 class="card-header">Lifecycle Dates</h5>
{% if lifecycle_info %}
<table class="table table-hover attr-table">
<tr>
<td>End of Sale</td>
<td><span {{ lifecycle_info.end_of_sale|date_badge_class }}>{{ lifecycle_info.end_of_sale }}</span></td>
</tr>
<tr>
<td>End of Maintenance Updates</td>
<td><span {{ lifecycle_info.end_of_maintenance|date_badge_class }}>{{ lifecycle_info.end_of_maintenance }}</span></td>
</tr>
<tr>
<td>End of Security Updates</td>
<td><span {{ lifecycle_info.end_of_security|date_badge_class }}>{{ lifecycle_info.end_of_security }}</span></td>
</tr>
<tr>
<td>Last Support Contract Purchase Date</td>
<td><span {{ lifecycle_info.last_contract_date|date_badge_class }}>{{ lifecycle_info.last_contract_date }}</span></td>
</tr>
<tr>
<td>End of Support</td>
<td><span {{ lifecycle_info.end_of_support|date_badge_class }}>{{ lifecycle_info.end_of_support }}</span></td>
</tr>
</table>
{% else %}
<div class="card-body"><span class="text-muted">No Lifecycle Dates Defined</span></div>
{% endif %}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

{% load filters %}
{% load helpers %}
{# renders panel on object (device) with support contract info assigned to it #}

<div class="card">
<h5 class="card-header">Support Contract</h5>
{% if support_contract %}
<table class="table table-hover attr-table">
<tr>
<th scope="row"><span title="Contract Number">Contract Number</span></th>
<td>{{ support_contract.contract.contract_id|linkify|placeholder }}</td>
</tr>
<tr>
<th scope="row">Support SKU</th>
<td>{{ support_contract.sku }}</td>
</tr>
<tr>
<th scope="row">Start Date</th>
<td>{{ support_contract.contract.start }}</td>
</tr>
<tr>
<th scope="row">End Date</th>
{% if support_contract.end == None %}
<td><span {{ support_contract.contract.end|date_badge_class }}>{{ support_contract.contract.end }}</span></td>
{% else %}
<td><span {{ support_contract.end|date_badge_class }}>{{ support_contract.end }}</span></td>
{% endif %}
</tr>
</table>
{% else %}
<div class="card-body"><span class="text-muted">No Support Contract Assigned<span></div>
{% endif %}
</div>

{% include "netbox_lifecycle/inc/hardware_lifecycle_info.html" %}
Empty file.
27 changes: 27 additions & 0 deletions netbox_lifecycle/templatetags/filters.py
Original file line number Diff line number Diff line change
@@ -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"')

0 comments on commit 2e2a27b

Please sign in to comment.