5 from datetime import datetime, timedelta
9 from monitor.database.info.model import *
10 from monitor.database.info.interface import *
15 from PLC.Parameter import Parameter, Mixed
17 def Parameter(a = None, b = None): pass
18 def Mixed(a = None, b = None, c = None): pass
20 def export_to_docbook(**kwargs):
33 # Inspect method. Remove self from the argument list.
34 max_args = method.func_code.co_varnames[0:method.func_code.co_argcount]
35 defaults = method.func_defaults
38 min_args = max_args[0:len(max_args) - len(defaults)]
40 defaults = tuple([None for arg in min_args]) + defaults
41 return (min_args, max_args, defaults)
43 keywords['name'] = method.__name__
44 keywords['args'] = args
46 method.__setattr__(arg, keywords[arg])
49 method.__setattr__(arg, kwargs[arg])
55 class MonitorXmlrpcServerMethods:
57 def listMethods(self):
58 mod = MonitorXmlrpcServer()
61 if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
65 def convert_datetime(d, keys=None):
71 if type(d[k]) == type(n):
72 ret[k] = time.mktime(d[k].utctimetuple())
76 class MonitorXmlrpcServer(object):
79 def listMethods(self):
80 mod = MonitorXmlrpcServer()
83 if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
89 params, method = xmlrpclib.loads(cherrypy.request.body.read())
91 if method == "xmlrpc":
93 raise AssertionError("method cannot be 'xmlrpc'")
94 # Get the function and make sure it's exposed.
95 method = getattr(self, method, None)
96 # Use the same error message to hide private method names
97 if method is None or not getattr(method, "exposed", False):
98 raise AssertionError("method does not exist")
101 # Call the method, convert it into a 1-element tuple
102 # as expected by dumps
103 response = method(*params)
106 response = xmlrpclib.dumps((response,), methodresponse=1, allow_none=1)
107 except xmlrpclib.Fault, fault:
108 # Can't marshal the result
109 response = xmlrpclib.dumps(fault, allow_none=1)
111 # Some other error; send back some error info
112 response = xmlrpclib.dumps(
113 xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
116 cherrypy.response.headers["Content-Type"] = "text/xml"
119 # User-defined functions must use cherrypy.expose; turbogears.expose
120 # does additional checking of the response type that we don't want.
122 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
124 returns=Parameter(bool, 'True if successful'))
125 def upAndRunning(self):
126 """ This call can indicate to a script whether the server is up
127 and running before trying any more sophisticated operations. """
130 # SITES ------------------------------------------------------------
133 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
134 accepts=[Parameter(dict, "Auth struct")],
135 returns=Parameter(list, 'array of SiteStatus records'))
136 def getSiteStatus(self, auth):
137 """ This call returns a list that includes the status and observations
138 of all sites, including those blacklisted. At this time, there is no
139 indication which sites are blacklisted from this list. """
141 sites = HistorySiteRecord.query.all()
143 d = q.to_dict(exclude=['timestamp', 'version', ])
144 d = convert_datetime(d, ['last_checked', 'last_changed', 'message_created'])
149 @export_to_docbook(roles=['admin'],
150 accepts=[Parameter(dict, "Auth struct")],
151 returns=Parameter(bool, 'True on success.'))
152 def clearSitePenalty(self, auth, loginbase):
153 """ Rather than waiting for monitor to run automatically, this call
154 will manually clear a site's penalties. """
155 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
156 sitehist.clearPenalty()
157 #sitehist.applyPenalty()
158 #sitehist.sendMessage('clear_penalty')
159 sitehist.closeTicket()
163 @export_to_docbook(roles=['admin'],
164 accepts=[Parameter(dict, "Auth struct")],
165 returns=Parameter(bool, 'True on success.'))
166 def increaseSitePenalty(self, auth, loginbase):
167 """ Rather than waiting for monitor to run automatically, this call
168 will manually increase a site's penalties."""
169 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
170 sitehist.increasePenalty()
171 #sitehist.applyPenalty()
172 #sitehist.sendMessage('increase_penalty')
175 # NODES ------------------------------------------------------------
178 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
179 accepts=[Parameter(dict, "Auth struct")],
180 returns=Parameter(list, 'array of NodeStatus records.'))
181 def getNodeStatus(self, auth):
182 """ This call returns a list of all nodes, including those
183 blacklisted. The current observation and recorded status of each node
186 sites = HistoryNodeRecord.query.all()
188 d = q.to_dict(exclude=['timestamp', 'version', ])
189 d = convert_datetime(d, ['last_checked', 'last_changed',])
194 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
195 accepts=[Parameter(dict, "Auth struct")],
196 returns=Parameter(bool, 'True on success.'))
197 def getRecentActions(self, auth, loginbase=None, hostname=None):
198 """ Monitor takes various actions on sites (such as applying
199 penalties) and nodes (such as repairing a node installation via
200 BootManager). As well, it makes a log of every email message sent
201 out, or believed to be sent. This call returns a list of all actions,
202 filtered on site or for a specific node. """
206 # BLACKLIST ------------------------------------------------------------
209 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
210 accepts=[Parameter(dict, "Auth struct")],
211 returns=Parameter(bool, 'True on success.'))
212 def getBlacklist(self, auth):
213 """ Return a list of all nodes and sites that are excluded from
214 penalties. Currently there is no way to exclude a node or site
215 from being monitored. """
216 bl = BlacklistRecord.query.all()
219 d = q.to_dict(exclude=['timestamp', 'version', 'id', ])
220 d = convert_datetime(d, ['date_created'])
226 @export_to_docbook(roles=['admin'],
227 accepts=[Parameter(dict, "Auth struct"),
228 Parameter(str, "hostname"),
229 Parameter(int, "expires number of seconds from time.now()")],
230 returns=Parameter(bool, 'True on success.'))
231 def addHostToBlacklist(self, auth, hostname, expires=0):
232 """ Add a host to the blacklist, with an optional expiration time"""
233 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
237 @export_to_docbook(roles=['admin'],
238 accepts=[Parameter(dict, "Auth struct"),
239 Parameter(str, "loginbase"),
240 Parameter(int, "expires number of seconds from time.now()")],
241 returns=Parameter(bool, 'True on success.'))
242 def addSiteToBlacklist(self, auth, loginbase, expires=0):
243 """ Add a site to the blacklist, with an optional expiration time"""
244 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
248 @export_to_docbook(roles=['admin'],
249 accepts=[Parameter(dict, "Auth struct"),
250 Parameter(str, "loginbase"),
251 Parameter(str, "hostname"),],
252 returns=Parameter(bool, 'True on success.'))
253 def deleteFromBlacklist(self, auth, loginbase=None, hostname=None):
254 """ Remove a host or site from the blacklist """
255 if (loginbase==None and hostname == None) or (loginbase != None and hostname != None):
256 raise Exception("Please specify a single record to delete: either hostname or loginbase")
257 elif loginbase != None:
258 bl = BlacklistRecord.get_by(loginbase=loginbase)
260 elif hostname != None:
261 bl = BlacklistRecord.get_by(hostname=hostname)