Added changelog views

This commit is contained in:
Jeremy Stretch 2018-06-14 16:15:14 -04:00
parent 21c4085c51
commit 3c2e0b0b17
26 changed files with 790 additions and 507 deletions

View File

@ -2,7 +2,9 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from extras.views import ChangeLogView
from . import views from . import views
from .models import Circuit, CircuitType, Provider
app_name = 'circuits' app_name = 'circuits'
urlpatterns = [ urlpatterns = [
@ -16,6 +18,7 @@ urlpatterns = [
url(r'^providers/(?P<slug>[\w-]+)/$', views.ProviderView.as_view(), name='provider'), url(r'^providers/(?P<slug>[\w-]+)/$', views.ProviderView.as_view(), name='provider'),
url(r'^providers/(?P<slug>[\w-]+)/edit/$', views.ProviderEditView.as_view(), name='provider_edit'), url(r'^providers/(?P<slug>[\w-]+)/edit/$', views.ProviderEditView.as_view(), name='provider_edit'),
url(r'^providers/(?P<slug>[\w-]+)/delete/$', views.ProviderDeleteView.as_view(), name='provider_delete'), url(r'^providers/(?P<slug>[\w-]+)/delete/$', views.ProviderDeleteView.as_view(), name='provider_delete'),
url(r'^providers/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='provider_changelog', kwargs={'model': Provider}),
# Circuit types # Circuit types
url(r'^circuit-types/$', views.CircuitTypeListView.as_view(), name='circuittype_list'), url(r'^circuit-types/$', views.CircuitTypeListView.as_view(), name='circuittype_list'),
@ -23,6 +26,7 @@ urlpatterns = [
url(r'^circuit-types/import/$', views.CircuitTypeBulkImportView.as_view(), name='circuittype_import'), url(r'^circuit-types/import/$', views.CircuitTypeBulkImportView.as_view(), name='circuittype_import'),
url(r'^circuit-types/delete/$', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'), url(r'^circuit-types/delete/$', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'),
url(r'^circuit-types/(?P<slug>[\w-]+)/edit/$', views.CircuitTypeEditView.as_view(), name='circuittype_edit'), url(r'^circuit-types/(?P<slug>[\w-]+)/edit/$', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
url(r'^circuit-types/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='circuittype_changelog', kwargs={'model': CircuitType}),
# Circuits # Circuits
url(r'^circuits/$', views.CircuitListView.as_view(), name='circuit_list'), url(r'^circuits/$', views.CircuitListView.as_view(), name='circuit_list'),
@ -33,6 +37,7 @@ urlpatterns = [
url(r'^circuits/(?P<pk>\d+)/$', views.CircuitView.as_view(), name='circuit'), url(r'^circuits/(?P<pk>\d+)/$', views.CircuitView.as_view(), name='circuit'),
url(r'^circuits/(?P<pk>\d+)/edit/$', views.CircuitEditView.as_view(), name='circuit_edit'), url(r'^circuits/(?P<pk>\d+)/edit/$', views.CircuitEditView.as_view(), name='circuit_edit'),
url(r'^circuits/(?P<pk>\d+)/delete/$', views.CircuitDeleteView.as_view(), name='circuit_delete'), url(r'^circuits/(?P<pk>\d+)/delete/$', views.CircuitDeleteView.as_view(), name='circuit_delete'),
url(r'^circuits/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='circuit_changelog', kwargs={'model': Circuit}),
url(r'^circuits/(?P<pk>\d+)/terminations/swap/$', views.circuit_terminations_swap, name='circuit_terminations_swap'), url(r'^circuits/(?P<pk>\d+)/terminations/swap/$', views.circuit_terminations_swap, name='circuit_terminations_swap'),
# Circuit terminations # Circuit terminations

View File

@ -2,11 +2,14 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from extras.views import ImageAttachmentEditView from extras.views import ChangeLogView, ImageAttachmentEditView
from ipam.views import ServiceCreateView from ipam.views import ServiceCreateView
from secrets.views import secret_add from secrets.views import secret_add
from . import views from . import views
from .models import Device, Rack, Site from .models import (
Device, DeviceRole, DeviceType, Manufacturer, Platform, Rack, RackGroup, RackReservation, RackRole, Region, Site,
VirtualChassis,
)
app_name = 'dcim' app_name = 'dcim'
urlpatterns = [ urlpatterns = [
@ -17,6 +20,7 @@ urlpatterns = [
url(r'^regions/import/$', views.RegionBulkImportView.as_view(), name='region_import'), url(r'^regions/import/$', views.RegionBulkImportView.as_view(), name='region_import'),
url(r'^regions/delete/$', views.RegionBulkDeleteView.as_view(), name='region_bulk_delete'), url(r'^regions/delete/$', views.RegionBulkDeleteView.as_view(), name='region_bulk_delete'),
url(r'^regions/(?P<pk>\d+)/edit/$', views.RegionEditView.as_view(), name='region_edit'), url(r'^regions/(?P<pk>\d+)/edit/$', views.RegionEditView.as_view(), name='region_edit'),
url(r'^regions/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='region_changelog', kwargs={'model': Region}),
# Sites # Sites
url(r'^sites/$', views.SiteListView.as_view(), name='site_list'), url(r'^sites/$', views.SiteListView.as_view(), name='site_list'),
@ -26,6 +30,7 @@ urlpatterns = [
url(r'^sites/(?P<slug>[\w-]+)/$', views.SiteView.as_view(), name='site'), url(r'^sites/(?P<slug>[\w-]+)/$', views.SiteView.as_view(), name='site'),
url(r'^sites/(?P<slug>[\w-]+)/edit/$', views.SiteEditView.as_view(), name='site_edit'), url(r'^sites/(?P<slug>[\w-]+)/edit/$', views.SiteEditView.as_view(), name='site_edit'),
url(r'^sites/(?P<slug>[\w-]+)/delete/$', views.SiteDeleteView.as_view(), name='site_delete'), url(r'^sites/(?P<slug>[\w-]+)/delete/$', views.SiteDeleteView.as_view(), name='site_delete'),
url(r'^sites/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='site_changelog', kwargs={'model': Site}),
url(r'^sites/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='site_add_image', kwargs={'model': Site}), url(r'^sites/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='site_add_image', kwargs={'model': Site}),
# Rack groups # Rack groups
@ -34,6 +39,7 @@ urlpatterns = [
url(r'^rack-groups/import/$', views.RackGroupBulkImportView.as_view(), name='rackgroup_import'), url(r'^rack-groups/import/$', views.RackGroupBulkImportView.as_view(), name='rackgroup_import'),
url(r'^rack-groups/delete/$', views.RackGroupBulkDeleteView.as_view(), name='rackgroup_bulk_delete'), url(r'^rack-groups/delete/$', views.RackGroupBulkDeleteView.as_view(), name='rackgroup_bulk_delete'),
url(r'^rack-groups/(?P<pk>\d+)/edit/$', views.RackGroupEditView.as_view(), name='rackgroup_edit'), url(r'^rack-groups/(?P<pk>\d+)/edit/$', views.RackGroupEditView.as_view(), name='rackgroup_edit'),
url(r'^rack-groups/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='rackgroup_changelog', kwargs={'model': RackGroup}),
# Rack roles # Rack roles
url(r'^rack-roles/$', views.RackRoleListView.as_view(), name='rackrole_list'), url(r'^rack-roles/$', views.RackRoleListView.as_view(), name='rackrole_list'),
@ -41,6 +47,7 @@ urlpatterns = [
url(r'^rack-roles/import/$', views.RackRoleBulkImportView.as_view(), name='rackrole_import'), url(r'^rack-roles/import/$', views.RackRoleBulkImportView.as_view(), name='rackrole_import'),
url(r'^rack-roles/delete/$', views.RackRoleBulkDeleteView.as_view(), name='rackrole_bulk_delete'), url(r'^rack-roles/delete/$', views.RackRoleBulkDeleteView.as_view(), name='rackrole_bulk_delete'),
url(r'^rack-roles/(?P<pk>\d+)/edit/$', views.RackRoleEditView.as_view(), name='rackrole_edit'), url(r'^rack-roles/(?P<pk>\d+)/edit/$', views.RackRoleEditView.as_view(), name='rackrole_edit'),
url(r'^rack-roles/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='rackrole_changelog', kwargs={'model': RackRole}),
# Rack reservations # Rack reservations
url(r'^rack-reservations/$', views.RackReservationListView.as_view(), name='rackreservation_list'), url(r'^rack-reservations/$', views.RackReservationListView.as_view(), name='rackreservation_list'),
@ -48,6 +55,7 @@ urlpatterns = [
url(r'^rack-reservations/delete/$', views.RackReservationBulkDeleteView.as_view(), name='rackreservation_bulk_delete'), url(r'^rack-reservations/delete/$', views.RackReservationBulkDeleteView.as_view(), name='rackreservation_bulk_delete'),
url(r'^rack-reservations/(?P<pk>\d+)/edit/$', views.RackReservationEditView.as_view(), name='rackreservation_edit'), url(r'^rack-reservations/(?P<pk>\d+)/edit/$', views.RackReservationEditView.as_view(), name='rackreservation_edit'),
url(r'^rack-reservations/(?P<pk>\d+)/delete/$', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'), url(r'^rack-reservations/(?P<pk>\d+)/delete/$', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'),
url(r'^rack-reservations/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='rackreservation_changelog', kwargs={'model': RackReservation}),
# Racks # Racks
url(r'^racks/$', views.RackListView.as_view(), name='rack_list'), url(r'^racks/$', views.RackListView.as_view(), name='rack_list'),
@ -59,6 +67,7 @@ urlpatterns = [
url(r'^racks/(?P<pk>\d+)/$', views.RackView.as_view(), name='rack'), url(r'^racks/(?P<pk>\d+)/$', views.RackView.as_view(), name='rack'),
url(r'^racks/(?P<pk>\d+)/edit/$', views.RackEditView.as_view(), name='rack_edit'), url(r'^racks/(?P<pk>\d+)/edit/$', views.RackEditView.as_view(), name='rack_edit'),
url(r'^racks/(?P<pk>\d+)/delete/$', views.RackDeleteView.as_view(), name='rack_delete'), url(r'^racks/(?P<pk>\d+)/delete/$', views.RackDeleteView.as_view(), name='rack_delete'),
url(r'^racks/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='rack_changelog', kwargs={'model': Rack}),
url(r'^racks/(?P<rack>\d+)/reservations/add/$', views.RackReservationCreateView.as_view(), name='rack_add_reservation'), url(r'^racks/(?P<rack>\d+)/reservations/add/$', views.RackReservationCreateView.as_view(), name='rack_add_reservation'),
url(r'^racks/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='rack_add_image', kwargs={'model': Rack}), url(r'^racks/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='rack_add_image', kwargs={'model': Rack}),
@ -68,6 +77,7 @@ urlpatterns = [
url(r'^manufacturers/import/$', views.ManufacturerBulkImportView.as_view(), name='manufacturer_import'), url(r'^manufacturers/import/$', views.ManufacturerBulkImportView.as_view(), name='manufacturer_import'),
url(r'^manufacturers/delete/$', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'), url(r'^manufacturers/delete/$', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'),
url(r'^manufacturers/(?P<slug>[\w-]+)/edit/$', views.ManufacturerEditView.as_view(), name='manufacturer_edit'), url(r'^manufacturers/(?P<slug>[\w-]+)/edit/$', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
url(r'^manufacturers/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='manufacturer_changelog', kwargs={'model': Manufacturer}),
# Device types # Device types
url(r'^device-types/$', views.DeviceTypeListView.as_view(), name='devicetype_list'), url(r'^device-types/$', views.DeviceTypeListView.as_view(), name='devicetype_list'),
@ -78,6 +88,7 @@ urlpatterns = [
url(r'^device-types/(?P<pk>\d+)/$', views.DeviceTypeView.as_view(), name='devicetype'), url(r'^device-types/(?P<pk>\d+)/$', views.DeviceTypeView.as_view(), name='devicetype'),
url(r'^device-types/(?P<pk>\d+)/edit/$', views.DeviceTypeEditView.as_view(), name='devicetype_edit'), url(r'^device-types/(?P<pk>\d+)/edit/$', views.DeviceTypeEditView.as_view(), name='devicetype_edit'),
url(r'^device-types/(?P<pk>\d+)/delete/$', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'), url(r'^device-types/(?P<pk>\d+)/delete/$', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'),
url(r'^device-types/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='devicetype_changelog', kwargs={'model': DeviceType}),
# Console port templates # Console port templates
url(r'^device-types/(?P<pk>\d+)/console-ports/add/$', views.ConsolePortTemplateCreateView.as_view(), name='devicetype_add_consoleport'), url(r'^device-types/(?P<pk>\d+)/console-ports/add/$', views.ConsolePortTemplateCreateView.as_view(), name='devicetype_add_consoleport'),
@ -110,6 +121,7 @@ urlpatterns = [
url(r'^device-roles/import/$', views.DeviceRoleBulkImportView.as_view(), name='devicerole_import'), url(r'^device-roles/import/$', views.DeviceRoleBulkImportView.as_view(), name='devicerole_import'),
url(r'^device-roles/delete/$', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'), url(r'^device-roles/delete/$', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'),
url(r'^device-roles/(?P<slug>[\w-]+)/edit/$', views.DeviceRoleEditView.as_view(), name='devicerole_edit'), url(r'^device-roles/(?P<slug>[\w-]+)/edit/$', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
url(r'^device-roles/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='devicerole_changelog', kwargs={'model': DeviceRole}),
# Platforms # Platforms
url(r'^platforms/$', views.PlatformListView.as_view(), name='platform_list'), url(r'^platforms/$', views.PlatformListView.as_view(), name='platform_list'),
@ -117,6 +129,7 @@ urlpatterns = [
url(r'^platforms/import/$', views.PlatformBulkImportView.as_view(), name='platform_import'), url(r'^platforms/import/$', views.PlatformBulkImportView.as_view(), name='platform_import'),
url(r'^platforms/delete/$', views.PlatformBulkDeleteView.as_view(), name='platform_bulk_delete'), url(r'^platforms/delete/$', views.PlatformBulkDeleteView.as_view(), name='platform_bulk_delete'),
url(r'^platforms/(?P<slug>[\w-]+)/edit/$', views.PlatformEditView.as_view(), name='platform_edit'), url(r'^platforms/(?P<slug>[\w-]+)/edit/$', views.PlatformEditView.as_view(), name='platform_edit'),
url(r'^platforms/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='platform_changelog', kwargs={'model': Platform}),
# Devices # Devices
url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'), url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),
@ -128,6 +141,7 @@ urlpatterns = [
url(r'^devices/(?P<pk>\d+)/$', views.DeviceView.as_view(), name='device'), url(r'^devices/(?P<pk>\d+)/$', views.DeviceView.as_view(), name='device'),
url(r'^devices/(?P<pk>\d+)/edit/$', views.DeviceEditView.as_view(), name='device_edit'), url(r'^devices/(?P<pk>\d+)/edit/$', views.DeviceEditView.as_view(), name='device_edit'),
url(r'^devices/(?P<pk>\d+)/delete/$', views.DeviceDeleteView.as_view(), name='device_delete'), url(r'^devices/(?P<pk>\d+)/delete/$', views.DeviceDeleteView.as_view(), name='device_delete'),
url(r'^devices/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='device_changelog', kwargs={'model': Device}),
url(r'^devices/(?P<pk>\d+)/inventory/$', views.DeviceInventoryView.as_view(), name='device_inventory'), url(r'^devices/(?P<pk>\d+)/inventory/$', views.DeviceInventoryView.as_view(), name='device_inventory'),
url(r'^devices/(?P<pk>\d+)/status/$', views.DeviceStatusView.as_view(), name='device_status'), url(r'^devices/(?P<pk>\d+)/status/$', views.DeviceStatusView.as_view(), name='device_status'),
url(r'^devices/(?P<pk>\d+)/lldp-neighbors/$', views.DeviceLLDPNeighborsView.as_view(), name='device_lldp_neighbors'), url(r'^devices/(?P<pk>\d+)/lldp-neighbors/$', views.DeviceLLDPNeighborsView.as_view(), name='device_lldp_neighbors'),
@ -221,6 +235,7 @@ urlpatterns = [
url(r'^virtual-chassis/add/$', views.VirtualChassisCreateView.as_view(), name='virtualchassis_add'), url(r'^virtual-chassis/add/$', views.VirtualChassisCreateView.as_view(), name='virtualchassis_add'),
url(r'^virtual-chassis/(?P<pk>\d+)/edit/$', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'), url(r'^virtual-chassis/(?P<pk>\d+)/edit/$', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'),
url(r'^virtual-chassis/(?P<pk>\d+)/delete/$', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'), url(r'^virtual-chassis/(?P<pk>\d+)/delete/$', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'),
url(r'^virtual-chassis/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='virtualchassis_changelog', kwargs={'model': VirtualChassis}),
url(r'^virtual-chassis/(?P<pk>\d+)/add-member/$', views.VirtualChassisAddMemberView.as_view(), name='virtualchassis_add_member'), url(r'^virtual-chassis/(?P<pk>\d+)/add-member/$', views.VirtualChassisAddMemberView.as_view(), name='virtualchassis_add_member'),
url(r'^virtual-chassis-members/(?P<pk>\d+)/delete/$', views.VirtualChassisRemoveMemberView.as_view(), name='virtualchassis_remove_member'), url(r'^virtual-chassis-members/(?P<pk>\d+)/delete/$', views.VirtualChassisRemoveMemberView.as_view(), name='virtualchassis_remove_member'),

View File

@ -132,7 +132,7 @@ class TopologyMapAdmin(admin.ModelAdmin):
@admin.register(ObjectChange) @admin.register(ObjectChange)
class ObjectChangeAdmin(admin.ModelAdmin): class ObjectChangeAdmin(admin.ModelAdmin):
actions = None actions = None
fields = ['time', 'content_type', 'display_object', 'action', 'display_user'] fields = ['time', 'content_type', 'display_object', 'action', 'display_user', 'object_data']
list_display = ['time', 'content_type', 'display_object', 'display_action', 'display_user'] list_display = ['time', 'content_type', 'display_object', 'display_action', 'display_user']
list_filter = ['time', 'action', 'user__username'] list_filter = ['time', 'action', 'user__username']
list_select_related = ['content_type', 'user'] list_select_related = ['content_type', 'user']
@ -156,7 +156,7 @@ class ObjectChangeAdmin(admin.ModelAdmin):
OBJECTCHANGE_ACTION_DELETE: 'deletelink', OBJECTCHANGE_ACTION_DELETE: 'deletelink',
} }
return mark_safe('<span class="{}">{}</span>'.format(icon[obj.action], obj.get_action_display())) return mark_safe('<span class="{}">{}</span>'.format(icon[obj.action], obj.get_action_display()))
display_user.short_description = 'action' display_action.short_description = 'action'
def display_object(self, obj): def display_object(self, obj):
if hasattr(obj.changed_object, 'get_absolute_url'): if hasattr(obj.changed_object, 'get_absolute_url'):

View File

@ -2,6 +2,7 @@ from __future__ import unicode_literals
from collections import OrderedDict from collections import OrderedDict
from datetime import date from datetime import date
import json
import graphviz import graphviz
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -720,6 +721,10 @@ class ObjectChange(models.Model):
return super(ObjectChange, self).save(*args, **kwargs) return super(ObjectChange, self).save(*args, **kwargs)
@property
def object_data_pretty(self):
return json.dumps(self.object_data, indent=4, sort_keys=True)
# #
# User actions # User actions

View File

@ -1,7 +1,9 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django import template
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count from django.db.models import Count
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404, redirect, render, reverse from django.shortcuts import get_object_or_404, redirect, render, reverse
@ -12,7 +14,7 @@ from taggit.models import Tag
from utilities.forms import ConfirmationForm from utilities.forms import ConfirmationForm
from utilities.views import BulkDeleteView, ObjectDeleteView, ObjectEditView, ObjectListView from utilities.views import BulkDeleteView, ObjectDeleteView, ObjectEditView, ObjectListView
from .forms import ImageAttachmentForm, TagForm from .forms import ImageAttachmentForm, TagForm
from .models import ImageAttachment, ReportResult, UserAction from .models import ImageAttachment, ObjectChange, ReportResult, UserAction
from .reports import get_report, get_reports from .reports import get_report, get_reports
from .tables import TagTable from .tables import TagTable
@ -50,6 +52,41 @@ class TagBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
default_return_url = 'extras:tag_list' default_return_url = 'extras:tag_list'
#
# Change logging
#
class ChangeLogView(View):
"""
Present a history of changes made to an object.
"""
def get(self, request, model, **kwargs):
# Get object my model and kwargs (e.g. slug='foo')
obj = get_object_or_404(model, **kwargs)
# Gather all changes for this object
content_type = ContentType.objects.get_for_model(model)
changes = ObjectChange.objects.filter(content_type=content_type, object_id=obj.pk)
# Check whether a header template exists for this model
base_template = '{}/{}.html'.format(model._meta.app_label, model._meta.model_name)
try:
template.loader.get_template(base_template)
object_var = model._meta.model_name
except template.TemplateDoesNotExist:
base_template = '_base.html'
object_var = 'obj'
return render(request, 'extras/changelog.html', {
object_var: obj,
'changes': changes,
'base_template': base_template,
'active_tab': 'changelog',
})
# #
# Image attachments # Image attachments
# #

View File

@ -2,7 +2,9 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from extras.views import ChangeLogView
from . import views from . import views
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
app_name = 'ipam' app_name = 'ipam'
@ -17,6 +19,7 @@ urlpatterns = [
url(r'^vrfs/(?P<pk>\d+)/$', views.VRFView.as_view(), name='vrf'), url(r'^vrfs/(?P<pk>\d+)/$', views.VRFView.as_view(), name='vrf'),
url(r'^vrfs/(?P<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'), url(r'^vrfs/(?P<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'),
url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'), url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
url(r'^vrfs/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='vrf_changelog', kwargs={'model': VRF}),
# RIRs # RIRs
url(r'^rirs/$', views.RIRListView.as_view(), name='rir_list'), url(r'^rirs/$', views.RIRListView.as_view(), name='rir_list'),
@ -24,6 +27,7 @@ urlpatterns = [
url(r'^rirs/import/$', views.RIRBulkImportView.as_view(), name='rir_import'), url(r'^rirs/import/$', views.RIRBulkImportView.as_view(), name='rir_import'),
url(r'^rirs/delete/$', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'), url(r'^rirs/delete/$', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'),
url(r'^rirs/(?P<slug>[\w-]+)/edit/$', views.RIREditView.as_view(), name='rir_edit'), url(r'^rirs/(?P<slug>[\w-]+)/edit/$', views.RIREditView.as_view(), name='rir_edit'),
url(r'^vrfs/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='rir_changelog', kwargs={'model': RIR}),
# Aggregates # Aggregates
url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'), url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'),
@ -34,6 +38,7 @@ urlpatterns = [
url(r'^aggregates/(?P<pk>\d+)/$', views.AggregateView.as_view(), name='aggregate'), url(r'^aggregates/(?P<pk>\d+)/$', views.AggregateView.as_view(), name='aggregate'),
url(r'^aggregates/(?P<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'), url(r'^aggregates/(?P<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'),
url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'), url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
url(r'^aggregates/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='aggregate_changelog', kwargs={'model': Aggregate}),
# Roles # Roles
url(r'^roles/$', views.RoleListView.as_view(), name='role_list'), url(r'^roles/$', views.RoleListView.as_view(), name='role_list'),
@ -41,6 +46,7 @@ urlpatterns = [
url(r'^roles/import/$', views.RoleBulkImportView.as_view(), name='role_import'), url(r'^roles/import/$', views.RoleBulkImportView.as_view(), name='role_import'),
url(r'^roles/delete/$', views.RoleBulkDeleteView.as_view(), name='role_bulk_delete'), url(r'^roles/delete/$', views.RoleBulkDeleteView.as_view(), name='role_bulk_delete'),
url(r'^roles/(?P<slug>[\w-]+)/edit/$', views.RoleEditView.as_view(), name='role_edit'), url(r'^roles/(?P<slug>[\w-]+)/edit/$', views.RoleEditView.as_view(), name='role_edit'),
url(r'^roles/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='role_changelog', kwargs={'model': Role}),
# Prefixes # Prefixes
url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'), url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'),
@ -51,6 +57,7 @@ urlpatterns = [
url(r'^prefixes/(?P<pk>\d+)/$', views.PrefixView.as_view(), name='prefix'), url(r'^prefixes/(?P<pk>\d+)/$', views.PrefixView.as_view(), name='prefix'),
url(r'^prefixes/(?P<pk>\d+)/edit/$', views.PrefixEditView.as_view(), name='prefix_edit'), url(r'^prefixes/(?P<pk>\d+)/edit/$', views.PrefixEditView.as_view(), name='prefix_edit'),
url(r'^prefixes/(?P<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'), url(r'^prefixes/(?P<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'),
url(r'^prefixes/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='prefix_changelog', kwargs={'model': Prefix}),
url(r'^prefixes/(?P<pk>\d+)/prefixes/$', views.PrefixPrefixesView.as_view(), name='prefix_prefixes'), url(r'^prefixes/(?P<pk>\d+)/prefixes/$', views.PrefixPrefixesView.as_view(), name='prefix_prefixes'),
url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.PrefixIPAddressesView.as_view(), name='prefix_ipaddresses'), url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.PrefixIPAddressesView.as_view(), name='prefix_ipaddresses'),
@ -61,6 +68,7 @@ urlpatterns = [
url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'), url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'), url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'), url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
url(r'^ip-addresses/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='ipaddress_changelog', kwargs={'model': IPAddress}),
url(r'^ip-addresses/assign/$', views.IPAddressAssignView.as_view(), name='ipaddress_assign'), url(r'^ip-addresses/assign/$', views.IPAddressAssignView.as_view(), name='ipaddress_assign'),
url(r'^ip-addresses/(?P<pk>\d+)/$', views.IPAddressView.as_view(), name='ipaddress'), url(r'^ip-addresses/(?P<pk>\d+)/$', views.IPAddressView.as_view(), name='ipaddress'),
url(r'^ip-addresses/(?P<pk>\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'), url(r'^ip-addresses/(?P<pk>\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
@ -72,6 +80,7 @@ urlpatterns = [
url(r'^vlan-groups/import/$', views.VLANGroupBulkImportView.as_view(), name='vlangroup_import'), url(r'^vlan-groups/import/$', views.VLANGroupBulkImportView.as_view(), name='vlangroup_import'),
url(r'^vlan-groups/delete/$', views.VLANGroupBulkDeleteView.as_view(), name='vlangroup_bulk_delete'), url(r'^vlan-groups/delete/$', views.VLANGroupBulkDeleteView.as_view(), name='vlangroup_bulk_delete'),
url(r'^vlan-groups/(?P<pk>\d+)/edit/$', views.VLANGroupEditView.as_view(), name='vlangroup_edit'), url(r'^vlan-groups/(?P<pk>\d+)/edit/$', views.VLANGroupEditView.as_view(), name='vlangroup_edit'),
url(r'^vlan-groups/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='vlangroup_changelog', kwargs={'model': VLANGroup}),
# VLANs # VLANs
url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'), url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'),
@ -83,9 +92,11 @@ urlpatterns = [
url(r'^vlans/(?P<pk>\d+)/members/$', views.VLANMembersView.as_view(), name='vlan_members'), url(r'^vlans/(?P<pk>\d+)/members/$', views.VLANMembersView.as_view(), name='vlan_members'),
url(r'^vlans/(?P<pk>\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'), url(r'^vlans/(?P<pk>\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'),
url(r'^vlans/(?P<pk>\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'), url(r'^vlans/(?P<pk>\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'),
url(r'^vlans/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='vlan_changelog', kwargs={'model': VLAN}),
# Services # Services
url(r'^services/(?P<pk>\d+)/edit/$', views.ServiceEditView.as_view(), name='service_edit'), url(r'^services/(?P<pk>\d+)/edit/$', views.ServiceEditView.as_view(), name='service_edit'),
url(r'^services/(?P<pk>\d+)/delete/$', views.ServiceDeleteView.as_view(), name='service_delete'), url(r'^services/(?P<pk>\d+)/delete/$', views.ServiceDeleteView.as_view(), name='service_delete'),
url(r'^services/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='service_changelog', kwargs={'model': Service}),
] ]

View File

@ -2,7 +2,9 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from extras.views import ChangeLogView
from . import views from . import views
from .models import Secret, SecretRole
app_name = 'secrets' app_name = 'secrets'
urlpatterns = [ urlpatterns = [
@ -13,6 +15,7 @@ urlpatterns = [
url(r'^secret-roles/import/$', views.SecretRoleBulkImportView.as_view(), name='secretrole_import'), url(r'^secret-roles/import/$', views.SecretRoleBulkImportView.as_view(), name='secretrole_import'),
url(r'^secret-roles/delete/$', views.SecretRoleBulkDeleteView.as_view(), name='secretrole_bulk_delete'), url(r'^secret-roles/delete/$', views.SecretRoleBulkDeleteView.as_view(), name='secretrole_bulk_delete'),
url(r'^secret-roles/(?P<slug>[\w-]+)/edit/$', views.SecretRoleEditView.as_view(), name='secretrole_edit'), url(r'^secret-roles/(?P<slug>[\w-]+)/edit/$', views.SecretRoleEditView.as_view(), name='secretrole_edit'),
url(r'^secret-roles/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='secretrole_changelog', kwargs={'model': SecretRole}),
# Secrets # Secrets
url(r'^secrets/$', views.SecretListView.as_view(), name='secret_list'), url(r'^secrets/$', views.SecretListView.as_view(), name='secret_list'),
@ -22,5 +25,6 @@ urlpatterns = [
url(r'^secrets/(?P<pk>\d+)/$', views.SecretView.as_view(), name='secret'), url(r'^secrets/(?P<pk>\d+)/$', views.SecretView.as_view(), name='secret'),
url(r'^secrets/(?P<pk>\d+)/edit/$', views.secret_edit, name='secret_edit'), url(r'^secrets/(?P<pk>\d+)/edit/$', views.secret_edit, name='secret_edit'),
url(r'^secrets/(?P<pk>\d+)/delete/$', views.SecretDeleteView.as_view(), name='secret_delete'), url(r'^secrets/(?P<pk>\d+)/delete/$', views.SecretDeleteView.as_view(), name='secret_delete'),
url(r'^secrets/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='secret_changelog', kwargs={'model': Secret}),
] ]

View File

@ -1,44 +1,57 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block title %}{{ circuit }}{% endblock %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'circuits:circuit_list' %}">Circuits</a></li>
<li><a href="{% url 'circuits:circuit_list' %}?provider={{ circuit.provider.slug }}">{{ circuit.provider }}</a></li>
<li>{{ circuit.cid }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'circuits:circuit_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.circuits.change_circuit %}
<a href="{% url 'circuits:circuit_edit' pk=circuit.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this circuit
</a>
{% endif %}
{% if perms.circuits.delete_circuit %}
<a href="{% url 'circuits:circuit_delete' pk=circuit.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this circuit
</a>
{% endif %}
</div>
<h1>{{ circuit }}</h1>
{% include 'inc/created_updated.html' with obj=circuit %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ circuit.get_absolute_url }}">Circuit</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'circuits:circuit_changelog' pk=circuit.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'circuits:circuit_list' %}">Circuits</a></li>
<li><a href="{% url 'circuits:circuit_list' %}?provider={{ circuit.provider.slug }}">{{ circuit.provider }}</a></li>
<li>{{ circuit.cid }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'circuits:circuit_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.circuits.change_circuit %}
<a href="{% url 'circuits:circuit_edit' pk=circuit.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this circuit
</a>
{% endif %}
{% if perms.circuits.delete_circuit %}
<a href="{% url 'circuits:circuit_delete' pk=circuit.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this circuit
</a>
{% endif %}
</div>
<h1>{% block title %}{{ circuit.provider }} - {{ circuit.cid }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=circuit %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -2,49 +2,62 @@
{% load static from staticfiles %} {% load static from staticfiles %}
{% load helpers %} {% load helpers %}
{% block title %}{{ provider }}{% endblock %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'circuits:provider_list' %}">Providers</a></li>
<li>{{ provider }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'circuits:provider_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if show_graphs %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ provider.name }}" data-url="{% url 'circuits-api:provider-graphs' pk=provider.pk %}" title="Show graphs">
<i class="fa fa-signal" aria-hidden="true"></i>
Graphs
</button>
{% endif %}
{% if perms.circuits.change_provider %}
<a href="{% url 'circuits:provider_edit' slug=provider.slug %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this provider
</a>
{% endif %}
{% if perms.circuits.delete_provider %}
<a href="{% url 'circuits:provider_delete' slug=provider.slug %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this provider
</a>
{% endif %}
</div>
<h1>{{ provider }}</h1>
{% include 'inc/created_updated.html' with obj=provider %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ provider.get_absolute_url }}">Provider</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'circuits:provider_changelog' slug=provider.slug %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'circuits:provider_list' %}">Providers</a></li>
<li>{{ provider }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'circuits:provider_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if show_graphs %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ provider.name }}" data-url="{% url 'circuits-api:provider-graphs' pk=provider.pk %}" title="Show graphs">
<i class="fa fa-signal" aria-hidden="true"></i>
Graphs
</button>
{% endif %}
{% if perms.circuits.change_provider %}
<a href="{% url 'circuits:provider_edit' slug=provider.slug %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this provider
</a>
{% endif %}
{% if perms.circuits.delete_provider %}
<a href="{% url 'circuits:provider_delete' slug=provider.slug %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this provider
</a>
{% endif %}
</div>
<h1>{% block title %}{{ provider }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=provider %}
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -2,6 +2,8 @@
{% load static from staticfiles %} {% load static from staticfiles %}
{% load helpers %} {% load helpers %}
{% block title %}{{ device }}{% endblock %}
{% block header %} {% block header %}
<div class="row"> <div class="row">
<div class="col-sm-8 col-md-9"> <div class="col-sm-8 col-md-9">
@ -45,11 +47,11 @@
</a> </a>
{% endif %} {% endif %}
</div> </div>
<h1>{% block title %}{{ device }}{% endblock %}</h1> <h1>{{ device }}</h1>
{% include 'inc/created_updated.html' with obj=device %} {% include 'inc/created_updated.html' with obj=device %}
<ul class="nav nav-tabs" style="margin-bottom: 20px"> <ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}> <li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{% url 'dcim:device' pk=device.pk %}">Info</a> <a href="{% url 'dcim:device' pk=device.pk %}">Device</a>
</li> </li>
<li role="presentation"{% if active_tab == 'inventory' %} class="active"{% endif %}> <li role="presentation"{% if active_tab == 'inventory' %} class="active"{% endif %}>
<a href="{% url 'dcim:device_inventory' pk=device.pk %}">Inventory</a> <a href="{% url 'dcim:device_inventory' pk=device.pk %}">Inventory</a>
@ -67,6 +69,9 @@
{% include 'dcim/inc/device_napalm_tabs.html' %} {% include 'dcim/inc/device_napalm_tabs.html' %}
{% endif %} {% endif %}
{% endif %} {% endif %}
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'dcim:device_changelog' pk=device.pk %}">Changelog</a>
</li>
</ul> </ul>
{% endblock %} {% endblock %}

View File

@ -1,34 +1,47 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block title %}{{ devicetype.manufacturer }} {{ devicetype.model }}{% endblock %}
{% block header %}
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
<li><a href="{% url 'dcim:devicetype_list' %}">Device Types</a></li>
<li><a href="{% url 'dcim:devicetype_list' %}?manufacturer={{ devicetype.manufacturer.slug }}">{{ devicetype.manufacturer }}</a></li>
<li>{{ devicetype.model }}</li>
</ol>
</div>
</div>
{% if perms.dcim.change_devicetype or perms.dcim.delete_devicetype %}
<div class="pull-right">
{% if perms.dcim.change_devicetype %}
<a href="{% url 'dcim:devicetype_edit' pk=devicetype.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this device type
</a>
{% endif %}
{% if perms.dcim.delete_devicetype %}
<a href="{% url 'dcim:devicetype_delete' pk=devicetype.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this device type
</a>
{% endif %}
</div>
{% endif %}
<h1>{{ devicetype.manufacturer }} {{ devicetype.model }}</h1>
{% include 'inc/created_updated.html' with obj=devicetype %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ devicetype.get_absolute_url }}">Device Type</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'dcim:devicetype_changelog' pk=devicetype.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
<li><a href="{% url 'dcim:devicetype_list' %}">Device Types</a></li>
<li><a href="{% url 'dcim:devicetype_list' %}?manufacturer={{ devicetype.manufacturer.slug }}">{{ devicetype.manufacturer }}</a></li>
<li>{{ devicetype.model }}</li>
</ol>
</div>
</div>
{% if perms.dcim.change_devicetype or perms.dcim.delete_devicetype %}
<div class="pull-right">
{% if perms.dcim.change_devicetype %}
<a href="{% url 'dcim:devicetype_edit' pk=devicetype.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this device type
</a>
{% endif %}
{% if perms.dcim.delete_devicetype %}
<a href="{% url 'dcim:devicetype_delete' pk=devicetype.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this device type
</a>
{% endif %}
</div>
{% endif %}
<h1>{% block title %}{{ devicetype.manufacturer }} {{ devicetype.model }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=devicetype %}
<div class="row"> <div class="row">
<div class="col-md-5"> <div class="col-md-5">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -1,48 +1,59 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'dcim:rack_list' %}">Racks</a></li>
<li><a href="{% url 'dcim:rack_list' %}?site={{ rack.site.slug }}">{{ rack.site }}</a></li>
<li>{{ rack }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'dcim:rack_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search racks" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
<a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}"{% else %}disabled="disabled"{% endif %} class="btn btn-primary">
<span class="fa fa-chevron-left" aria-hidden="true"></span> Previous Rack
</a>
<a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}"{% else %}disabled="disabled"{% endif %} class="btn btn-primary">
<span class="fa fa-chevron-right" aria-hidden="true"></span> Next Rack
</a>
{% if perms.dcim.change_rack %}
<a href="{% url 'dcim:rack_edit' pk=rack.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span> Edit this rack
</a>
{% endif %}
{% if perms.dcim.delete_rack %}
<a href="{% url 'dcim:rack_delete' pk=rack.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span> Delete this rack
</a>
{% endif %}
</div>
<h1>{% block title %}Rack {{ rack }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=rack %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ rack.get_absolute_url }}">Rack</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'dcim:rack_changelog' pk=rack.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'dcim:rack_list' %}">Racks</a></li>
<li><a href="{% url 'dcim:rack_list' %}?site={{ rack.site.slug }}">{{ rack.site }}</a></li>
<li>{{ rack }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'dcim:rack_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search racks" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
<a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}"{% else %}disabled="disabled"{% endif %} class="btn btn-primary">
<span class="fa fa-chevron-left" aria-hidden="true"></span> Previous Rack
</a>
<a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}"{% else %}disabled="disabled"{% endif %} class="btn btn-primary">
<span class="fa fa-chevron-right" aria-hidden="true"></span> Next Rack
</a>
{% if perms.dcim.change_rack %}
<a href="{% url 'dcim:rack_edit' pk=rack.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span> Edit this rack
</a>
{% endif %}
{% if perms.dcim.delete_rack %}
<a href="{% url 'dcim:rack_delete' pk=rack.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span> Delete this rack
</a>
{% endif %}
</div>
<h1>{% block title %}Rack {{ rack }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=rack %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -3,54 +3,66 @@
{% load tz %} {% load tz %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'dcim:site_list' %}">Sites</a></li>
{% if site.region %}
{% for region in site.region.get_ancestors %}
<li><a href="{{ region.get_absolute_url }}">{{ region }}</a></li>
{% endfor %}
<li><a href="{{ site.region.get_absolute_url }}">{{ site.region }}</a></li>
{% endif %}
<li>{{ site }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'dcim:site_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search sites" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if show_graphs %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ site.name }}" data-url="{% url 'dcim-api:site-graphs' pk=site.pk %}" title="Show graphs">
<i class="fa fa-signal" aria-hidden="true"></i>
Graphs
</button>
{% endif %}
{% if perms.dcim.change_site %}
<a href="{% url 'dcim:site_edit' slug=site.slug %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this site
</a>
{% endif %}
{% if perms.dcim.delete_site %}
<a href="{% url 'dcim:site_delete' slug=site.slug %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this site
</a>
{% endif %}
</div>
<h1>{% block title %}{{ site }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=site %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ site.get_absolute_url }}">Site</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'dcim:site_changelog' slug=site.slug %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
{% if site.region %}
{% for region in site.region.get_ancestors %}
<li><a href="{{ region.get_absolute_url }}">{{ region }}</a></li>
{% endfor %}
<li><a href="{{ site.region.get_absolute_url }}">{{ site.region }}</a></li>
{% endif %}
<li>{{ site }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'dcim:site_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search sites" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if show_graphs %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ site.name }}" data-url="{% url 'dcim-api:site-graphs' pk=site.pk %}" title="Show graphs">
<i class="fa fa-signal" aria-hidden="true"></i>
Graphs
</button>
{% endif %}
{% if perms.dcim.change_site %}
<a href="{% url 'dcim:site_edit' slug=site.slug %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this site
</a>
{% endif %}
{% if perms.dcim.delete_site %}
<a href="{% url 'dcim:site_delete' slug=site.slug %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this site
</a>
{% endif %}
</div>
<h1>{% block title %}{{ site }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=site %}
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -0,0 +1,36 @@
{% extends base_template %}
{% block title %}{% if obj %}{{ obj }}{% else %}{{ block.super }}{% endif %} - Changelog{% endblock %}
{% block content %}
{% if obj %}<h1>{{ obj }}</h1>{% endif %}
<table class="table">
<thead>
<tr>
<th>Time</th>
<th>User</th>
<th>Action</th>
<th></th>
</tr>
</thead>
<tbody>
{% for change in changes %}
<tr>
<td>{{ change.time }}</td>
<td>{{ change.user }}</td>
<td>{{ change.get_action_display }}</td>
<td>
<button class="btn btn-xs btn-primary" type="button" data-toggle="collapse" data-target="#change{{ change.pk }}" aria-expanded="false" aria-controls="collapseExample">
<i class="fa fa-search"></i>
</button>
</td>
</tr>
<tr class="collapse" id="change{{ change.pk }}">
<td colspan="4">
<pre class="well">{{ change.object_data_pretty }}</pre>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -1,44 +1,55 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'ipam:aggregate_list' %}">Aggregates</a></li>
<li><a href="{% url 'ipam:aggregate_list' %}?rir={{ aggregate.rir.slug }}">{{ aggregate.rir }}</a></li>
<li>{{ aggregate }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'ipam:aggregate_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search aggregates" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.ipam.change_aggregate %}
<a href="{% url 'ipam:aggregate_edit' pk=aggregate.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this aggregate
</a>
{% endif %}
{% if perms.ipam.delete_aggregate %}
<a href="{% url 'ipam:aggregate_delete' pk=aggregate.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this aggregate
</a>
{% endif %}
</div>
<h1>{% block title %}{{ aggregate }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=aggregate %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ aggregate.get_absolute_url }}">Aggregate</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'ipam:aggregate_changelog' pk=aggregate.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'ipam:aggregate_list' %}">Aggregates</a></li>
<li><a href="{% url 'ipam:aggregate_list' %}?rir={{ aggregate.rir.slug }}">{{ aggregate.rir }}</a></li>
<li>{{ aggregate }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'ipam:aggregate_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search aggregates" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.ipam.change_aggregate %}
<a href="{% url 'ipam:aggregate_edit' pk=aggregate.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this aggregate
</a>
{% endif %}
{% if perms.ipam.delete_aggregate %}
<a href="{% url 'ipam:aggregate_delete' pk=aggregate.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this aggregate
</a>
{% endif %}
</div>
<h1>{% block title %}{{ aggregate }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=aggregate %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -1,46 +1,57 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'ipam:ipaddress_list' %}">IP Addresses</a></li>
{% if ipaddress.vrf %}
<li><a href="{% url 'ipam:vrf' pk=ipaddress.vrf.pk %}">{{ ipaddress.vrf }}</a></li>
{% endif %}
<li>{{ ipaddress }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'ipam:ipaddress_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search IPs" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.ipam.change_ipaddress %}
<a href="{% url 'ipam:ipaddress_edit' pk=ipaddress.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this IP
</a>
{% endif %}
{% if perms.ipam.delete_ipaddress %}
<a href="{% url 'ipam:ipaddress_delete' pk=ipaddress.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this IP
</a>
{% endif %}
</div>
<h1>{% block title %}{{ ipaddress }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=ipaddress %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ ipaddress.get_absolute_url }}">IP Address</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'ipam:ipaddress_changelog' pk=ipaddress.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'ipam:ipaddress_list' %}">IP Addresses</a></li>
{% if ipaddress.vrf %}
<li><a href="{% url 'ipam:vrf' pk=ipaddress.vrf.pk %}">{{ ipaddress.vrf }}</a></li>
{% endif %}
<li>{{ ipaddress }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'ipam:ipaddress_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search IPs" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.ipam.change_ipaddress %}
<a href="{% url 'ipam:ipaddress_edit' pk=ipaddress.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this IP
</a>
{% endif %}
{% if perms.ipam.delete_ipaddress %}
<a href="{% url 'ipam:ipaddress_delete' pk=ipaddress.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this IP
</a>
{% endif %}
</div>
<h1>{% block title %}{{ ipaddress }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=ipaddress %}
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -53,9 +53,18 @@
<h1>{% block title %}{{ prefix }}{% endblock %}</h1> <h1>{% block title %}{{ prefix }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=prefix %} {% include 'inc/created_updated.html' with obj=prefix %}
<ul class="nav nav-tabs" style="margin-bottom: 20px"> <ul class="nav nav-tabs" style="margin-bottom: 20px">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}><a href="{% url 'ipam:prefix' pk=prefix.pk %}">Prefix</a></li> <li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<li role="presentation"{% if active_tab == 'prefixes' %} class="active"{% endif %}><a href="{% url 'ipam:prefix_prefixes' pk=prefix.pk %}">Child Prefixes <span class="badge">{{ prefix.get_child_prefixes.count }}</span></a></li> <a href="{% url 'ipam:prefix' pk=prefix.pk %}">Prefix</a>
<li role="presentation"{% if active_tab == 'ip-addresses' %} class="active"{% endif %}><a href="{% url 'ipam:prefix_ipaddresses' pk=prefix.pk %}">IP Addresses <span class="badge">{{ prefix.get_child_ips.count }}</span></a></li> </li>
<li role="presentation"{% if active_tab == 'prefixes' %} class="active"{% endif %}>
<a href="{% url 'ipam:prefix_prefixes' pk=prefix.pk %}">Child Prefixes <span class="badge">{{ prefix.get_child_prefixes.count }}</span></a>
</li>
<li role="presentation"{% if active_tab == 'ip-addresses' %} class="active"{% endif %}>
<a href="{% url 'ipam:prefix_ipaddresses' pk=prefix.pk %}">IP Addresses <span class="badge">{{ prefix.get_child_ips.count }}</span></a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'ipam:prefix_changelog' pk=prefix.pk %}">Changelog</a>
</li>
</ul> </ul>
{% endblock %} {% endblock %}

View File

@ -45,8 +45,15 @@
<h1>{% block title %}VLAN {{ vlan.display_name }}{% endblock %}</h1> <h1>{% block title %}VLAN {{ vlan.display_name }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=vlan %} {% include 'inc/created_updated.html' with obj=vlan %}
<ul class="nav nav-tabs" style="margin-bottom: 20px"> <ul class="nav nav-tabs" style="margin-bottom: 20px">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}><a href="{% url 'ipam:vlan' pk=vlan.pk %}">VLAN</a></li> <li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<li role="presentation"{% if active_tab == 'members' %} class="active"{% endif %}><a href="{% url 'ipam:vlan_members' pk=vlan.pk %}">Members <span class="badge">{{ vlan.get_members.count }}</span></a></li> <a href="{% url 'ipam:vlan' pk=vlan.pk %}">VLAN</a>
</li>
<li role="presentation"{% if active_tab == 'members' %} class="active"{% endif %}>
<a href="{% url 'ipam:vlan_members' pk=vlan.pk %}">Members <span class="badge">{{ vlan.get_members.count }}</span></a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'ipam:vlan_changelog' pk=vlan.pk %}">Changelog</a>
</li>
</ul> </ul>
{% endblock %} {% endblock %}

View File

@ -1,43 +1,54 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'ipam:vrf_list' %}">VRFs</a></li>
<li>{{ vrf }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'ipam:vrf_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search VRFs" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.ipam.change_vrf %}
<a href="{% url 'ipam:vrf_edit' pk=vrf.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this VRF
</a>
{% endif %}
{% if perms.ipam.delete_vrf %}
<a href="{% url 'ipam:vrf_delete' pk=vrf.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this VRF
</a>
{% endif %}
</div>
<h1>{% block title %}VRF {{ vrf }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=vrf %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ aggregate.get_absolute_url }}">VRF</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'ipam:vrf_changelog' pk=vrf.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'ipam:vrf_list' %}">VRFs</a></li>
<li>{{ vrf }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'ipam:vrf_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search VRFs" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.ipam.change_vrf %}
<a href="{% url 'ipam:vrf_edit' pk=vrf.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this VRF
</a>
{% endif %}
{% if perms.ipam.delete_vrf %}
<a href="{% url 'ipam:vrf_delete' pk=vrf.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this VRF
</a>
{% endif %}
</div>
<h1>{% block title %}VRF {{ vrf }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=vrf %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -3,32 +3,43 @@
{% load helpers %} {% load helpers %}
{% load secret_helpers %} {% load secret_helpers %}
{% block content %} {% block header %}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><a href="{% url 'secrets:secret_list' %}">Secrets</a></li> <li><a href="{% url 'secrets:secret_list' %}">Secrets</a></li>
<li><a href="{% url 'secrets:secret_list' %}?role={{ secret.role.slug }}">{{ secret.role }}</a></li> <li><a href="{% url 'secrets:secret_list' %}?role={{ secret.role.slug }}">{{ secret.role }}</a></li>
<li>{{ secret.device }}{% if secret.name %} ({{ secret.name }}){% endif %}</li> <li>{{ secret.device }}{% if secret.name %} ({{ secret.name }}){% endif %}</li>
</ol> </ol>
</div>
</div> </div>
</div> <div class="pull-right">
<div class="pull-right"> {% if perms.secrets.change_secret %}
{% if perms.secrets.change_secret %} <a href="{% url 'secrets:secret_edit' pk=secret.pk %}" class="btn btn-warning">
<a href="{% url 'secrets:secret_edit' pk=secret.pk %}" class="btn btn-warning"> <span class="fa fa-pencil" aria-hidden="true"></span>
<span class="fa fa-pencil" aria-hidden="true"></span> Edit this secret
Edit this secret </a>
</a> {% endif %}
{% endif %} {% if perms.secrets.delete_secret %}
{% if perms.secrets.delete_secret %} <a href="{% url 'secrets:secret_delete' pk=secret.pk %}" class="btn btn-danger">
<a href="{% url 'secrets:secret_delete' pk=secret.pk %}" class="btn btn-danger"> <span class="fa fa-trash" aria-hidden="true"></span>
<span class="fa fa-trash" aria-hidden="true"></span> Delete this secret
Delete this secret </a>
</a> {% endif %}
{% endif %} </div>
</div> <h1>{% block title %}{{ secret }}{% endblock %}</h1>
<h1>{% block title %}{{ secret }}{% endblock %}</h1> {% include 'inc/created_updated.html' with obj=secret %}
{% include 'inc/created_updated.html' with obj=secret %} <ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ secret.get_absolute_url }}">Secret</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'secrets:secret_changelog' pk=secret.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -1,46 +1,57 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'tenancy:tenant_list' %}">Tenants</a></li>
{% if tenant.group %}
<li><a href="{% url 'tenancy:tenant_list' %}?group={{ tenant.group.slug }}">{{ tenant.group }}</a></li>
{% endif %}
<li>{{ tenant }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'tenancy:tenant_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Name" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.tenancy.change_tenant %}
<a href="{% url 'tenancy:tenant_edit' slug=tenant.slug %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this tenant
</a>
{% endif %}
{% if perms.tenancy.delete_tenant %}
<a href="{% url 'tenancy:tenant_delete' slug=tenant.slug %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this tenant
</a>
{% endif %}
</div>
<h1>{% block title %}{{ tenant }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=tenant %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ tenant.get_absolute_url }}">Tenant</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'tenancy:tenant_changelog' slug=tenant.slug %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'tenancy:tenant_list' %}">Tenants</a></li>
{% if tenant.group %}
<li><a href="{% url 'tenancy:tenant_list' %}?group={{ tenant.group.slug }}">{{ tenant.group }}</a></li>
{% endif %}
<li>{{ tenant }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'tenancy:tenant_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Name" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.tenancy.change_tenant %}
<a href="{% url 'tenancy:tenant_edit' slug=tenant.slug %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this tenant
</a>
{% endif %}
{% if perms.tenancy.delete_tenant %}
<a href="{% url 'tenancy:tenant_delete' slug=tenant.slug %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this tenant
</a>
{% endif %}
</div>
<h1>{% block title %}{{ tenant }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=tenant %}
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -1,46 +1,57 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row" xmlns="http://www.w3.org/1999/html">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{{ cluster.type.get_absolute_url }}">{{ cluster.type }}</a></li>
{% if cluster.group %}
<li><a href="{{ cluster.group.get_absolute_url }}">{{ cluster.group }}</a></li>
{% endif %}
<li>{{ cluster }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'virtualization:cluster_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search clusters" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.virtualization.change_cluster %}
<a href="{% url 'virtualization:cluster_edit' pk=cluster.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this cluster
</a>
{% endif %}
{% if perms.dcim.delete_cluster %}
<a href="{% url 'virtualization:cluster_delete' pk=cluster.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this cluster
</a>
{% endif %}
</div>
<h1>{% block title %}{{ cluster }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=cluster %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ cluster.get_absolute_url }}">Cluster</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'virtualization:cluster_changelog' pk=cluster.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row" xmlns="http://www.w3.org/1999/html">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{{ cluster.type.get_absolute_url }}">{{ cluster.type }}</a></li>
{% if cluster.group %}
<li><a href="{{ cluster.group.get_absolute_url }}">{{ cluster.group }}</a></li>
{% endif %}
<li>{{ cluster }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'virtualization:cluster_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search clusters" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.virtualization.change_cluster %}
<a href="{% url 'virtualization:cluster_edit' pk=cluster.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this cluster
</a>
{% endif %}
{% if perms.dcim.delete_cluster %}
<a href="{% url 'virtualization:cluster_delete' pk=cluster.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this cluster
</a>
{% endif %}
</div>
<h1>{% block title %}{{ cluster }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=cluster %}
<div class="row"> <div class="row">
<div class="col-md-5"> <div class="col-md-5">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -1,45 +1,56 @@
{% extends '_base.html' %} {% extends '_base.html' %}
{% load helpers %} {% load helpers %}
{% block header %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
{% if virtualmachine.cluster %}
<li><a href="{{ virtualmachine.cluster.get_absolute_url }}">{{ virtualmachine.cluster }}</a></li>
{% endif %}
<li>{{ virtualmachine }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'virtualization:virtualmachine_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search virtual machines" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.virtualization.change_virtualmachine %}
<a href="{% url 'virtualization:virtualmachine_edit' pk=virtualmachine.pk %}" class="btn btn-warning">
<span class="fa fa-pencil"></span>
Edit this VM
</a>
{% endif %}
{% if perms.virtualization.delete_virtualmachine %}
<a href="{% url 'virtualization:virtualmachine_delete' pk=virtualmachine.pk %}" class="btn btn-danger">
<span class="fa fa-trash"></span>
Delete this VM
</a>
{% endif %}
</div>
<h1>{% block title %}{{ virtualmachine }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=virtualmachine %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ virtualmachine.get_absolute_url }}">Virtual Machine</a>
</li>
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url 'virtualization:virtualmachine_changelog' pk=virtualmachine.pk %}">Changelog</a>
</li>
</ul>
{% endblock %}
{% block content %} {% block content %}
<div class="row">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
{% if vm.cluster %}
<li><a href="{{ vm.cluster.get_absolute_url }}">{{ vm.cluster }}</a></li>
{% endif %}
<li>{{ vm }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'virtualization:virtualmachine_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search virtual machines" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right">
{% if perms.virtualization.change_virtualmachine %}
<a href="{% url 'virtualization:virtualmachine_edit' pk=vm.pk %}" class="btn btn-warning">
<span class="fa fa-pencil"></span>
Edit this VM
</a>
{% endif %}
{% if perms.virtualization.delete_virtualmachine %}
<a href="{% url 'virtualization:virtualmachine_delete' pk=vm.pk %}" class="btn btn-danger">
<span class="fa fa-trash"></span>
Delete this VM
</a>
{% endif %}
</div>
<h1>{% block title %}{{ vm }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=vm %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">
@ -49,19 +60,19 @@
<table class="table table-hover panel-body attr-table"> <table class="table table-hover panel-body attr-table">
<tr> <tr>
<td>Name</td> <td>Name</td>
<td>{{ vm }}</td> <td>{{ virtualmachine }}</td>
</tr> </tr>
<tr> <tr>
<td>Status</td> <td>Status</td>
<td> <td>
<span class="label label-{{ vm.get_status_class }}">{{ vm.get_status_display }}</span> <span class="label label-{{ virtualmachine.get_status_class }}">{{ virtualmachine.get_status_display }}</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Role</td> <td>Role</td>
<td> <td>
{% if vm.role %} {% if virtualmachine.role %}
<a href="{% url 'virtualization:virtualmachine_list' %}?role={{ vm.role.slug }}">{{ vm.role }}</a> <a href="{% url 'virtualization:virtualmachine_list' %}?role={{ virtualmachine.role.slug }}">{{ virtualmachine.role }}</a>
{% else %} {% else %}
<span class="text-muted">None</span> <span class="text-muted">None</span>
{% endif %} {% endif %}
@ -70,8 +81,8 @@
<tr> <tr>
<td>Platform</td> <td>Platform</td>
<td> <td>
{% if vm.platform %} {% if virtualmachine.platform %}
<a href="{% url 'virtualization:virtualmachine_list' %}?platform={{ vm.platform.slug }}">{{ vm.platform }}</a> <a href="{% url 'virtualization:virtualmachine_list' %}?platform={{ virtualmachine.platform.slug }}">{{ virtualmachine.platform }}</a>
{% else %} {% else %}
<span class="text-muted">None</span> <span class="text-muted">None</span>
{% endif %} {% endif %}
@ -80,12 +91,12 @@
<tr> <tr>
<td>Tenant</td> <td>Tenant</td>
<td> <td>
{% if vm.tenant %} {% if virtualmachine.tenant %}
{% if vm.tenant.group %} {% if virtualmachine.tenant.group %}
<a href="{{ vm.tenant.group.get_absolute_url }}">{{ vm.tenant.group }}</a> <a href="{{ virtualmachine.tenant.group.get_absolute_url }}">{{ virtualmachine.tenant.group }}</a>
<i class="fa fa-angle-right"></i> <i class="fa fa-angle-right"></i>
{% endif %} {% endif %}
<a href="{{ vm.tenant.get_absolute_url }}">{{ vm.tenant }}</a> <a href="{{ virtualmachine.tenant.get_absolute_url }}">{{ virtualmachine.tenant }}</a>
{% else %} {% else %}
<span class="text-muted">None</span> <span class="text-muted">None</span>
{% endif %} {% endif %}
@ -94,12 +105,12 @@
<tr> <tr>
<td>Primary IPv4</td> <td>Primary IPv4</td>
<td> <td>
{% if vm.primary_ip4 %} {% if virtualmachine.primary_ip4 %}
<a href="{% url 'ipam:ipaddress' pk=vm.primary_ip4.pk %}">{{ vm.primary_ip4.address.ip }}</a> <a href="{% url 'ipam:ipaddress' pk=virtualmachine.primary_ip4.pk %}">{{ virtualmachine.primary_ip4.address.ip }}</a>
{% if vm.primary_ip4.nat_inside %} {% if virtualmachine.primary_ip4.nat_inside %}
<span>(NAT for {{ vm.primary_ip4.nat_inside.address.ip }})</span> <span>(NAT for {{ virtualmachine.primary_ip4.nat_inside.address.ip }})</span>
{% elif vm.primary_ip4.nat_outside %} {% elif virtualmachine.primary_ip4.nat_outside %}
<span>(NAT: {{ vm.primary_ip4.nat_outside.address.ip }})</span> <span>(NAT: {{ virtualmachine.primary_ip4.nat_outside.address.ip }})</span>
{% endif %} {% endif %}
{% else %} {% else %}
<span class="text-muted">N/A</span> <span class="text-muted">N/A</span>
@ -109,12 +120,12 @@
<tr> <tr>
<td>Primary IPv6</td> <td>Primary IPv6</td>
<td> <td>
{% if vm.primary_ip6 %} {% if virtualmachine.primary_ip6 %}
<a href="{% url 'ipam:ipaddress' pk=vm.primary_ip6.pk %}">{{ vm.primary_ip6.address.ip }}</a> <a href="{% url 'ipam:ipaddress' pk=virtualmachine.primary_ip6.pk %}">{{ virtualmachine.primary_ip6.address.ip }}</a>
{% if vm.primary_ip6.nat_inside %} {% if virtualmachine.primary_ip6.nat_inside %}
<span>(NAT for {{ vm.primary_ip6.nat_inside.address.ip }})</span> <span>(NAT for {{ virtualmachine.primary_ip6.nat_inside.address.ip }})</span>
{% elif vm.primary_ip6.nat_outside %} {% elif virtualmachine.primary_ip6.nat_outside %}
<span>(NAT: {{ vm.primary_ip6.nat_outside.address.ip }})</span> <span>(NAT: {{ virtualmachine.primary_ip6.nat_outside.address.ip }})</span>
{% endif %} {% endif %}
{% else %} {% else %}
<span class="text-muted">N/A</span> <span class="text-muted">N/A</span>
@ -124,7 +135,7 @@
<tr> <tr>
<td>Tags</td> <td>Tags</td>
<td> <td>
{% for tag in vm.tags.all %} {% for tag in virtualmachine.tags.all %}
{% tag 'virtualization:virtualmachine_list' tag %} {% tag 'virtualization:virtualmachine_list' tag %}
{% empty %} {% empty %}
<span class="text-muted">N/A</span> <span class="text-muted">N/A</span>
@ -133,14 +144,14 @@
</tr> </tr>
</table> </table>
</div> </div>
{% include 'inc/custom_fields_panel.html' with custom_fields=vm.get_custom_fields %} {% include 'inc/custom_fields_panel.html' with custom_fields=virtualmachine.get_custom_fields %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<strong>Comments</strong> <strong>Comments</strong>
</div> </div>
<div class="panel-body"> <div class="panel-body">
{% if vm.comments %} {% if virtualmachine.comments %}
{{ vm.comments|gfm }} {{ virtualmachine.comments|gfm }}
{% else %} {% else %}
<span class="text-muted">None</span> <span class="text-muted">None</span>
{% endif %} {% endif %}
@ -156,16 +167,16 @@
<tr> <tr>
<td>Cluster</td> <td>Cluster</td>
<td> <td>
{% if vm.cluster.group %} {% if virtualmachine.cluster.group %}
<a href="{{ vm.cluster.group.get_absolute_url }}">{{ vm.cluster.group }}</a> <a href="{{ virtualmachine.cluster.group.get_absolute_url }}">{{ virtualmachine.cluster.group }}</a>
<i class="fa fa-angle-right"></i> <i class="fa fa-angle-right"></i>
{% endif %} {% endif %}
<a href="{{ vm.cluster.get_absolute_url }}">{{ vm.cluster }}</a> <a href="{{ virtualmachine.cluster.get_absolute_url }}">{{ virtualmachine.cluster }}</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Cluster Type</td> <td>Cluster Type</td>
<td>{{ vm.cluster.type }}</td> <td>{{ virtualmachine.cluster.type }}</td>
</tr> </tr>
</table> </table>
</div> </div>
@ -177,8 +188,8 @@
<tr> <tr>
<td><i class="fa fa-tachometer"></i> Virtual CPUs</td> <td><i class="fa fa-tachometer"></i> Virtual CPUs</td>
<td> <td>
{% if vm.vcpus %} {% if virtualmachine.vcpus %}
{{ vm.vcpus }} {{ virtualmachine.vcpus }}
{% else %} {% else %}
<span class="text-muted">N/A</span> <span class="text-muted">N/A</span>
{% endif %} {% endif %}
@ -187,8 +198,8 @@
<tr> <tr>
<td><i class="fa fa-microchip"></i> Memory</td> <td><i class="fa fa-microchip"></i> Memory</td>
<td> <td>
{% if vm.memory %} {% if virtualmachine.memory %}
{{ vm.memory }} MB {{ virtualmachine.memory }} MB
{% else %} {% else %}
<span class="text-muted">N/A</span> <span class="text-muted">N/A</span>
{% endif %} {% endif %}
@ -197,8 +208,8 @@
<tr> <tr>
<td><i class="fa fa-hdd-o"></i> Disk Space</td> <td><i class="fa fa-hdd-o"></i> Disk Space</td>
<td> <td>
{% if vm.disk %} {% if virtualmachine.disk %}
{{ vm.disk }} GB {{ virtualmachine.disk }} GB
{% else %} {% else %}
<span class="text-muted">N/A</span> <span class="text-muted">N/A</span>
{% endif %} {% endif %}
@ -223,7 +234,7 @@
{% endif %} {% endif %}
{% if perms.ipam.add_service %} {% if perms.ipam.add_service %}
<div class="panel-footer text-right"> <div class="panel-footer text-right">
<a href="{% url 'virtualization:virtualmachine_service_assign' virtualmachine=vm.pk %}" class="btn btn-xs btn-primary"> <a href="{% url 'virtualization:virtualmachine_service_assign' virtualmachine=virtualmachine.pk %}" class="btn btn-xs btn-primary">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Assign service <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Assign service
</a> </a>
</div> </div>
@ -236,7 +247,7 @@
{% if perms.dcim.change_interface or perms.dcim.delete_interface %} {% if perms.dcim.change_interface or perms.dcim.delete_interface %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="virtual_machine" value="{{ vm.pk }}" /> <input type="hidden" name="virtual_machine" value="{{ virtualmachine.pk }}" />
{% endif %} {% endif %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
@ -264,7 +275,7 @@
</thead> </thead>
<tbody> <tbody>
{% for iface in interfaces %} {% for iface in interfaces %}
{% include 'dcim/inc/interface.html' with device=vm %} {% include 'dcim/inc/interface.html' with device=virtualmachine %}
{% empty %} {% empty %}
<tr> <tr>
<td colspan="9" class="text-center text-muted">&mdash; No interfaces defined &mdash;</td> <td colspan="9" class="text-center text-muted">&mdash; No interfaces defined &mdash;</td>
@ -275,21 +286,21 @@
{% if perms.dcim.add_interface or perms.dcim.delete_interface %} {% if perms.dcim.add_interface or perms.dcim.delete_interface %}
<div class="panel-footer"> <div class="panel-footer">
{% if interfaces and perms.dcim.change_interface %} {% if interfaces and perms.dcim.change_interface %}
<button type="submit" name="_rename" formaction="{% url 'dcim:interface_bulk_rename' %}?return_url={{ vm.get_absolute_url }}" class="btn btn-warning btn-xs"> <button type="submit" name="_rename" formaction="{% url 'dcim:interface_bulk_rename' %}?return_url={{ virtualmachine.get_absolute_url }}" class="btn btn-warning btn-xs">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
</button> </button>
<button type="submit" name="_edit" formaction="{% url 'virtualization:interface_bulk_edit' pk=vm.pk %}" class="btn btn-warning btn-xs"> <button type="submit" name="_edit" formaction="{% url 'virtualization:interface_bulk_edit' pk=virtualmachine.pk %}" class="btn btn-warning btn-xs">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
</button> </button>
{% endif %} {% endif %}
{% if interfaces and perms.dcim.delete_interface %} {% if interfaces and perms.dcim.delete_interface %}
<button type="submit" name="_delete" formaction="{% url 'virtualization:interface_bulk_delete' pk=vm.pk %}" class="btn btn-danger btn-xs"> <button type="submit" name="_delete" formaction="{% url 'virtualization:interface_bulk_delete' pk=virtualmachine.pk %}" class="btn btn-danger btn-xs">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
</button> </button>
{% endif %} {% endif %}
{% if perms.dcim.add_interface %} {% if perms.dcim.add_interface %}
<div class="pull-right"> <div class="pull-right">
<a href="{% url 'virtualization:interface_add' pk=vm.pk %}" class="btn btn-primary btn-xs"> <a href="{% url 'virtualization:interface_add' pk=virtualmachine.pk %}" class="btn btn-primary btn-xs">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add interfaces <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add interfaces
</a> </a>
</div> </div>

View File

@ -2,7 +2,9 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from extras.views import ChangeLogView
from . import views from . import views
from .models import Tenant, TenantGroup
app_name = 'tenancy' app_name = 'tenancy'
urlpatterns = [ urlpatterns = [
@ -13,6 +15,7 @@ urlpatterns = [
url(r'^tenant-groups/import/$', views.TenantGroupBulkImportView.as_view(), name='tenantgroup_import'), url(r'^tenant-groups/import/$', views.TenantGroupBulkImportView.as_view(), name='tenantgroup_import'),
url(r'^tenant-groups/delete/$', views.TenantGroupBulkDeleteView.as_view(), name='tenantgroup_bulk_delete'), url(r'^tenant-groups/delete/$', views.TenantGroupBulkDeleteView.as_view(), name='tenantgroup_bulk_delete'),
url(r'^tenant-groups/(?P<slug>[\w-]+)/edit/$', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'), url(r'^tenant-groups/(?P<slug>[\w-]+)/edit/$', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'),
url(r'^tenant-groups/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='tenantgroup_changelog', kwargs={'model': TenantGroup}),
# Tenants # Tenants
url(r'^tenants/$', views.TenantListView.as_view(), name='tenant_list'), url(r'^tenants/$', views.TenantListView.as_view(), name='tenant_list'),
@ -23,5 +26,6 @@ urlpatterns = [
url(r'^tenants/(?P<slug>[\w-]+)/$', views.TenantView.as_view(), name='tenant'), url(r'^tenants/(?P<slug>[\w-]+)/$', views.TenantView.as_view(), name='tenant'),
url(r'^tenants/(?P<slug>[\w-]+)/edit/$', views.TenantEditView.as_view(), name='tenant_edit'), url(r'^tenants/(?P<slug>[\w-]+)/edit/$', views.TenantEditView.as_view(), name='tenant_edit'),
url(r'^tenants/(?P<slug>[\w-]+)/delete/$', views.TenantDeleteView.as_view(), name='tenant_delete'), url(r'^tenants/(?P<slug>[\w-]+)/delete/$', views.TenantDeleteView.as_view(), name='tenant_delete'),
url(r'^tenants/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='tenant_changelog', kwargs={'model': Tenant}),
] ]

View File

@ -2,8 +2,10 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from extras.views import ChangeLogView
from ipam.views import ServiceCreateView from ipam.views import ServiceCreateView
from . import views from . import views
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
app_name = 'virtualization' app_name = 'virtualization'
urlpatterns = [ urlpatterns = [
@ -14,6 +16,7 @@ urlpatterns = [
url(r'^cluster-types/import/$', views.ClusterTypeBulkImportView.as_view(), name='clustertype_import'), url(r'^cluster-types/import/$', views.ClusterTypeBulkImportView.as_view(), name='clustertype_import'),
url(r'^cluster-types/delete/$', views.ClusterTypeBulkDeleteView.as_view(), name='clustertype_bulk_delete'), url(r'^cluster-types/delete/$', views.ClusterTypeBulkDeleteView.as_view(), name='clustertype_bulk_delete'),
url(r'^cluster-types/(?P<slug>[\w-]+)/edit/$', views.ClusterTypeEditView.as_view(), name='clustertype_edit'), url(r'^cluster-types/(?P<slug>[\w-]+)/edit/$', views.ClusterTypeEditView.as_view(), name='clustertype_edit'),
url(r'^cluster-types/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='clustertype_changelog', kwargs={'model': ClusterType}),
# Cluster groups # Cluster groups
url(r'^cluster-groups/$', views.ClusterGroupListView.as_view(), name='clustergroup_list'), url(r'^cluster-groups/$', views.ClusterGroupListView.as_view(), name='clustergroup_list'),
@ -21,6 +24,7 @@ urlpatterns = [
url(r'^cluster-groups/import/$', views.ClusterGroupBulkImportView.as_view(), name='clustergroup_import'), url(r'^cluster-groups/import/$', views.ClusterGroupBulkImportView.as_view(), name='clustergroup_import'),
url(r'^cluster-groups/delete/$', views.ClusterGroupBulkDeleteView.as_view(), name='clustergroup_bulk_delete'), url(r'^cluster-groups/delete/$', views.ClusterGroupBulkDeleteView.as_view(), name='clustergroup_bulk_delete'),
url(r'^cluster-groups/(?P<slug>[\w-]+)/edit/$', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'), url(r'^cluster-groups/(?P<slug>[\w-]+)/edit/$', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'),
url(r'^cluster-groups/(?P<slug>[\w-]+)/changelog/$', ChangeLogView.as_view(), name='clustergroup_changelog', kwargs={'model': ClusterGroup}),
# Clusters # Clusters
url(r'^clusters/$', views.ClusterListView.as_view(), name='cluster_list'), url(r'^clusters/$', views.ClusterListView.as_view(), name='cluster_list'),
@ -31,6 +35,7 @@ urlpatterns = [
url(r'^clusters/(?P<pk>\d+)/$', views.ClusterView.as_view(), name='cluster'), url(r'^clusters/(?P<pk>\d+)/$', views.ClusterView.as_view(), name='cluster'),
url(r'^clusters/(?P<pk>\d+)/edit/$', views.ClusterEditView.as_view(), name='cluster_edit'), url(r'^clusters/(?P<pk>\d+)/edit/$', views.ClusterEditView.as_view(), name='cluster_edit'),
url(r'^clusters/(?P<pk>\d+)/delete/$', views.ClusterDeleteView.as_view(), name='cluster_delete'), url(r'^clusters/(?P<pk>\d+)/delete/$', views.ClusterDeleteView.as_view(), name='cluster_delete'),
url(r'^clusters/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='cluster_changelog', kwargs={'model': Cluster}),
url(r'^clusters/(?P<pk>\d+)/devices/add/$', views.ClusterAddDevicesView.as_view(), name='cluster_add_devices'), url(r'^clusters/(?P<pk>\d+)/devices/add/$', views.ClusterAddDevicesView.as_view(), name='cluster_add_devices'),
url(r'^clusters/(?P<pk>\d+)/devices/remove/$', views.ClusterRemoveDevicesView.as_view(), name='cluster_remove_devices'), url(r'^clusters/(?P<pk>\d+)/devices/remove/$', views.ClusterRemoveDevicesView.as_view(), name='cluster_remove_devices'),
@ -43,6 +48,7 @@ urlpatterns = [
url(r'^virtual-machines/(?P<pk>\d+)/$', views.VirtualMachineView.as_view(), name='virtualmachine'), url(r'^virtual-machines/(?P<pk>\d+)/$', views.VirtualMachineView.as_view(), name='virtualmachine'),
url(r'^virtual-machines/(?P<pk>\d+)/edit/$', views.VirtualMachineEditView.as_view(), name='virtualmachine_edit'), url(r'^virtual-machines/(?P<pk>\d+)/edit/$', views.VirtualMachineEditView.as_view(), name='virtualmachine_edit'),
url(r'^virtual-machines/(?P<pk>\d+)/delete/$', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'), url(r'^virtual-machines/(?P<pk>\d+)/delete/$', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'),
url(r'^virtual-machines/(?P<pk>\d+)/changelog/$', ChangeLogView.as_view(), name='virtualmachine_changelog', kwargs={'model': VirtualMachine}),
url(r'^virtual-machines/(?P<virtualmachine>\d+)/services/assign/$', ServiceCreateView.as_view(), name='virtualmachine_service_assign'), url(r'^virtual-machines/(?P<virtualmachine>\d+)/services/assign/$', ServiceCreateView.as_view(), name='virtualmachine_service_assign'),
# VM interfaces # VM interfaces

View File

@ -258,12 +258,12 @@ class VirtualMachineView(View):
def get(self, request, pk): def get(self, request, pk):
vm = get_object_or_404(VirtualMachine.objects.select_related('tenant__group'), pk=pk) virtualmachine = get_object_or_404(VirtualMachine.objects.select_related('tenant__group'), pk=pk)
interfaces = Interface.objects.filter(virtual_machine=vm) interfaces = Interface.objects.filter(virtual_machine=virtualmachine)
services = Service.objects.filter(virtual_machine=vm) services = Service.objects.filter(virtual_machine=virtualmachine)
return render(request, 'virtualization/virtualmachine.html', { return render(request, 'virtualization/virtualmachine.html', {
'vm': vm, 'virtualmachine': virtualmachine,
'interfaces': interfaces, 'interfaces': interfaces,
'services': services, 'services': services,
}) })