mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Add dedicated views for organizational models
This commit is contained in:
@ -175,7 +175,7 @@ class CircuitType(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?type={}".format(reverse('circuits:circuit_list'), self.slug)
|
||||
return reverse('circuits:circuittype', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -38,6 +38,7 @@ urlpatterns = [
|
||||
path('circuit-types/import/', views.CircuitTypeBulkImportView.as_view(), name='circuittype_import'),
|
||||
path('circuit-types/edit/', views.CircuitTypeBulkEditView.as_view(), name='circuittype_bulk_edit'),
|
||||
path('circuit-types/delete/', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'),
|
||||
path('circuit-types/<int:pk>/', views.CircuitTypeView.as_view(), name='circuittype'),
|
||||
path('circuit-types/<int:pk>/edit/', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
|
||||
path('circuit-types/<int:pk>/delete/', views.CircuitTypeDeleteView.as_view(), name='circuittype_delete'),
|
||||
path('circuit-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='circuittype_changelog', kwargs={'model': CircuitType}),
|
||||
|
@ -147,6 +147,23 @@ class CircuitTypeListView(generic.ObjectListView):
|
||||
table = tables.CircuitTypeTable
|
||||
|
||||
|
||||
class CircuitTypeView(generic.ObjectView):
|
||||
queryset = CircuitType.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
circuits = Circuit.objects.restrict(request.user, 'view').filter(
|
||||
type=instance
|
||||
)
|
||||
|
||||
circuits_table = tables.CircuitTable(circuits)
|
||||
circuits_table.columns.hide('type')
|
||||
paginate_table(circuits_table, request)
|
||||
|
||||
return {
|
||||
'circuits_table': circuits_table,
|
||||
}
|
||||
|
||||
|
||||
class CircuitTypeEditView(generic.ObjectEditView):
|
||||
queryset = CircuitType.objects.all()
|
||||
model_form = forms.CircuitTypeForm
|
||||
|
@ -65,7 +65,7 @@ class Manufacturer(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?manufacturer={}".format(reverse('dcim:devicetype_list'), self.slug)
|
||||
return reverse('dcim:manufacturer', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
@ -375,6 +375,9 @@ class DeviceRole(OrganizationalModel):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('dcim:devicerole', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
self.name,
|
||||
@ -436,7 +439,7 @@ class Platform(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?platform={}".format(reverse('dcim:device_list'), self.slug)
|
||||
return reverse('dcim:platform', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -67,7 +67,7 @@ class RackRole(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?role={}".format(reverse('dcim:rack_list'), self.slug)
|
||||
return reverse('dcim:rackrole', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -50,6 +50,9 @@ __all__ = (
|
||||
|
||||
class DeviceRoleTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
name = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
device_count = LinkedCountColumn(
|
||||
viewname='dcim:device_list',
|
||||
url_params={'role': 'slug'},
|
||||
@ -76,6 +79,9 @@ class DeviceRoleTable(BaseTable):
|
||||
|
||||
class PlatformTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
name = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
device_count = LinkedCountColumn(
|
||||
viewname='dcim:device_list',
|
||||
url_params={'platform': 'slug'},
|
||||
|
@ -57,6 +57,7 @@ urlpatterns = [
|
||||
path('rack-roles/import/', views.RackRoleBulkImportView.as_view(), name='rackrole_import'),
|
||||
path('rack-roles/edit/', views.RackRoleBulkEditView.as_view(), name='rackrole_bulk_edit'),
|
||||
path('rack-roles/delete/', views.RackRoleBulkDeleteView.as_view(), name='rackrole_bulk_delete'),
|
||||
path('rack-roles/<int:pk>/', views.RackRoleView.as_view(), name='rackrole'),
|
||||
path('rack-roles/<int:pk>/edit/', views.RackRoleEditView.as_view(), name='rackrole_edit'),
|
||||
path('rack-roles/<int:pk>/delete/', views.RackRoleDeleteView.as_view(), name='rackrole_delete'),
|
||||
path('rack-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rackrole_changelog', kwargs={'model': RackRole}),
|
||||
@ -93,6 +94,7 @@ urlpatterns = [
|
||||
path('manufacturers/import/', views.ManufacturerBulkImportView.as_view(), name='manufacturer_import'),
|
||||
path('manufacturers/edit/', views.ManufacturerBulkEditView.as_view(), name='manufacturer_bulk_edit'),
|
||||
path('manufacturers/delete/', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'),
|
||||
path('manufacturers/<int:pk>/', views.ManufacturerView.as_view(), name='manufacturer'),
|
||||
path('manufacturers/<int:pk>/edit/', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
|
||||
path('manufacturers/<int:pk>/delete/', views.ManufacturerDeleteView.as_view(), name='manufacturer_delete'),
|
||||
path('manufacturers/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='manufacturer_changelog', kwargs={'model': Manufacturer}),
|
||||
@ -179,6 +181,7 @@ urlpatterns = [
|
||||
path('device-roles/import/', views.DeviceRoleBulkImportView.as_view(), name='devicerole_import'),
|
||||
path('device-roles/edit/', views.DeviceRoleBulkEditView.as_view(), name='devicerole_bulk_edit'),
|
||||
path('device-roles/delete/', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'),
|
||||
path('device-roles/<int:pk>/', views.DeviceRoleView.as_view(), name='devicerole'),
|
||||
path('device-roles/<int:pk>/edit/', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
|
||||
path('device-roles/<int:pk>/delete/', views.DeviceRoleDeleteView.as_view(), name='devicerole_delete'),
|
||||
path('device-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='devicerole_changelog', kwargs={'model': DeviceRole}),
|
||||
@ -189,6 +192,7 @@ urlpatterns = [
|
||||
path('platforms/import/', views.PlatformBulkImportView.as_view(), name='platform_import'),
|
||||
path('platforms/edit/', views.PlatformBulkEditView.as_view(), name='platform_bulk_edit'),
|
||||
path('platforms/delete/', views.PlatformBulkDeleteView.as_view(), name='platform_bulk_delete'),
|
||||
path('platforms/<int:pk>/', views.PlatformView.as_view(), name='platform'),
|
||||
path('platforms/<int:pk>/edit/', views.PlatformEditView.as_view(), name='platform_edit'),
|
||||
path('platforms/<int:pk>/delete/', views.PlatformDeleteView.as_view(), name='platform_delete'),
|
||||
path('platforms/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='platform_changelog', kwargs={'model': Platform}),
|
||||
|
@ -20,6 +20,7 @@ from secrets.models import Secret
|
||||
from utilities.forms import ConfirmationForm
|
||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||
from utilities.permissions import get_permission_for_model
|
||||
from utilities.tables import paginate_table
|
||||
from utilities.utils import csv_format, count_related
|
||||
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
|
||||
from virtualization.models import VirtualMachine
|
||||
@ -341,6 +342,23 @@ class RackRoleListView(generic.ObjectListView):
|
||||
table = tables.RackRoleTable
|
||||
|
||||
|
||||
class RackRoleView(generic.ObjectView):
|
||||
queryset = RackRole.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
racks = Rack.objects.restrict(request.user, 'view').filter(
|
||||
role=instance
|
||||
)
|
||||
|
||||
racks_table = tables.RackTable(racks)
|
||||
racks_table.columns.hide('role')
|
||||
paginate_table(racks_table, request)
|
||||
|
||||
return {
|
||||
'racks_table': racks_table,
|
||||
}
|
||||
|
||||
|
||||
class RackRoleEditView(generic.ObjectEditView):
|
||||
queryset = RackRole.objects.all()
|
||||
model_form = forms.RackRoleForm
|
||||
@ -567,6 +585,23 @@ class ManufacturerListView(generic.ObjectListView):
|
||||
table = tables.ManufacturerTable
|
||||
|
||||
|
||||
class ManufacturerView(generic.ObjectView):
|
||||
queryset = Manufacturer.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
devicetypes = DeviceType.objects.restrict(request.user, 'view').filter(
|
||||
manufacturer=instance
|
||||
)
|
||||
|
||||
devicetypes_table = tables.DeviceTypeTable(devicetypes)
|
||||
devicetypes_table.columns.hide('manufacturer')
|
||||
paginate_table(devicetypes_table, request)
|
||||
|
||||
return {
|
||||
'devicetypes_table': devicetypes_table,
|
||||
}
|
||||
|
||||
|
||||
class ManufacturerEditView(generic.ObjectEditView):
|
||||
queryset = Manufacturer.objects.all()
|
||||
model_form = forms.ManufacturerForm
|
||||
@ -1017,6 +1052,23 @@ class DeviceRoleListView(generic.ObjectListView):
|
||||
table = tables.DeviceRoleTable
|
||||
|
||||
|
||||
class DeviceRoleView(generic.ObjectView):
|
||||
queryset = DeviceRole.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
devices = Device.objects.restrict(request.user, 'view').filter(
|
||||
device_role=instance
|
||||
)
|
||||
|
||||
devices_table = tables.DeviceTable(devices)
|
||||
devices_table.columns.hide('device_role')
|
||||
paginate_table(devices_table, request)
|
||||
|
||||
return {
|
||||
'devices_table': devices_table,
|
||||
}
|
||||
|
||||
|
||||
class DeviceRoleEditView(generic.ObjectEditView):
|
||||
queryset = DeviceRole.objects.all()
|
||||
model_form = forms.DeviceRoleForm
|
||||
@ -1056,6 +1108,23 @@ class PlatformListView(generic.ObjectListView):
|
||||
table = tables.PlatformTable
|
||||
|
||||
|
||||
class PlatformView(generic.ObjectView):
|
||||
queryset = Platform.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
devices = Device.objects.restrict(request.user, 'view').filter(
|
||||
platform=instance
|
||||
)
|
||||
|
||||
devices_table = tables.DeviceTable(devices)
|
||||
devices_table.columns.hide('platform')
|
||||
paginate_table(devices_table, request)
|
||||
|
||||
return {
|
||||
'devices_table': devices_table,
|
||||
}
|
||||
|
||||
|
||||
class PlatformEditView(generic.ObjectEditView):
|
||||
queryset = Platform.objects.all()
|
||||
model_form = forms.PlatformForm
|
||||
|
@ -66,7 +66,7 @@ class RIR(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?rir={}".format(reverse('ipam:aggregate_list'), self.slug)
|
||||
return reverse('ipam:rir', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
@ -216,6 +216,9 @@ class Role(OrganizationalModel):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('ipam:role', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
self.name,
|
||||
|
@ -70,7 +70,7 @@ class VLANGroup(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('ipam:vlangroup_vlans', args=[self.pk])
|
||||
return reverse('ipam:vlangroup', args=[self.pk])
|
||||
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
@ -224,6 +224,9 @@ class AggregateDetailTable(AggregateTable):
|
||||
|
||||
class RoleTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
name = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
prefix_count = LinkedCountColumn(
|
||||
viewname='ipam:prefix_list',
|
||||
url_params={'role': 'slug'},
|
||||
@ -450,9 +453,8 @@ class VLANTable(BaseTable):
|
||||
site = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
group = tables.LinkColumn(
|
||||
viewname='ipam:vlangroup_vlans',
|
||||
args=[Accessor('group__pk')]
|
||||
group = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
tenant = TenantColumn()
|
||||
status = ChoiceFieldColumn(
|
||||
|
@ -37,6 +37,7 @@ urlpatterns = [
|
||||
path('rirs/import/', views.RIRBulkImportView.as_view(), name='rir_import'),
|
||||
path('rirs/edit/', views.RIRBulkEditView.as_view(), name='rir_bulk_edit'),
|
||||
path('rirs/delete/', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'),
|
||||
path('rirs/<int:pk>/', views.RIRView.as_view(), name='rir'),
|
||||
path('rirs/<int:pk>/edit/', views.RIREditView.as_view(), name='rir_edit'),
|
||||
path('rirs/<int:pk>/delete/', views.RIRDeleteView.as_view(), name='rir_delete'),
|
||||
path('rirs/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rir_changelog', kwargs={'model': RIR}),
|
||||
@ -59,6 +60,7 @@ urlpatterns = [
|
||||
path('roles/import/', views.RoleBulkImportView.as_view(), name='role_import'),
|
||||
path('roles/edit/', views.RoleBulkEditView.as_view(), name='role_bulk_edit'),
|
||||
path('roles/delete/', views.RoleBulkDeleteView.as_view(), name='role_bulk_delete'),
|
||||
path('roles/<int:pk>/', views.RoleView.as_view(), name='role'),
|
||||
path('roles/<int:pk>/edit/', views.RoleEditView.as_view(), name='role_edit'),
|
||||
path('roles/<int:pk>/delete/', views.RoleDeleteView.as_view(), name='role_delete'),
|
||||
path('roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='role_changelog', kwargs={'model': Role}),
|
||||
@ -97,9 +99,9 @@ urlpatterns = [
|
||||
path('vlan-groups/import/', views.VLANGroupBulkImportView.as_view(), name='vlangroup_import'),
|
||||
path('vlan-groups/edit/', views.VLANGroupBulkEditView.as_view(), name='vlangroup_bulk_edit'),
|
||||
path('vlan-groups/delete/', views.VLANGroupBulkDeleteView.as_view(), name='vlangroup_bulk_delete'),
|
||||
path('vlan-groups/<int:pk>/', views.VLANGroupView.as_view(), name='vlangroup'),
|
||||
path('vlan-groups/<int:pk>/edit/', views.VLANGroupEditView.as_view(), name='vlangroup_edit'),
|
||||
path('vlan-groups/<int:pk>/delete/', views.VLANGroupDeleteView.as_view(), name='vlangroup_delete'),
|
||||
path('vlan-groups/<int:pk>/vlans/', views.VLANGroupVLANsView.as_view(), name='vlangroup_vlans'),
|
||||
path('vlan-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='vlangroup_changelog', kwargs={'model': VLANGroup}),
|
||||
|
||||
# VLANs
|
||||
|
@ -148,6 +148,23 @@ class RIRListView(generic.ObjectListView):
|
||||
template_name = 'ipam/rir_list.html'
|
||||
|
||||
|
||||
class RIRView(generic.ObjectView):
|
||||
queryset = RIR.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
aggregates = Aggregate.objects.restrict(request.user, 'view').filter(
|
||||
rir=instance
|
||||
)
|
||||
|
||||
aggregates_table = tables.AggregateTable(aggregates)
|
||||
aggregates_table.columns.hide('rir')
|
||||
paginate_table(aggregates_table, request)
|
||||
|
||||
return {
|
||||
'aggregates_table': aggregates_table,
|
||||
}
|
||||
|
||||
|
||||
class RIREditView(generic.ObjectEditView):
|
||||
queryset = RIR.objects.all()
|
||||
model_form = forms.RIRForm
|
||||
@ -286,6 +303,23 @@ class RoleListView(generic.ObjectListView):
|
||||
table = tables.RoleTable
|
||||
|
||||
|
||||
class RoleView(generic.ObjectView):
|
||||
queryset = Role.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
prefixes = Prefix.objects.restrict(request.user, 'view').filter(
|
||||
role=instance
|
||||
)
|
||||
|
||||
prefixes_table = tables.PrefixTable(prefixes)
|
||||
prefixes_table.columns.hide('role')
|
||||
paginate_table(prefixes_table, request)
|
||||
|
||||
return {
|
||||
'prefixes_table': prefixes_table,
|
||||
}
|
||||
|
||||
|
||||
class RoleEditView(generic.ObjectEditView):
|
||||
queryset = Role.objects.all()
|
||||
model_form = forms.RoleForm
|
||||
@ -633,6 +667,29 @@ class VLANGroupListView(generic.ObjectListView):
|
||||
table = tables.VLANGroupTable
|
||||
|
||||
|
||||
class VLANGroupView(generic.ObjectView):
|
||||
queryset = VLANGroup.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
vlans = VLAN.objects.restrict(request.user, 'view').filter(group=instance).prefetch_related(
|
||||
Prefetch('prefixes', queryset=Prefix.objects.restrict(request.user))
|
||||
)
|
||||
vlans_count = vlans.count()
|
||||
vlans = add_available_vlans(instance, vlans)
|
||||
|
||||
vlans_table = tables.VLANDetailTable(vlans)
|
||||
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
|
||||
vlans_table.columns.show('pk')
|
||||
vlans_table.columns.hide('site')
|
||||
vlans_table.columns.hide('group')
|
||||
paginate_table(vlans_table, request)
|
||||
|
||||
return {
|
||||
'vlans_count': vlans_count,
|
||||
'vlans_table': vlans_table,
|
||||
}
|
||||
|
||||
|
||||
class VLANGroupEditView(generic.ObjectEditView):
|
||||
queryset = VLANGroup.objects.all()
|
||||
model_form = forms.VLANGroupForm
|
||||
@ -666,38 +723,6 @@ class VLANGroupBulkDeleteView(generic.BulkDeleteView):
|
||||
table = tables.VLANGroupTable
|
||||
|
||||
|
||||
class VLANGroupVLANsView(generic.ObjectView):
|
||||
queryset = VLANGroup.objects.all()
|
||||
template_name = 'ipam/vlangroup_vlans.html'
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
vlans = VLAN.objects.restrict(request.user, 'view').filter(group=instance).prefetch_related(
|
||||
Prefetch('prefixes', queryset=Prefix.objects.restrict(request.user))
|
||||
)
|
||||
vlans = add_available_vlans(instance, vlans)
|
||||
|
||||
vlan_table = tables.VLANDetailTable(vlans)
|
||||
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
|
||||
vlan_table.columns.show('pk')
|
||||
vlan_table.columns.hide('site')
|
||||
vlan_table.columns.hide('group')
|
||||
paginate_table(vlan_table, request)
|
||||
|
||||
# Compile permissions list for rendering the object table
|
||||
permissions = {
|
||||
'add': request.user.has_perm('ipam.add_vlan'),
|
||||
'change': request.user.has_perm('ipam.change_vlan'),
|
||||
'delete': request.user.has_perm('ipam.delete_vlan'),
|
||||
}
|
||||
|
||||
return {
|
||||
'first_available_vlan': instance.get_next_available_vid(),
|
||||
'bulk_querystring': f'group_id={instance.pk}',
|
||||
'vlan_table': vlan_table,
|
||||
'permissions': permissions,
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# VLANs
|
||||
#
|
||||
|
@ -263,7 +263,7 @@ class SecretRole(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?role={}".format(reverse('secrets:secret_list'), self.slug)
|
||||
return reverse('secrets:secretrole', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -13,6 +13,7 @@ urlpatterns = [
|
||||
path('secret-roles/import/', views.SecretRoleBulkImportView.as_view(), name='secretrole_import'),
|
||||
path('secret-roles/edit/', views.SecretRoleBulkEditView.as_view(), name='secretrole_bulk_edit'),
|
||||
path('secret-roles/delete/', views.SecretRoleBulkDeleteView.as_view(), name='secretrole_bulk_delete'),
|
||||
path('secret-roles/<int:pk>/', views.SecretRoleView.as_view(), name='secretrole'),
|
||||
path('secret-roles/<int:pk>/edit/', views.SecretRoleEditView.as_view(), name='secretrole_edit'),
|
||||
path('secret-roles/<int:pk>/delete/', views.SecretRoleDeleteView.as_view(), name='secretrole_delete'),
|
||||
path('secret-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='secretrole_changelog', kwargs={'model': SecretRole}),
|
||||
|
@ -7,6 +7,7 @@ from django.utils.html import escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from netbox.views import generic
|
||||
from utilities.tables import paginate_table
|
||||
from utilities.utils import count_related
|
||||
from . import filters, forms, tables
|
||||
from .models import SecretRole, Secret, SessionKey, UserKey
|
||||
@ -33,6 +34,23 @@ class SecretRoleListView(generic.ObjectListView):
|
||||
table = tables.SecretRoleTable
|
||||
|
||||
|
||||
class SecretRoleView(generic.ObjectView):
|
||||
queryset = SecretRole.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
secrets = Secret.objects.restrict(request.user, 'view').filter(
|
||||
role=instance
|
||||
)
|
||||
|
||||
secrets_table = tables.SecretTable(secrets)
|
||||
secrets_table.columns.hide('role')
|
||||
paginate_table(secrets_table, request)
|
||||
|
||||
return {
|
||||
'secrets_table': secrets_table,
|
||||
}
|
||||
|
||||
|
||||
class SecretRoleEditView(generic.ObjectEditView):
|
||||
queryset = SecretRole.objects.all()
|
||||
model_form = forms.SecretRoleForm
|
||||
|
60
netbox/templates/circuits/circuittype.html
Normal file
60
netbox/templates/circuits/circuittype.html
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'circuits:circuittype_list' %}">Circuit Types</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Circuit Type</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Circuits</td>
|
||||
<td>
|
||||
<a href="{% url 'circuits:circuit_list' %}?type_id={{ object.pk }}">{{ circuits_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Circuits</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=circuits_table %}
|
||||
{% if perms.circuits.add_circuit %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'circuits:circuit_add' %}?type={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add circuit
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=circuits_table.paginator page=circuits_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
76
netbox/templates/dcim/devicerole.html
Normal file
76
netbox/templates/dcim/devicerole.html
Normal file
@ -0,0 +1,76 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'dcim:devicerole_list' %}">Device Roles</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Device Role</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Color</td>
|
||||
<td>
|
||||
<span class="label color-block" style="background-color: #{{ object.color }}"> </span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>VM Role</td>
|
||||
<td>
|
||||
{% if object.vm_role %}
|
||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
||||
{% else %}
|
||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Devices</td>
|
||||
<td>
|
||||
<a href="{% url 'dcim:device_list' %}?role_id={{ object.pk }}">{{ devices_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Devices</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=devices_table %}
|
||||
{% if perms.dcim.add_device %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'dcim:device_add' %}?device_role={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add device
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=devices_table.paginator page=devices_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
60
netbox/templates/dcim/manufacturer.html
Normal file
60
netbox/templates/dcim/manufacturer.html
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'dcim:manufacturer_list' %}">Manufacturers</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Manufacturer</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Device types</td>
|
||||
<td>
|
||||
<a href="{% url 'dcim:devicetype_list' %}?manufacturer_id={{ object.pk }}">{{ devicetypes_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Device Types</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=devicetypes_table %}
|
||||
{% if perms.dcim.add_devicetype %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'dcim:devicetype_add' %}?manufacturer={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add device type
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=devicetypes_table.paginator page=devicetypes_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
68
netbox/templates/dcim/platform.html
Normal file
68
netbox/templates/dcim/platform.html
Normal file
@ -0,0 +1,68 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'dcim:platform_list' %}">Platforms</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Platform</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NAPALM Driver</td>
|
||||
<td>{{ object.napalm_driver }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NAPALM Arguments</td>
|
||||
<td><pre>{{ object.napalm_args }}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Devices</td>
|
||||
<td>
|
||||
<a href="{% url 'dcim:device_list' %}?platform_id={{ object.pk }}">{{ devices_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Devices</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=devices_table %}
|
||||
{% if perms.dcim.add_device %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'dcim:device_add' %}?device_role={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add device
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=devices_table.paginator page=devices_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
66
netbox/templates/dcim/rackrole.html
Normal file
66
netbox/templates/dcim/rackrole.html
Normal file
@ -0,0 +1,66 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'dcim:rackrole_list' %}">Rack Roles</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Rack Role</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Color</td>
|
||||
<td>
|
||||
<span class="label color-block" style="background-color: #{{ object.color }}"> </span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Racks</td>
|
||||
<td>
|
||||
<a href="{% url 'dcim:rack_list' %}?role_id={{ object.pk }}">{{ racks_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Racks</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=racks_table %}
|
||||
{% if perms.dcim.add_rack %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'dcim:rack_add' %}?role={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add rack
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=racks_table.paginator page=racks_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
70
netbox/templates/ipam/rir.html
Normal file
70
netbox/templates/ipam/rir.html
Normal file
@ -0,0 +1,70 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'ipam:rir_list' %}">RIRs</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>RIR</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Private</td>
|
||||
<td>
|
||||
{% if object.is_private %}
|
||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
||||
{% else %}
|
||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aggregates</td>
|
||||
<td>
|
||||
<a href="{% url 'ipam:aggregate_list' %}?rir_id={{ object.pk }}">{{ aggregates_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Aggregates</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=aggregates_table %}
|
||||
{% if perms.ipam.add_aggregate %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'ipam:aggregate_add' %}?rir={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add aggregate
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=aggregates_table.paginator page=aggregates_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
64
netbox/templates/ipam/role.html
Normal file
64
netbox/templates/ipam/role.html
Normal file
@ -0,0 +1,64 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'ipam:role_list' %}">Roles</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Role</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Weight</td>
|
||||
<td>{{ object.weight }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Prefixes</td>
|
||||
<td>
|
||||
<a href="{% url 'ipam:prefix_list' %}?role_id={{ object.pk }}">{{ prefixes_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Prefixes</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=prefixes_table %}
|
||||
{% if perms.ipam.add_prefix %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'ipam:prefix_add' %}?role={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add prefix
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=prefixes_table.paginator page=prefixes_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
72
netbox/templates/ipam/vlangroup.html
Normal file
72
netbox/templates/ipam/vlangroup.html
Normal file
@ -0,0 +1,72 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'ipam:vlangroup_list' %}">VLAN Groups</a></li>
|
||||
{% if object.scope %}
|
||||
<li><a href="{{ object.scope.get_absolute_url }}">{{ object.scope }}</a></li>
|
||||
{% endif %}
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>VLAN Group</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Scope</td>
|
||||
<td>
|
||||
{% if object.scope %}
|
||||
<a href="{{ object.scope.get_absolute_url }}">{{ object.scope }}</a>
|
||||
{% else %}
|
||||
<span class="text-muted">—</span>
|
||||
{% endif %}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>VLANs</td>
|
||||
<td>
|
||||
<a href="{% url 'ipam:vlan_list' %}?group_id={{ object.pk }}">{{ vlans_count }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>VLANs</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=vlans_table %}
|
||||
{% if perms.ipam.add_vlan %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'ipam:vlan_add' %}?role={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add VLAN
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=vlans_table.paginator page=vlans_table.page %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -1,24 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{{ object }} - VLANs{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row noprint">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{% url 'ipam:vlangroup_list' %}">VLAN Groups</a></li>
|
||||
{% if object.site %}
|
||||
<li><a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a></li>
|
||||
{% endif %}
|
||||
<li>{{ object }}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'ipam/inc/vlangroup_header.html' %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{% include 'utilities/obj_table.html' with table=vlan_table table_template='panel_table.html' heading='VLANs' bulk_edit_url='ipam:vlan_bulk_edit' bulk_delete_url='ipam:vlan_bulk_delete' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
60
netbox/templates/secrets/secretrole.html
Normal file
60
netbox/templates/secrets/secretrole.html
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'secrets:secretrole_list' %}">Secret Roles</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Secret Role</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Secrets</td>
|
||||
<td>
|
||||
<a href="{% url 'secrets:secret_list' %}?role_id={{ object.pk }}">{{ secrets_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Secrets</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=secrets_table %}
|
||||
{% if perms.secrets.add_secret %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'secrets:secret_add' %}?role={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add secret
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=secrets_table.paginator page=secrets_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
60
netbox/templates/virtualization/clustergroup.html
Normal file
60
netbox/templates/virtualization/clustergroup.html
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'virtualization:clustertype_list' %}">Cluster Groups</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Cluster Group</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Clusters</td>
|
||||
<td>
|
||||
<a href="{% url 'virtualization:cluster_list' %}?group_id={{ object.pk }}">{{ clusters_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Clusters</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=clusters_table %}
|
||||
{% if perms.virtualization.add_cluster %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'virtualization:cluster_add' %}?type={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add cluster
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=clusters_table.paginator page=clusters_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
60
netbox/templates/virtualization/clustertype.html
Normal file
60
netbox/templates/virtualization/clustertype.html
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends 'generic/object.html' %}
|
||||
{% load helpers %}
|
||||
{% load plugins %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{% url 'virtualization:clustertype_list' %}">Cluster Types</a></li>
|
||||
<li>{{ object }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Cluster Type</strong>
|
||||
</div>
|
||||
<table class="table table-hover panel-body attr-table">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ object.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Clusters</td>
|
||||
<td>
|
||||
<a href="{% url 'virtualization:cluster_list' %}?type_id={{ object.pk }}">{{ clusters_table.rows|length }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% plugin_left_page object %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% include 'inc/custom_fields_panel.html' %}
|
||||
{% plugin_right_page object %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Clusters</strong>
|
||||
</div>
|
||||
{% include 'inc/table.html' with table=clusters_table %}
|
||||
{% if perms.virtualization.add_cluster %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
<a href="{% url 'virtualization:cluster_add' %}?type={{ object.pk }}" class="btn btn-xs btn-primary">
|
||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add cluster
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=clusters_table.paginator page=clusters_table.page %}
|
||||
{% plugin_full_width_page object %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -59,7 +59,7 @@ class ClusterType(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?type={}".format(reverse('virtualization:cluster_list'), self.slug)
|
||||
return reverse('virtualization:clustertype', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
@ -102,7 +102,7 @@ class ClusterGroup(OrganizationalModel):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?group={}".format(reverse('virtualization:cluster_list'), self.slug)
|
||||
return reverse('virtualization:clustergroup', args=[self.pk])
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
@ -14,6 +14,7 @@ urlpatterns = [
|
||||
path('cluster-types/import/', views.ClusterTypeBulkImportView.as_view(), name='clustertype_import'),
|
||||
path('cluster-types/edit/', views.ClusterTypeBulkEditView.as_view(), name='clustertype_bulk_edit'),
|
||||
path('cluster-types/delete/', views.ClusterTypeBulkDeleteView.as_view(), name='clustertype_bulk_delete'),
|
||||
path('cluster-types/<int:pk>/', views.ClusterTypeView.as_view(), name='clustertype'),
|
||||
path('cluster-types/<int:pk>/edit/', views.ClusterTypeEditView.as_view(), name='clustertype_edit'),
|
||||
path('cluster-types/<int:pk>/delete/', views.ClusterTypeDeleteView.as_view(), name='clustertype_delete'),
|
||||
path('cluster-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='clustertype_changelog', kwargs={'model': ClusterType}),
|
||||
@ -24,6 +25,7 @@ urlpatterns = [
|
||||
path('cluster-groups/import/', views.ClusterGroupBulkImportView.as_view(), name='clustergroup_import'),
|
||||
path('cluster-groups/edit/', views.ClusterGroupBulkEditView.as_view(), name='clustergroup_bulk_edit'),
|
||||
path('cluster-groups/delete/', views.ClusterGroupBulkDeleteView.as_view(), name='clustergroup_bulk_delete'),
|
||||
path('cluster-groups/<int:pk>/', views.ClusterGroupView.as_view(), name='clustergroup'),
|
||||
path('cluster-groups/<int:pk>/edit/', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'),
|
||||
path('cluster-groups/<int:pk>/delete/', views.ClusterGroupDeleteView.as_view(), name='clustergroup_delete'),
|
||||
path('cluster-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='clustergroup_changelog', kwargs={'model': ClusterGroup}),
|
||||
|
@ -11,6 +11,7 @@ from ipam.models import IPAddress, Service
|
||||
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
|
||||
from netbox.views import generic
|
||||
from secrets.models import Secret
|
||||
from utilities.tables import paginate_table
|
||||
from utilities.utils import count_related
|
||||
from . import filters, forms, tables
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
@ -27,6 +28,23 @@ class ClusterTypeListView(generic.ObjectListView):
|
||||
table = tables.ClusterTypeTable
|
||||
|
||||
|
||||
class ClusterTypeView(generic.ObjectView):
|
||||
queryset = ClusterType.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
clusters = Cluster.objects.restrict(request.user, 'view').filter(
|
||||
type=instance
|
||||
)
|
||||
|
||||
clusters_table = tables.ClusterTable(clusters)
|
||||
clusters_table.columns.hide('type')
|
||||
paginate_table(clusters_table, request)
|
||||
|
||||
return {
|
||||
'clusters_table': clusters_table,
|
||||
}
|
||||
|
||||
|
||||
class ClusterTypeEditView(generic.ObjectEditView):
|
||||
queryset = ClusterType.objects.all()
|
||||
model_form = forms.ClusterTypeForm
|
||||
@ -69,6 +87,23 @@ class ClusterGroupListView(generic.ObjectListView):
|
||||
table = tables.ClusterGroupTable
|
||||
|
||||
|
||||
class ClusterGroupView(generic.ObjectView):
|
||||
queryset = ClusterGroup.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
clusters = Cluster.objects.restrict(request.user, 'view').filter(
|
||||
group=instance
|
||||
)
|
||||
|
||||
clusters_table = tables.ClusterTable(clusters)
|
||||
clusters_table.columns.hide('group')
|
||||
paginate_table(clusters_table, request)
|
||||
|
||||
return {
|
||||
'clusters_table': clusters_table,
|
||||
}
|
||||
|
||||
|
||||
class ClusterGroupEditView(generic.ObjectEditView):
|
||||
queryset = ClusterGroup.objects.all()
|
||||
model_form = forms.ClusterGroupForm
|
||||
|
Reference in New Issue
Block a user