# from monitorweb import model
# import logging
# log = logging.getLogger("monitorweb.controllers")
+from monitor.database.info.model import *
+from pcucontrol import reboot
+
+def format_ports(pcu):
+ retval = []
+ if pcu.port_status and len(pcu.port_status.keys()) > 0 :
+ obj = reboot.model_to_object(pcu.plc_pcu_stats['model'])
+ for port in obj.supported_ports:
+ state = pcu.port_status[str(port)]
+ retval.append( (port, state) )
+
+ if retval == []:
+ retval = [( "Closed/Filtered", "state" )]
+
+ return retval
+
+def format_pcu_shortstatus(pcu):
+ status = "error"
+ if pcu.reboot_trial_status == str(0):
+ status = "ok"
+ elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
+ status = pcu.reboot_trial_status
+ else:
+ status = "error"
+
+ return status
class Root(controllers.RootController):
- @expose(template="monitorweb.templates.welcome")
- def index(self):
- import time
- # log.debug("Happy TurboGears Controller Responding For Duty")
- flash("Your application is now running")
- return dict(now=time.ctime())
+ @expose(template="monitorweb.templates.welcome")
+ def index(self):
+ import time
+ # log.debug("Happy TurboGears Controller Responding For Duty")
+ flash("Your application is now running")
+ return dict(now=time.ctime())
+
+ @expose(template="monitorweb.templates.nodelist")
+ def node(self, filter='BOOT'):
+ import time
+ fbquery = FindbadNodeRecord.get_all_latest()
+ query = []
+ filtercount = {'DOWN' : 0, 'BOOT': 0, 'DEBUG' : 0, 'neverboot' : 0, 'pending' : 0, 'all' : 0}
+ for node in fbquery:
+ if node.plc_pcuid:
+ pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid).first()
+ if pcu:
+ node.pcu_status = pcu.reboot_trial_status
+ else:
+ node.pcu_status = "nodata"
+ else:
+ node.pcu_status = "nopcu"
+
+ if node.kernel_version:
+ node.kernel = node.kernel_version.split()[2]
+ else:
+ node.kernel = ""
+
+ # NOTE: count filters
+ if node.observed_status != 'DOWN':
+ filtercount[node.observed_status] += 1
+ else:
+ if node.plc_node_stats['last_contact'] != None:
+ filtercount[node.observed_status] += 1
+ else:
+ filtercount['neverboot'] += 1
+
+ # NOTE: apply filter
+ if filter == node.observed_status:
+ if filter == "DOWN":
+ if node.plc_node_stats['last_contact'] != None:
+ query.append(node)
+ else:
+ query.append(node)
+ elif filter == "neverboot":
+ if node.plc_node_stats['last_contact'] == None:
+ query.append(node)
+ elif filter == "pending":
+ # TODO: look in message logs...
+ pass
+ elif filter == "all":
+ query.append(node)
+
+ return dict(now=time.ctime(), query=query, fc=filtercount)
+
+ @expose(template="monitorweb.templates.pculist")
+ def pcu(self, filter='all'):
+ import time
+ fbquery = FindbadPCURecord.get_all_latest()
+ query = []
+ filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
+ for node in fbquery:
+
+ # NOTE: count filter
+ if node.reboot_trial_status == str(0):
+ filtercount['ok'] += 1
+ elif node.reboot_trial_status == 'NetDown' or node.reboot_trial_status == 'Not_Run':
+ filtercount[node.reboot_trial_status] += 1
+ else:
+ filtercount['pending'] += 1
+
+ print reboot.pcu_name(node.plc_pcu_stats)
+ node.ports = format_ports(node)
+ node.status = format_pcu_shortstatus(node)
+
+ # NOTE: apply filter
+ if filter == "all":
+ query.append(node)
+ elif filter == "ok" and node.reboot_trial_status == str(0):
+ query.append(node)
+ elif filter == node.reboot_trial_status:
+ query.append(node)
+ elif filter == "pending":
+ # TODO: look in message logs...
+ if node.reboot_trial_status != str(0) and \
+ node.reboot_trial_status != 'NetDown' and \
+ node.reboot_trial_status != 'Not_Run':
+
+ query.append(node)
+
+ return dict(query=query, fc=filtercount)
+
+ @expose(template="monitorweb.templates.pculist")
+ def site(self, filter='all'):
+ filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
+ return dict(query=[], fc=filtercount)
+
+ @expose(template="monitorweb.templates.pculist")
+ def action(self, filter='all'):
+ filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
+ return dict(query=[], fc=filtercount)
padding: 0;\r
}\r
\r
-td, th {padding:3px;border:none;}\r
+td, th {padding:2px;border:none;}\r
tr th {text-align:left;background-color:#f0f0f0;color:#333;}\r
tr.odd td {background-color:#edf3fe;}\r
tr.even td {background-color:#fff;}\r
color: #369;\r
}\r
\r
+#portopen { background-color: lightgreen; }\r
+#portclosed { background-color: indianred; }\r
+#portfiltered { background-color: gold; }\r
+\r
+#dns-DNS-OK { background-color: lightgreen; }\r
+#dns-NOHOSTNAME { background-color: white; }\r
+#dns-DNS-MISMATCH { background-color: gold; }\r
+#dns-DNS-NOENTRY { background-color: indianred; }\r
+#dns-NO-DNS-OR-IP { background-color: indianred; }\r
+\r
+#status-NetDown { background-color: lightgrey; }\r
+#status-Not_Run { background-color: lightgrey; }\r
+#status-ok { background-color: darkseagreen; }\r
+#status-0 { background-color: darkseagreen; }\r
+#status-error { background-color: indianred; width="200px"; }\r
\r
#main_content {\r
color: black;\r
.fielderror {\r
color: red;\r
font-weight: bold;\r
-}
\ No newline at end of file
+}\r
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?python
+layout_params['page_title'] = "Monitor Node View"
+?>
+<html py:layout="'sitemenu.kid'"
+ xmlns:py="http://purl.org/kid/ns#">
+
+ <div py:match="item.tag == 'content'">
+ <table width="100%">
+ <thead>
+ <tr>
+ <th><a href="${tg.url('node', filter='BOOT')}">Production(${fc['BOOT']})</a></th>
+ <th><a href="${tg.url('node', filter='DEBUG')}">Debug(${fc['DEBUG']})</a></th>
+ <th><a href="${tg.url('node', filter='DOWN')}">Down(${fc['DOWN']})</a></th>
+ <th><a href="${tg.url('node', filter='neverboot')}">Never Booted(${fc['neverboot']})</a></th>
+ <th><a href="${tg.url('node', filter='pending')}">Pending Reply(${fc['pending']})</a></th>
+ <th><a href="${tg.url('node', filter='all')}">All</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td colspan="5">
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Hostname</th>
+ <th>ping</th>
+ <th>ssh</th>
+ <th>pcu</th>
+ <th>status</th>
+ <th>kernel</th>
+ <th>last_contact</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr py:for="i,node in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
+ <td nowrap="true" py:content="node.hostname"></td>
+ <td py:content="node.ping_status"></td>
+ <td py:content="node.ssh_status"></td>
+ <td py:content="node.pcu_status"></td>
+ <td py:content="node.observed_status"></td>
+ <td nowrap="true" py:content="node.kernel"></td>
+ <td py:content="node.plc_node_stats['last_contact']"></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?python
+layout_params['page_title'] = "Monitor PCU View"
+from pcucontrol.reboot import pcu_name, model_to_object
+from monitor import config
+
+def plc_site_link(pcu):
+ return "https://" + config.MONITOR_HOSTNAME + "/db/sites/index.php?id=" + str(pcu['site_id'])
+
+def pcu_link(pcu):
+ return "https://" + config.MONITOR_HOSTNAME + "/db/sites/pcu.php?id=" + str(pcu['pcu_id'])
+
+?>
+<html py:layout="'sitemenu.kid'"
+ xmlns:py="http://purl.org/kid/ns#">
+
+ <div py:match="item.tag == 'content'">
+ <table width="100%">
+ <thead>
+ <tr>
+ <th><a href="${tg.url('pcu', filter='ok')}">Ok(${fc['ok']})</a></th>
+ <th><a href="${tg.url('pcu', filter='Not_Run')}">Misconfigured(${fc['Not_Run']})</a></th>
+ <th><a href="${tg.url('pcu', filter='NetDown')}">Offline(${fc['NetDown']})</a></th>
+ <th><a href="${tg.url('pcu', filter='pending')}">Runtime Error(${fc['pending']})</a></th>
+ <th><a href="${tg.url('pcu', filter='all')}">All</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td colspan="5">
+ <table border="1">
+ <thead>
+ <tr>
+ <th>Site</th>
+ <th>PCU Name</th>
+ <th>Missing Fields</th>
+ <th>DNS Status</th>
+ <th>Port Status</th>
+ <th width="80%">Test Results</th>
+ <th>Model</th>
+ <th>Nodes</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr py:for="i,node in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
+ <td><a href="${plc_site_link(node.plc_pcu_stats)}">sitename</a></td>
+ <td nowrap="true" >
+ <a href="${pcu_link(node.plc_pcu_stats)}">${pcu_name(node.plc_pcu_stats)}</a></td>
+ <td py:content="node.entry_complete"></td>
+ <td id="dns-${node.dns_status}" py:content="node.dns_status"></td>
+ <td>
+ <span py:for="port,state in node.ports"
+ id="port${state}" py:content="'%s, ' % port">80</span>
+ </td>
+ <td id="status-${node.status}" py:content="node.reboot_trial_status"></td>
+ <td py:content="node.plc_pcu_stats['model']"></td>
+ <td py:content="len(node.plc_pcu_stats['node_ids'])"></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns:py="http://purl.org/kid/ns#">
+ <head>
+ <title>App Name - ${page_title}</title>
+ <link href="/static/css/style.css" type="text/css" rel="stylesheet" />
+ </head>
+
+ <body>
+ <h1>Monitor : ${page_title}</h1>
+ <table valign="top" border="1" bgcolor="white" align="center" width="800">
+ <tr>
+ <td>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="${tg.url('node')}">Nodes</a></th>
+ <th><a href="${tg.url('pcu')}">PCUs</a></th>
+ <th><a href="${tg.url('site')}">Sites</a></th>
+ <th><a href="${tg.url('action')}">Actions</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td colspan="4">
+ <content>Default content - this will be replaced by an element marked with
+ py:match="item.tag == 'content'"</content>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+ <div class="footer">Copywrite XYZ</div>
+ </body>
+</html>