Add support for new Tempmon Appliance table, etc.
This commit is contained in:
parent
aa97a36167
commit
40a8761feb
|
@ -44,8 +44,10 @@
|
|||
<%def name="render_main_fields(form)">
|
||||
${form.render_field_readonly('client')}
|
||||
${form.render_field_readonly('config_key')}
|
||||
${form.render_field_readonly('appliance')}
|
||||
${form.render_field_readonly('appliance_type')}
|
||||
${form.render_field_readonly('description')}
|
||||
${form.render_field_readonly('location')}
|
||||
${form.render_field_readonly('device_path')}
|
||||
${form.render_field_readonly('notes')}
|
||||
${form.render_field_readonly('enabled')}
|
||||
|
|
|
@ -30,6 +30,7 @@ from .core import MasterView
|
|||
|
||||
|
||||
def includeme(config):
|
||||
config.include('tailbone.views.tempmon.appliances')
|
||||
config.include('tailbone.views.tempmon.clients')
|
||||
config.include('tailbone.views.tempmon.probes')
|
||||
config.include('tailbone.views.tempmon.readings')
|
||||
|
|
93
tailbone/views/tempmon/appliances.py
Normal file
93
tailbone/views/tempmon/appliances.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2018 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
# Rattail is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
Views for tempmon appliances
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
from rattail_tempmon.db import model as tempmon
|
||||
|
||||
from webhelpers2.html import HTML, tags
|
||||
|
||||
from tailbone.views.tempmon import MasterView
|
||||
|
||||
|
||||
class TempmonApplianceView(MasterView):
|
||||
"""
|
||||
Master view for tempmon appliances.
|
||||
"""
|
||||
model_class = tempmon.Appliance
|
||||
model_title = "TempMon Appliance"
|
||||
model_title_plural = "TempMon Appliances"
|
||||
route_prefix = 'tempmon.appliances'
|
||||
url_prefix = '/tempmon/appliances'
|
||||
|
||||
grid_columns = [
|
||||
'name',
|
||||
'location',
|
||||
]
|
||||
|
||||
form_fields = [
|
||||
'name',
|
||||
'location',
|
||||
'clients',
|
||||
'probes',
|
||||
]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(TempmonApplianceView, self).configure_grid(g)
|
||||
g.set_sort_defaults('name')
|
||||
|
||||
def configure_form(self, f):
|
||||
super(TempmonApplianceView, self).configure_form(f)
|
||||
|
||||
# clients
|
||||
if self.viewing:
|
||||
f.set_renderer('clients', self.render_clients)
|
||||
else:
|
||||
f.remove_field('clients')
|
||||
|
||||
# probes
|
||||
if self.viewing:
|
||||
f.set_renderer('probes', self.render_probes)
|
||||
elif self.creating or self.editing:
|
||||
f.remove_field('probes')
|
||||
|
||||
def render_clients(self, appliance, field):
|
||||
clients = {}
|
||||
for probe in appliance.probes:
|
||||
if probe.client.uuid not in clients:
|
||||
clients[probe.client.uuid] = probe.client
|
||||
|
||||
if not clients:
|
||||
return ""
|
||||
|
||||
clients = sorted(clients.values(), key=lambda client: client.hostname)
|
||||
items = [HTML.tag('li', c=[tags.link_to(client.hostname, self.request.route_url('tempmon.clients.view', uuid=client.uuid))])
|
||||
for client in clients]
|
||||
return HTML.tag('ul', c=items)
|
||||
|
||||
|
||||
def includeme(config):
|
||||
TempmonApplianceView.defaults(config)
|
|
@ -28,14 +28,11 @@ from __future__ import unicode_literals, absolute_import
|
|||
|
||||
import subprocess
|
||||
|
||||
import six
|
||||
|
||||
from rattail_tempmon.db import model as tempmon
|
||||
|
||||
import colander
|
||||
from webhelpers2.html import HTML, tags
|
||||
|
||||
from tailbone import grids
|
||||
from tailbone.views.tempmon import MasterView
|
||||
|
||||
|
||||
|
@ -68,6 +65,7 @@ class TempmonClientView(MasterView):
|
|||
'location',
|
||||
'disk_type',
|
||||
'delay',
|
||||
'appliances',
|
||||
'probes',
|
||||
'notes',
|
||||
'enabled',
|
||||
|
@ -119,6 +117,12 @@ class TempmonClientView(MasterView):
|
|||
# delay
|
||||
f.set_helptext('delay', tempmon.Client.delay.__doc__)
|
||||
|
||||
# appliances
|
||||
if self.viewing:
|
||||
f.set_renderer('appliances', self.render_appliances)
|
||||
else:
|
||||
f.remove_field('appliances')
|
||||
|
||||
# probes
|
||||
if self.viewing:
|
||||
f.set_renderer('probes', self.render_probes)
|
||||
|
@ -149,44 +153,19 @@ class TempmonClientView(MasterView):
|
|||
if query.count():
|
||||
raise colander.Invalid(node, "Config key must be unique")
|
||||
|
||||
def render_probes(self, client, field):
|
||||
if not client.probes:
|
||||
def render_appliances(self, client, field):
|
||||
appliances = {}
|
||||
for probe in client.probes:
|
||||
if probe.appliance and probe.appliance.uuid not in appliances:
|
||||
appliances[probe.appliance.uuid] = probe.appliance
|
||||
|
||||
if not appliances:
|
||||
return ""
|
||||
|
||||
route_prefix = self.get_route_prefix()
|
||||
view_url = lambda p, i: self.request.route_url('tempmon.probes.view', uuid=p.uuid)
|
||||
actions = [
|
||||
grids.GridAction('view', icon='zoomin', url=view_url),
|
||||
]
|
||||
if self.request.has_perm('tempmon.probes.edit'):
|
||||
url = lambda p, i: self.request.route_url('tempmon.probes.edit', uuid=p.uuid)
|
||||
actions.append(grids.GridAction('edit', icon='pencil', url=url))
|
||||
|
||||
g = grids.Grid(
|
||||
key='{}.probes'.format(route_prefix),
|
||||
data=client.probes,
|
||||
columns=[
|
||||
'description',
|
||||
'critical_temp_min',
|
||||
'good_temp_min',
|
||||
'good_temp_max',
|
||||
'critical_temp_max',
|
||||
'status',
|
||||
'enabled',
|
||||
],
|
||||
labels={
|
||||
'critical_temp_min': "Crit. Min",
|
||||
'good_temp_min': "Good Min",
|
||||
'good_temp_max': "Good Max",
|
||||
'critical_temp_max': "Crit. Max",
|
||||
},
|
||||
url=lambda p: self.request.route_url('tempmon.probes.view', uuid=p.uuid),
|
||||
linked_columns=['description'],
|
||||
main_actions=actions,
|
||||
)
|
||||
g.set_enum('status', self.enum.TEMPMON_PROBE_STATUS)
|
||||
g.set_type('enabled', 'boolean')
|
||||
return HTML.literal(g.render_grid())
|
||||
appliances = sorted(appliances.values(), key=lambda a: a.name)
|
||||
items = [HTML.tag('li', c=[tags.link_to(a.name, self.request.route_url('tempmon.appliances.view', uuid=a.uuid))])
|
||||
for a in appliances]
|
||||
return HTML.tag('ul', c=items)
|
||||
|
||||
def delete_instance(self, client):
|
||||
# bulk-delete all readings first
|
||||
|
|
|
@ -28,7 +28,9 @@ from __future__ import unicode_literals, absolute_import
|
|||
|
||||
from rattail_tempmon.db import Session as RawTempmonSession
|
||||
|
||||
from tailbone import views
|
||||
from webhelpers2.html import HTML
|
||||
|
||||
from tailbone import views, grids
|
||||
from tailbone.db import TempmonSession
|
||||
|
||||
|
||||
|
@ -40,3 +42,45 @@ class MasterView(views.MasterView):
|
|||
|
||||
def get_bulk_delete_session(self):
|
||||
return RawTempmonSession()
|
||||
|
||||
def render_probes(self, obj, field):
|
||||
"""
|
||||
This method is used by Appliance and Client views.
|
||||
"""
|
||||
if not obj.probes:
|
||||
return ""
|
||||
|
||||
route_prefix = self.get_route_prefix()
|
||||
view_url = lambda p, i: self.request.route_url('tempmon.probes.view', uuid=p.uuid)
|
||||
actions = [
|
||||
grids.GridAction('view', icon='zoomin', url=view_url),
|
||||
]
|
||||
if self.request.has_perm('tempmon.probes.edit'):
|
||||
url = lambda p, i: self.request.route_url('tempmon.probes.edit', uuid=p.uuid)
|
||||
actions.append(grids.GridAction('edit', icon='pencil', url=url))
|
||||
|
||||
g = grids.Grid(
|
||||
key='{}.probes'.format(route_prefix),
|
||||
data=obj.probes,
|
||||
columns=[
|
||||
'description',
|
||||
'critical_temp_min',
|
||||
'good_temp_min',
|
||||
'good_temp_max',
|
||||
'critical_temp_max',
|
||||
'status',
|
||||
'enabled',
|
||||
],
|
||||
labels={
|
||||
'critical_temp_min': "Crit. Min",
|
||||
'good_temp_min': "Good Min",
|
||||
'good_temp_max': "Good Max",
|
||||
'critical_temp_max': "Crit. Max",
|
||||
},
|
||||
url=lambda p: self.request.route_url('tempmon.probes.view', uuid=p.uuid),
|
||||
linked_columns=['description'],
|
||||
main_actions=actions,
|
||||
)
|
||||
g.set_enum('status', self.enum.TEMPMON_PROBE_STATUS)
|
||||
g.set_type('enabled', 'boolean')
|
||||
return HTML.literal(g.render_grid())
|
||||
|
|
|
@ -61,6 +61,7 @@ class TempmonProbeView(MasterView):
|
|||
grid_columns = [
|
||||
'client',
|
||||
'config_key',
|
||||
'appliance',
|
||||
'appliance_type',
|
||||
'description',
|
||||
'device_path',
|
||||
|
@ -71,8 +72,10 @@ class TempmonProbeView(MasterView):
|
|||
form_fields = [
|
||||
'client',
|
||||
'config_key',
|
||||
'appliance',
|
||||
'appliance_type',
|
||||
'description',
|
||||
'location',
|
||||
'device_path',
|
||||
'critical_temp_max',
|
||||
'critical_max_timeout',
|
||||
|
@ -133,6 +136,18 @@ class TempmonProbeView(MasterView):
|
|||
f.set_widget('client_uuid', dfwidget.SelectWidget(values=client_values))
|
||||
f.set_label('client_uuid', "Tempmon Client")
|
||||
|
||||
# appliance
|
||||
f.set_renderer('appliance', self.render_appliance)
|
||||
if self.creating or self.editing:
|
||||
f.replace('appliance', 'appliance_uuid')
|
||||
appliances = self.Session.query(tempmon.Appliance)\
|
||||
.order_by(tempmon.Appliance.name)
|
||||
appliance_values = [(appliance.uuid, appliance.name)
|
||||
for appliance in appliances]
|
||||
appliance_values.insert(0, ('', "(none)"))
|
||||
f.set_widget('appliance_uuid', dfwidget.SelectWidget(values=appliance_values))
|
||||
f.set_label('appliance_uuid', "Appliance")
|
||||
|
||||
# appliance_type
|
||||
f.set_enum('appliance_type', self.enum.TEMPMON_APPLIANCE_TYPE)
|
||||
|
||||
|
@ -167,6 +182,14 @@ class TempmonProbeView(MasterView):
|
|||
url = self.request.route_url('tempmon.clients.view', uuid=client.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
def render_appliance(self, probe, field):
|
||||
appliance = probe.appliance
|
||||
if not appliance:
|
||||
return ""
|
||||
text = six.text_type(appliance)
|
||||
url = self.request.route_url('tempmon.appliances.view', uuid=appliance.uuid)
|
||||
return tags.link_to(text, url)
|
||||
|
||||
def delete_instance(self, probe):
|
||||
# bulk-delete all readings first
|
||||
readings = self.Session.query(tempmon.Reading)\
|
||||
|
|
Loading…
Reference in a new issue