672 lines
24 KiB
Python
Executable File
672 lines
24 KiB
Python
Executable File
#
|
|
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
|
#
|
|
# The right to copy, distribute, modify, or otherwise make use
|
|
# of this software may be licensed only pursuant to the terms
|
|
# of an applicable Wind River license agreement.
|
|
#
|
|
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
|
|
import logging
|
|
|
|
from django.core.urlresolvers import reverse
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from horizon import exceptions
|
|
from horizon import tabs
|
|
from openstack_dashboard import api
|
|
from openstack_dashboard.dashboards.admin.inventory.cpu_functions import \
|
|
tables as cpufunctions_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.devices import \
|
|
tables as device_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.interfaces import \
|
|
tables as interface_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.lldp import \
|
|
tables as lldp_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.memorys import \
|
|
tables as memory_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.ports import \
|
|
tables as port_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.sensors import \
|
|
tables as sensor_tables
|
|
from openstack_dashboard.dashboards.admin.inventory.storages import \
|
|
tables as storage_tables
|
|
from openstack_dashboard.dashboards.admin.inventory import \
|
|
tables as toplevel_tables
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class HostsTab(tabs.TableTab):
|
|
table_classes = (toplevel_tables.HostsController,
|
|
toplevel_tables.HostsStorage,
|
|
toplevel_tables.HostsCompute,
|
|
toplevel_tables.HostsUnProvisioned,)
|
|
name = _("Hosts")
|
|
slug = "hosts"
|
|
template_name = ("admin/inventory/_hosts.html")
|
|
|
|
# for optimization, the complete hosts list, and phosts list from
|
|
# patching service, are in class scope.
|
|
all_hosts = []
|
|
all_phosts = []
|
|
|
|
def get_all_hosts_data(self):
|
|
request = self.request
|
|
self.all_hosts = []
|
|
try:
|
|
self.all_hosts = api.sysinv.host_list(request)
|
|
except Exception:
|
|
exceptions.handle(request,
|
|
_('Unable to retrieve host list.'))
|
|
self.all_phosts = []
|
|
try:
|
|
self.all_phosts = api.patch.get_hosts(request)
|
|
except Exception:
|
|
exceptions.handle(request,
|
|
_('Unable to retrieve host list from'
|
|
' patching service.'))
|
|
|
|
def get_hosts_data(self, personality):
|
|
hosts = self.all_hosts
|
|
phosts = self.all_phosts
|
|
|
|
if personality == api.sysinv.PERSONALITY_CONTROLLER:
|
|
hosts = [h for h in hosts if h._personality and
|
|
h._personality.lower().startswith(
|
|
api.sysinv.PERSONALITY_CONTROLLER)]
|
|
elif personality == api.sysinv.PERSONALITY_UNKNOWN:
|
|
hosts = [h for h in hosts if not h._personality]
|
|
else:
|
|
hosts = [h for h in hosts if h._personality and
|
|
h._personality.lower() == personality]
|
|
|
|
# Add patching status data to hosts
|
|
for h in hosts:
|
|
for ph in phosts:
|
|
if h.hostname == ph.hostname:
|
|
if ph.interim_state is True:
|
|
h.patch_current = "Pending"
|
|
elif ph.patch_failed is True:
|
|
h.patch_current = "Failed"
|
|
else:
|
|
h.patch_current = ph.patch_current
|
|
h.requires_reboot = ph.requires_reboot
|
|
h._patch_state = ph.state
|
|
h.allow_insvc_patching = ph.allow_insvc_patching
|
|
|
|
# Sort hosts by hostname
|
|
hosts.sort(key=lambda f: (f.hostname))
|
|
return hosts
|
|
|
|
def get_hostscontroller_data(self):
|
|
controllers = self.get_hosts_data(api.sysinv.PERSONALITY_CONTROLLER)
|
|
|
|
return controllers
|
|
|
|
def get_hostsstorage_data(self):
|
|
storages = self.get_hosts_data(api.sysinv.PERSONALITY_STORAGE)
|
|
|
|
return storages
|
|
|
|
def get_hostscompute_data(self):
|
|
computes = self.get_hosts_data(api.sysinv.PERSONALITY_COMPUTE)
|
|
|
|
return computes
|
|
|
|
def get_hostsunprovisioned_data(self):
|
|
unprovisioned = self.get_hosts_data(api.sysinv.PERSONALITY_UNKNOWN)
|
|
|
|
return unprovisioned
|
|
|
|
def load_table_data(self):
|
|
# Calls the get_{{ table_name }}_data methods for each table class
|
|
# and sets the data on the tables
|
|
self.get_all_hosts_data()
|
|
return super(HostsTab, self).load_table_data()
|
|
|
|
def get_context_data(self, request):
|
|
# Adds a {{ table_name }}_table item to the context for each table
|
|
# in the table_classes attribute
|
|
context = super(HostsTab, self).get_context_data(request)
|
|
|
|
controllers = context['hostscontroller_table'].data
|
|
storages = context['hostsstorage_table'].data
|
|
computes = context['hostscompute_table'].data
|
|
unprovisioned = context['hostsunprovisioned_table'].data
|
|
|
|
context['controllers'] = controllers
|
|
context['storages'] = storages
|
|
context['computes'] = computes
|
|
context['unprovisioned'] = unprovisioned
|
|
|
|
totals = []
|
|
ctrl_cnt = 0
|
|
comp_cnt = 0
|
|
stor_cnt = 0
|
|
degr_cnt = 0
|
|
fail_cnt = 0
|
|
|
|
for h in controllers:
|
|
ctrl_cnt += 1
|
|
if h._availability == 'degraded':
|
|
degr_cnt += 1
|
|
elif h._availability == 'failed':
|
|
fail_cnt += 1
|
|
|
|
for h in storages:
|
|
stor_cnt += 1
|
|
if h._availability == 'degraded':
|
|
degr_cnt += 1
|
|
elif h._availability == 'failed':
|
|
fail_cnt += 1
|
|
|
|
for h in computes:
|
|
comp_cnt += 1
|
|
if h._availability == 'degraded':
|
|
degr_cnt += 1
|
|
elif h._availability == 'failed':
|
|
fail_cnt += 1
|
|
|
|
if (ctrl_cnt > 0):
|
|
badge = "badge-success"
|
|
totals.append(
|
|
{'name': "Controller", 'value': ctrl_cnt, 'badge': badge})
|
|
|
|
if (stor_cnt > 0):
|
|
badge = "badge-success"
|
|
totals.append(
|
|
{'name': "Storage", 'value': stor_cnt, 'badge': badge})
|
|
|
|
if (comp_cnt > 0):
|
|
badge = "badge-success"
|
|
totals.append(
|
|
{'name': "Compute", 'value': comp_cnt, 'badge': badge})
|
|
|
|
if (degr_cnt > 0):
|
|
badge = "badge-warning"
|
|
else:
|
|
badge = ""
|
|
totals.append({'name': "Degraded", 'value': degr_cnt, 'badge': badge})
|
|
|
|
if (fail_cnt > 0):
|
|
badge = "badge-danger"
|
|
else:
|
|
badge = ""
|
|
totals.append({'name': "Failed", 'value': fail_cnt, 'badge': badge})
|
|
|
|
context['totals'] = totals
|
|
return context
|
|
|
|
|
|
class CpuProfilesTab(tabs.TableTab):
|
|
table_classes = (toplevel_tables.CpuProfilesTable, )
|
|
name = _("Cpu Profiles")
|
|
slug = "cpuprofiles"
|
|
template_name = ("admin/inventory/_cpuprofiles.html")
|
|
preload = False
|
|
|
|
def get_cpuprofiles_data(self):
|
|
cpuprofiles = []
|
|
try:
|
|
cpuprofiles = api.sysinv.host_cpuprofile_list(self.request)
|
|
cpuprofiles.sort(key=lambda f: (f.profilename))
|
|
except Exception:
|
|
cpuprofiles = []
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve host list.'))
|
|
return cpuprofiles
|
|
|
|
def allowed(self, request, datum=None):
|
|
return not api.sysinv.is_system_mode_simplex(request)
|
|
|
|
|
|
class InterfaceProfilesTab(tabs.TableTab):
|
|
table_classes = (toplevel_tables.InterfaceProfilesTable, )
|
|
name = _("Interface Profiles")
|
|
slug = "interfaceprofiles"
|
|
template_name = ("admin/inventory/_interfaceprofiles.html")
|
|
preload = False
|
|
|
|
def get_interfaceprofiles_data(self):
|
|
interfaceprofiles = []
|
|
try:
|
|
interfaceprofiles = api.sysinv.host_interfaceprofile_list(
|
|
self.request)
|
|
except Exception:
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve host list.'))
|
|
interfaceprofiles.sort(key=lambda f: (f.profilename))
|
|
return interfaceprofiles
|
|
|
|
def allowed(self, request, dataum=None):
|
|
return not api.sysinv.is_system_mode_simplex(request)
|
|
|
|
|
|
class DiskProfilesTab(tabs.TableTab):
|
|
table_classes = (toplevel_tables.DiskProfilesTable, )
|
|
name = _("Storage Profiles")
|
|
slug = "diskprofiles"
|
|
template_name = ("admin/inventory/_diskprofiles.html")
|
|
preload = False
|
|
|
|
def get_diskprofiles_data(self):
|
|
diskprofiles = []
|
|
try:
|
|
diskprofiles = api.sysinv.host_diskprofile_list(self.request)
|
|
|
|
for diskprofile in diskprofiles:
|
|
journals = {}
|
|
count = 0
|
|
for stor in diskprofile.stors:
|
|
if stor.function == 'journal':
|
|
count += 1
|
|
journals.update({stor.uuid: count})
|
|
|
|
for s in diskprofile.stors:
|
|
if s.function == 'journal' and count > 1:
|
|
setattr(s, "count", journals[s.uuid])
|
|
if s.function == 'osd':
|
|
if s.journal_location != s.uuid:
|
|
if count > 1:
|
|
setattr(s, "count",
|
|
journals[s.journal_location])
|
|
except Exception:
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve storage profile list.'))
|
|
diskprofiles.sort(key=lambda f: (f.profilename))
|
|
return diskprofiles
|
|
|
|
def allowed(self, request, dataum=None):
|
|
return not api.sysinv.is_system_mode_simplex(request)
|
|
|
|
|
|
class MemoryProfilesTab(tabs.TableTab):
|
|
table_classes = (toplevel_tables.MemoryProfilesTable, )
|
|
name = _("Memory Profiles")
|
|
slug = "memoryprofiles"
|
|
template_name = ("admin/inventory/_memoryprofiles.html")
|
|
preload = False
|
|
|
|
def get_memoryprofiles_data(self):
|
|
memoryprofiles = []
|
|
try:
|
|
memoryprofiles = api.sysinv.host_memprofile_list(self.request)
|
|
except Exception:
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve memory profile list.'))
|
|
memoryprofiles.sort(key=lambda f: (f.profilename))
|
|
return memoryprofiles
|
|
|
|
def allowed(self, request, dataum=None):
|
|
return not api.sysinv.is_system_mode_simplex(request)
|
|
|
|
|
|
class DeviceUsageTab(tabs.TableTab):
|
|
table_classes = (device_tables.DeviceUsageTable, )
|
|
name = _("Device Usage")
|
|
slug = "deviceusage"
|
|
template_name = ("admin/inventory/_deviceusage.html")
|
|
preload = False
|
|
|
|
def get_sysinv_devices(self, request):
|
|
device_list = api.sysinv.device_list_all(request)
|
|
return device_list
|
|
|
|
def get_device_description(self, usage, devices):
|
|
# Correlate the (device_id, vendor_id) or class_id to the
|
|
# Sysinv view of devices to get a user-friendly description to
|
|
# display.
|
|
for device in devices:
|
|
if (usage.device_id == device.pdevice_id and
|
|
usage.vendor_id == device.pvendor_id):
|
|
return device.pdevice
|
|
elif (usage.class_id == device.pclass_id):
|
|
return device.pclass
|
|
|
|
def get_deviceusage_data(self):
|
|
deviceusage = []
|
|
devices = []
|
|
try:
|
|
deviceusage = api.nova.get_device_usage_list(self.request)
|
|
devices = self.get_sysinv_devices(self.request)
|
|
for du in deviceusage:
|
|
du.description = self.get_device_description(du, devices)
|
|
except Exception:
|
|
# exceptions.handle(self.request,
|
|
# _('Unable to retrieve device usage.'))
|
|
pass
|
|
|
|
return deviceusage
|
|
|
|
|
|
class InventoryTabs(tabs.TabGroup):
|
|
slug = "inventory"
|
|
tabs = (
|
|
HostsTab,
|
|
CpuProfilesTab, InterfaceProfilesTab,
|
|
DiskProfilesTab, MemoryProfilesTab, DeviceUsageTab)
|
|
sticky = True
|
|
|
|
|
|
class OverviewTab(tabs.TableTab):
|
|
table_classes = (
|
|
cpufunctions_tables.CpuFunctionsTable, port_tables.PortsTable,
|
|
interface_tables.InterfacesTable)
|
|
name = _("Overview")
|
|
slug = "overview"
|
|
template_name = ("admin/inventory/_detail_overview.html")
|
|
|
|
def get_cpufunctions_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.core_assignment
|
|
|
|
def get_ports_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
host.ports.sort(key=lambda f: (f.name))
|
|
return host.ports
|
|
|
|
def get_interfaces_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
|
|
# add 'ports' member to interface class for easier mgmt in table
|
|
if host.interfaces:
|
|
for i in host.interfaces:
|
|
if i.iftype == 'ethernet':
|
|
i.ports = [p.uuid for p in host.ports if
|
|
i.uuid == p.interface_uuid]
|
|
i.portNameList = [p.get_port_display_name() for p in
|
|
host.ports if
|
|
i.uuid == p.interface_uuid]
|
|
i.dpdksupport = [p.dpdksupport for p in host.ports if
|
|
i.uuid == p.interface_uuid]
|
|
elif i.iftype == 'vlan':
|
|
for u in i.uses:
|
|
for j in host.interfaces:
|
|
if j.ifname == str(u):
|
|
if j.iftype == 'ethernet':
|
|
i.dpdksupport = [p.dpdksupport for p in
|
|
host.ports if
|
|
j.uuid ==
|
|
p.interface_uuid]
|
|
elif j.iftype == 'ae':
|
|
for ae_u in j.uses:
|
|
for k in host.interfaces:
|
|
if k.ifname == str(ae_u):
|
|
i.dpdksupport = [
|
|
p.dpdksupport for p in
|
|
host.ports if
|
|
k.uuid ==
|
|
p.interface_uuid]
|
|
elif i.iftype == 'ae':
|
|
for u in i.uses:
|
|
for j in host.interfaces:
|
|
if j.ifname == str(u):
|
|
i.dpdksupport = [p.dpdksupport for p in
|
|
host.ports if
|
|
j.uuid == p.interface_uuid]
|
|
|
|
host.interfaces.sort(key=lambda f: (f.ifname))
|
|
return host.interfaces
|
|
|
|
def get_context_data(self, request):
|
|
context = super(OverviewTab, self).get_context_data(request)
|
|
try:
|
|
context['host'] = self.tab_group.kwargs['host']
|
|
except Exception:
|
|
redirect = reverse('horizon:admin:inventory:index')
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve inventory details.'),
|
|
redirect=redirect)
|
|
return context
|
|
|
|
|
|
class CpuFunctionsTab(tabs.TableTab):
|
|
table_classes = (cpufunctions_tables.CpuFunctionsTable, )
|
|
name = _("Processor")
|
|
slug = "cpufunctions"
|
|
template_name = ("admin/inventory/_detail_cpufunctions.html")
|
|
|
|
def get_cpufunctions_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.core_assignment
|
|
|
|
def get_context_data(self, request):
|
|
context = super(CpuFunctionsTab, self).get_context_data(request)
|
|
try:
|
|
context['host'] = self.tab_group.kwargs['host']
|
|
except Exception:
|
|
redirect = reverse('horizon:admin:inventory:index')
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve inventory details.'),
|
|
redirect=redirect)
|
|
return context
|
|
|
|
|
|
class MemorysTab(tabs.TableTab):
|
|
table_classes = (memory_tables.MemorysTable, )
|
|
name = _("Memory")
|
|
slug = "memorys"
|
|
template_name = ("admin/inventory/_detail_memorys.html")
|
|
|
|
def get_memorys_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
host.memorys.sort(key=lambda f: (f.numa_node))
|
|
return host.memorys
|
|
|
|
|
|
class StorageTab(tabs.TableTab):
|
|
table_classes = (storage_tables.DisksTable,
|
|
storage_tables.StorageVolumesTable,
|
|
storage_tables.PhysicalVolumesTable,
|
|
storage_tables.LocalVolumeGroupsTable,
|
|
storage_tables.PartitionsTable,)
|
|
name = _("Storage")
|
|
slug = "storages"
|
|
template_name = ("admin/inventory/_detail_storages.html")
|
|
|
|
def get_disks_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.disks
|
|
|
|
def get_storagevolumes_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.stors
|
|
|
|
def get_physicalvolumes_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.pvs
|
|
|
|
def get_localvolumegroups_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.lvgs
|
|
|
|
def get_partitions_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
return host.partitions
|
|
|
|
def get_context_data(self, request):
|
|
context = super(StorageTab, self).get_context_data(request)
|
|
try:
|
|
context['host'] = self.tab_group.kwargs['host']
|
|
except Exception:
|
|
redirect = reverse('horizon:admin:inventory:index')
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve inventory details.'),
|
|
redirect=redirect)
|
|
|
|
context['cinder_backend'] = api.sysinv.get_cinder_backend(request)
|
|
|
|
return context
|
|
|
|
|
|
class PortsTab(tabs.TableTab):
|
|
table_classes = (port_tables.PortsTable, )
|
|
name = _("Ports")
|
|
slug = "ports"
|
|
template_name = ("admin/inventory/_detail_ports.html")
|
|
|
|
def get_ports_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
host.ports.sort(key=lambda f: (f.name))
|
|
return host.ports
|
|
|
|
|
|
class InterfacesTab(tabs.TableTab):
|
|
table_classes = (interface_tables.InterfacesTable, )
|
|
name = _("Interfaces")
|
|
slug = "interfaces"
|
|
template_name = ("admin/inventory/_detail_interfaces.html")
|
|
|
|
def get_interfaces_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
|
|
# add 'ports' member to interface class for easier mgmt in table
|
|
if host.interfaces:
|
|
for i in host.interfaces:
|
|
i.host_id = host.id
|
|
|
|
port_data = \
|
|
map(list, zip(*[(p.get_port_display_name(),
|
|
p.neighbours) for p in host.ports if
|
|
i.uuid == p.interface_uuid]))
|
|
|
|
if port_data:
|
|
# Default interface
|
|
i.portNameList = port_data[0]
|
|
i.portNeighbourList = port_data[1]
|
|
else:
|
|
# Non-default interface, no port data
|
|
i.portNameList = []
|
|
i.portNeighbourList = []
|
|
|
|
if i.iftype == 'ethernet':
|
|
i.dpdksupport = [p.dpdksupport for p in host.ports if
|
|
i.uuid == p.interface_uuid]
|
|
elif i.iftype == 'vlan':
|
|
for u in i.uses:
|
|
for j in host.interfaces:
|
|
if j.ifname == str(u):
|
|
if j.iftype == 'ethernet':
|
|
i.dpdksupport = [p.dpdksupport for p in
|
|
host.ports if
|
|
j.uuid ==
|
|
p.interface_uuid]
|
|
elif j.iftype == 'ae':
|
|
for ae_u in j.uses:
|
|
for k in host.interfaces:
|
|
if k.ifname == str(ae_u):
|
|
i.dpdksupport = [
|
|
p.dpdksupport for p in
|
|
host.ports if
|
|
k.uuid ==
|
|
p.interface_uuid]
|
|
elif i.iftype == 'ae':
|
|
for u in i.uses:
|
|
for j in host.interfaces:
|
|
if j.ifname == str(u):
|
|
i.dpdksupport = [p.dpdksupport for p in
|
|
host.ports if
|
|
j.uuid == p.interface_uuid]
|
|
|
|
host.interfaces.sort(key=lambda f: (f.ifname))
|
|
return host.interfaces
|
|
|
|
|
|
class SensorTab(tabs.TableTab):
|
|
table_classes = (sensor_tables.SensorsTable,
|
|
sensor_tables.SensorGroupsTable,)
|
|
name = _("Sensors")
|
|
slug = "sensors"
|
|
template_name = ("admin/inventory/_detail_sensors.html")
|
|
|
|
def get_sensorgroups_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
|
|
# To extract the sensors in this group
|
|
if host.sensorgroups:
|
|
for i in host.sensorgroups:
|
|
i.host_id = host.id
|
|
i.sensors = [s.uuid for s in host.sensors if
|
|
i.uuid == s.sensorgroup_uuid]
|
|
i.sensorNameList = [s.get_sensor_display_name()
|
|
for s in host.sensors
|
|
if i.uuid == s.sensorgroup_uuid]
|
|
|
|
return host.sensorgroups
|
|
|
|
def get_sensors_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
if host.sensors:
|
|
for i in host.sensors:
|
|
i.host_id = host.id
|
|
i.sensorgroups = [s.uuid for s in host.sensorgroups if
|
|
i.sensorgroup_uuid == s.uuid]
|
|
i.sensorgroupNameList = [s.get_sensorgroup_display_name()
|
|
for s in host.sensorgroups
|
|
if i.sensorgroup_uuid == s.uuid]
|
|
return host.sensors
|
|
# .sort(key=lambda s: (s.status))
|
|
|
|
def get_context_data(self, request):
|
|
context = super(SensorTab, self).get_context_data(request)
|
|
|
|
sensors = self.get_sensors_data()
|
|
|
|
context["critical"] = len(
|
|
[s for s in sensors if (s.status == 'critical' and
|
|
s.suppress != 'True')])
|
|
context["major"] = len([s for s in sensors if (s.status == 'major' and
|
|
s.suppress != 'True')])
|
|
context["minor"] = len([s for s in sensors if (s.status == 'minor' and
|
|
s.suppress != 'True')])
|
|
context["suppressed"] = \
|
|
len([s for s in sensors if s.suppress == 'True'])
|
|
context["total"] = len(sensors)
|
|
|
|
try:
|
|
context['host'] = self.tab_group.kwargs['host']
|
|
except Exception:
|
|
redirect = reverse('horizon:admin:inventory:index')
|
|
exceptions.handle(self.request,
|
|
_('Unable to retrieve inventory details.'),
|
|
redirect=redirect)
|
|
return context
|
|
|
|
|
|
class DevicesTab(tabs.TableTab):
|
|
table_classes = (device_tables.DevicesTable, )
|
|
name = _("Devices")
|
|
slug = "devices"
|
|
template_name = ("admin/inventory/_detail_devices.html")
|
|
|
|
def get_devices_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
if host.devices:
|
|
for d in host.devices:
|
|
d.host_id = host.id
|
|
return host.devices
|
|
|
|
|
|
class LldpTab(tabs.TableTab):
|
|
table_classes = (lldp_tables.LldpNeighboursTable,)
|
|
name = _("LLDP")
|
|
slug = "lldp"
|
|
template_name = ("admin/inventory/_detail_lldp.html")
|
|
|
|
def get_neighbours_data(self):
|
|
host = self.tab_group.kwargs['host']
|
|
# The LLDP neighbours data have been retrieved when HostDetailTabs
|
|
# is loaded
|
|
host.lldpneighbours.sort(key=lambda f: f.port_name)
|
|
return host.lldpneighbours
|
|
|
|
|
|
class HostDetailTabs(tabs.TabGroup):
|
|
slug = "inventory_details"
|
|
tabs = (OverviewTab, CpuFunctionsTab, MemorysTab, StorageTab, PortsTab,
|
|
InterfacesTab, LldpTab, SensorTab, DevicesTab, )
|
|
sticky = True
|