--- /dev/null
+import sys
+import xmlrpclib
+import cherrypy
+import turbogears
+from datetime import datetime, timedelta
+import time
+
+from monitor.database.info.model import *
+from monitor.database.info.interface import *
+
+class MonitorXmlrpcServerMethods:
+ @cherrypy.expose
+ def listMethods(self):
+ mod = MonitorXmlrpcServer()
+ ret_list = []
+ for f in dir(mod):
+ if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
+ ret_list += [f]
+ return ret_list
+
+def convert_datetime(d, keys=None):
+ ret = d.copy()
+ n = datetime.now()
+ if keys == None:
+ keys = d.keys()
+ for k in keys:
+ if type(d[k]) == type(n):
+ ret[k] = time.mktime(d[k].utctimetuple())
+
+ return ret
+
+class MonitorXmlrpcServer(object):
+
+ @cherrypy.expose
+ def listMethods(self):
+ mod = MonitorXmlrpcServer()
+ ret_list = []
+ for f in dir(mod):
+ if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
+ ret_list += [f]
+ return ret_list
+
+ @turbogears.expose()
+ def XMLRPC(self):
+ params, method = xmlrpclib.loads(cherrypy.request.body.read())
+ try:
+ if method == "xmlrpc":
+ # prevent recursion
+ raise AssertionError("method cannot be 'xmlrpc'")
+ # Get the function and make sure it's exposed.
+ method = getattr(self, method, None)
+ # Use the same error message to hide private method names
+ if method is None or not getattr(method, "exposed", False):
+ raise AssertionError("method does not exist")
+
+ session.clear()
+ # Call the method, convert it into a 1-element tuple
+ # as expected by dumps
+ response = method(*params)
+
+ session.flush()
+ response = xmlrpclib.dumps((response,), methodresponse=1, allow_none=1)
+ except xmlrpclib.Fault, fault:
+ # Can't marshal the result
+ response = xmlrpclib.dumps(fault, allow_none=1)
+ except:
+ # Some other error; send back some error info
+ response = xmlrpclib.dumps(
+ xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
+ )
+
+ cherrypy.response.headers["Content-Type"] = "text/xml"
+ return response
+
+ # User-defined functions must use cherrypy.expose; turbogears.expose
+ # does additional checking of the response type that we don't want.
+ @cherrypy.expose
+ def upAndRunning(self):
+ return True
+
+ # SITES ------------------------------------------------------------
+
+ @cherrypy.expose
+ def getSiteStatus(self, auth):
+ ret_list = []
+ sites = HistorySiteRecord.query.all()
+ for q in sites:
+ d = q.to_dict(exclude=['timestamp', 'version', ])
+ d = convert_datetime(d, ['last_checked', 'last_changed', 'message_created'])
+ ret_list.append(d)
+ return ret_list
+
+ @cherrypy.expose
+ def clearSitePenalty(self, auth, loginbase):
+ sitehist = SiteInterface.get_or_make(loginbase=loginbase)
+ sitehist.clearPenalty()
+ #sitehist.applyPenalty()
+ #sitehist.sendMessage('clear_penalty')
+ sitehist.closeTicket()
+ return True
+
+ @cherrypy.expose
+ def increaseSitePenalty(self, auth, loginbase):
+ sitehist = SiteInterface.get_or_make(loginbase=loginbase)
+ sitehist.increasePenalty()
+ #sitehist.applyPenalty()
+ #sitehist.sendMessage('increase_penalty')
+ return True
+
+ # NODES ------------------------------------------------------------
+
+ @cherrypy.expose
+ def getNodeStatus(self, auth):
+ ret_list = []
+ sites = HistoryNodeRecord.query.all()
+ for q in sites:
+ d = q.to_dict(exclude=['timestamp', 'version', ])
+ d = convert_datetime(d, ['last_checked', 'last_changed',])
+ ret_list.append(d)
+ return ret_list
+
+ @cherrypy.expose
+ def getRecentActions(self, auth, loginbase=None, hostname=None):
+ ret_list = []
+ return ret_list
+
+ # BLACKLIST ------------------------------------------------------------
+
+ @cherrypy.expose
+ def getBlacklist(self, auth):
+ bl = BlacklistRecord.query.all()
+ ret_list = []
+ for q in bl:
+ d = q.to_dict(exclude=['timestamp', 'version', 'id', ])
+ d = convert_datetime(d, ['date_created'])
+ ret_list.append(d)
+
+ return ret_list
+ # datetime.datetime.fromtimestamp(time.mktime(time.strptime(mytime, time_format)))
+
+ @cherrypy.expose
+ def addHostToBlacklist(self, auth, hostname, expires=0):
+ bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
+ return True
+
+ @cherrypy.expose
+ def addSiteToBlacklist(self, auth, loginbase, expires=0):
+ bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
+ return True
+
+ @cherrypy.expose
+ def deleteFromBlacklist(self, auth, loginbase=None, hostname=None):
+ if (loginbase==None and hostname == None) or (loginbase != None and hostname != None):
+ raise Exception("Please specify a single record to delete: either hostname or loginbase")
+ elif loginbase != None:
+ bl = BlacklistRecord.get_by(loginbase=loginbase)
+ bl.delete()
+ elif hostname != None:
+ bl = BlacklistRecord.get_by(hostname=hostname)
+ bl.delete()
+ return True
--- /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 List"
+from monitor.util import diff_time
+from time import mktime
+from links import *
+?>
+<html py:layout="'sitemenu.kid'"
+ xmlns:py="http://purl.org/kid/ns#"
+ xmlns:mochi="http://www.mochi.org">
+
+ <div py:match="item.tag == 'content'">
+ <h3>Node History : ${hostname}</h3>
+ <table width="100%">
+ <tbody>
+ <tr>
+ <td>
+ <table id="sortable_table" class="datagrid" border="1" width="100%">
+ <thead>
+ <tr>
+ <th mochi:format="int"></th>
+ <!--th>Site</th>
+ <th>pcu</th-->
+ <th>Hostname</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></td>
+ <!--td id="site-${node.site.status}">
+ <a href="${link('pcuview', loginbase=node.loginbase)}">${node.loginbase}</a>
+ </td>
+ <td width="20%" nowrap='true' align='center' id="status-${node.pcu_short_status}">
+ <div id="links">
+ <a class="info" py:if="'error' in node.pcu_short_status"
+ href="${link('pcuview', pcuid=node.plc_pcuid)}">
+ Error<span><pre>${node.pcu.reboot_trial_status}</pre></span></a>
+ <a py:if="'error' not in node.pcu_short_status and 'none' not in node.pcu_short_status"
+ href="${link('pcuview', pcuid=node.plc_pcuid)}"
+ py:content="node.pcu_short_status">Reboot Status</a>
+ <span py:if="'none' in node.pcu_short_status"
+ py:content="node.pcu_short_status">Reboot Status</span>
+ </div>
+ </td-->
+ <td id="node-${node.observed_status}" nowrap="true">
+ <a target="_top" href="${link('pcuview', hostname=node.hostname)}" py:content="node.hostname">your.host.org</a></td>
+ <td nowrap="true" py:content="node.kernel"></td>
+ <td py:content="node.date_checked"></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 Site History List"
+from monitor.util import diff_time
+from time import mktime
+from links import *
+?>
+<html py:layout="'sitemenu.kid'"
+ xmlns:py="http://purl.org/kid/ns#"
+ xmlns:mochi="http://www.mochi.org">
+
+ <div py:match="item.tag == 'content'">
+ <h3>Site History : ${loginbase}</h3>
+ <table width="100%">
+ <tbody>
+ <tr>
+ <td>
+ <table id="sortable_table" class="datagrid" border="1" width="100%">
+ <thead>
+ <tr>
+ <th mochi:format="int"></th>
+ <th>Site name</th>
+ <th>Enabled</th>
+ <th>Penalty</th>
+ <th mochi:format="int">Slices/Max</th>
+ <th mochi:format="int">Nodes/Total</th>
+ <th>Date Checked</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr py:for="i,site in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
+ <td></td>
+ <td nowrap="true">
+ <div class='oneline'>
+ <a class='left' href="${link('pcuview', loginbase=site.loginbase)}">${site.loginbase}</a>
+ <a class='right' href="${plc_site_uri(site.loginbase)}">
+ <img style='display: inline' border='0' src="static/images/extlink.gif" align='right'/></a>
+ </div>
+ </td>
+ <td py:content="site.enabled"></td>
+ <td id="site-${site.penalty_level}">${site.penalty_level}</td>
+ <td>${site.slices_used}/${site.slices_total}</td>
+ <td>${site.nodes_up} / ${site.nodes_total}</td>
+ <td id="site-${site.status}" py:content="diff_time(mktime(site.last_changed.timetuple()))"></td>
+ <td py:content="site.timestamp"></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+</html>