5 from datetime import datetime, timedelta
7 from monitor.wrapper import plc
10 from monitor.database.info.model import *
11 from monitor.database.info.interface import *
16 from PLC.Parameter import Parameter, Mixed
18 def Parameter(a = None, b = None): pass
19 def Mixed(a = None, b = None, c = None): pass
21 def export_to_docbook(**kwargs):
34 # Inspect method. Remove self from the argument list.
35 max_args = method.func_code.co_varnames[0:method.func_code.co_argcount]
36 defaults = method.func_defaults
39 min_args = max_args[0:len(max_args) - len(defaults)]
41 defaults = tuple([None for arg in min_args]) + defaults
42 return (min_args, max_args, defaults)
44 keywords['name'] = method.__name__
45 keywords['args'] = args
47 method.__setattr__(arg, keywords[arg])
50 method.__setattr__(arg, kwargs[arg])
56 class MonitorXmlrpcServerMethods:
58 def listMethods(self):
59 mod = MonitorXmlrpcServer()
62 if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
66 def convert_datetime(d, keys=None):
72 if type(d[k]) == type(n):
73 ret[k] = time.mktime(d[k].utctimetuple())
77 class MonitorXmlrpcServer(object):
80 def listMethods(self):
81 mod = MonitorXmlrpcServer()
84 if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
90 params, method = xmlrpclib.loads(cherrypy.request.body.read())
92 if method == "xmlrpc":
94 raise AssertionError("method cannot be 'xmlrpc'")
95 # Get the function and make sure it's exposed.
96 method = getattr(self, method, None)
97 # Use the same error message to hide private method names
98 if method is None or not getattr(method, "exposed", False):
99 raise AssertionError("method does not exist")
102 # Call the method, convert it into a 1-element tuple
103 # as expected by dumps
104 response = method(*params)
107 response = xmlrpclib.dumps((response,), methodresponse=1, allow_none=1)
108 except xmlrpclib.Fault, fault:
109 # Can't marshal the result
110 response = xmlrpclib.dumps(fault, allow_none=1)
112 # Some other error; send back some error info
113 response = xmlrpclib.dumps(
114 xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
117 cherrypy.response.headers["Content-Type"] = "text/xml"
120 # User-defined functions must use cherrypy.expose; turbogears.expose
121 # does additional checking of the response type that we don't want.
123 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
125 returns=Parameter(bool, 'True if successful'))
126 def upAndRunning(self,noop=None):
127 """ This call can indicate to a script whether the server is up
128 and running before trying any more sophisticated operations. """
131 # BOOTMAN SEQUENCE ------------------------------------------------------------
134 @export_to_docbook(roles=['admin'],
135 accepts=[Parameter(dict, "Auth struct"),
136 Parameter(str, "The bootman sequence returned by MyOps"),
137 Parameter(str, "The action string that identifies what to do when this sequence occurs")],
138 returns=Parameter(bool, 'True on success.'))
139 def setBootmanSequence(self, auth, sequence, action):
140 """ Using this call, you can set a new sequence to identify an Unknown
141 Error sqeuence returned by MyOps and associate it with a pre-defined
142 action, (i.e. reboot, reinstall, or others). Please see the
143 documentation for automated actions to see a list of supported
145 api = plc.getAuthAPI()
148 bms = BootmanSequenceRecord.get_by(sequence=sequence)
150 bms = BootmanSequenceRecord(sequence=sequence, action=action)
160 @export_to_docbook(roles=['admin'],
161 accepts=[Parameter(dict, "Auth struct")],
162 returns=Parameter(list, 'Array of bootman sequences'))
163 def getBootmanSequences(self, auth):
164 """ Using this call, you can learn all currently defined bootman
165 sequences and their associated actions. """
166 api = plc.getAuthAPI()
170 bms = BootmanSequenceRecord.query.all()
173 d = convert_datetime(d, ['date_created'])
179 # SITES ------------------------------------------------------------
182 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
183 accepts=[Parameter(dict, "Auth struct")],
184 returns=Parameter(list, 'array of SiteStatus records'))
185 def getSiteStatus(self, auth):
186 """ This call returns a list that includes the status and observations
187 of all sites, including those blacklisted. At this time, there is no
188 indication which sites are blacklisted from this list. """
190 sites = HistorySiteRecord.query.all()
192 d = q.to_dict(exclude=['timestamp', 'version', ])
193 d = convert_datetime(d, ['last_checked', 'last_changed', 'message_created'])
198 @export_to_docbook(roles=['admin'],
199 accepts=[Parameter(dict, "Auth struct")],
200 returns=Parameter(bool, 'True on success.'))
201 def clearSitePenalty(self, auth, loginbase):
202 """ Rather than waiting for monitor to run automatically, this call
203 will manually clear a site's penalties. """
204 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
205 sitehist.clearPenalty()
206 #sitehist.applyPenalty()
207 #sitehist.sendMessage('clear_penalty')
208 sitehist.closeTicket()
212 @export_to_docbook(roles=['admin'],
213 accepts=[Parameter(dict, "Auth struct")],
214 returns=Parameter(bool, 'True on success.'))
215 def increaseSitePenalty(self, auth, loginbase):
216 """ Rather than waiting for monitor to run automatically, this call
217 will manually increase a site's penalties."""
218 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
219 sitehist.increasePenalty()
220 #sitehist.applyPenalty()
221 #sitehist.sendMessage('increase_penalty')
224 # NODES ------------------------------------------------------------
227 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
228 accepts=[Parameter(dict, "Auth struct")],
229 returns=Parameter(list, 'array of NodeStatus records.'))
230 def getNodeStatus(self, auth):
231 """ This call returns a list of all nodes, including those
232 blacklisted. The current observation and recorded status of each node
235 sites = HistoryNodeRecord.query.all()
237 d = q.to_dict(exclude=['timestamp', 'version', ])
238 d = convert_datetime(d, ['last_checked', 'last_changed',])
243 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
244 accepts=[Parameter(dict, "Auth struct")],
245 returns=Parameter(bool, 'True on success.'))
246 def getRecentActions(self, auth, loginbase=None, hostname=None):
247 """ Monitor takes various actions on sites (such as applying
248 penalties) and nodes (such as repairing a node installation via
249 BootManager). As well, it makes a log of every email message sent
250 out, or believed to be sent. This call returns a list of all actions,
251 filtered on site or for a specific node. """
255 # BLACKLIST ------------------------------------------------------------
258 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
259 accepts=[Parameter(dict, "Auth struct")],
260 returns=Parameter(bool, 'True on success.'))
261 def getBlacklist(self, auth):
262 """ Return a list of all nodes and sites that are excluded from
263 penalties. Currently there is no way to exclude a node or site
264 from being monitored. """
265 bl = BlacklistRecord.query.all()
268 d = q.to_dict(exclude=['timestamp', 'version', 'id', ])
269 d = convert_datetime(d, ['date_created'])
275 @export_to_docbook(roles=['admin'],
276 accepts=[Parameter(dict, "Auth struct"),
277 Parameter(str, "hostname"),
278 Parameter(int, "expires number of seconds from time.now()")],
279 returns=Parameter(bool, 'True on success.'))
280 def addHostToBlacklist(self, auth, hostname, expires=0):
281 """ Add a host to the blacklist, with an optional expiration time"""
282 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
286 @export_to_docbook(roles=['admin'],
287 accepts=[Parameter(dict, "Auth struct"),
288 Parameter(str, "loginbase"),
289 Parameter(int, "expires number of seconds from time.now()")],
290 returns=Parameter(bool, 'True on success.'))
291 def addSiteToBlacklist(self, auth, loginbase, expires=0):
292 """ Add a site to the blacklist, with an optional expiration time"""
293 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
297 @export_to_docbook(roles=['admin'],
298 accepts=[Parameter(dict, "Auth struct"),
299 Parameter(str, "loginbase"),
300 Parameter(str, "hostname"),],
301 returns=Parameter(bool, 'True on success.'))
302 def deleteFromBlacklist(self, auth, loginbase=None, hostname=None):
303 """ Remove a host or site from the blacklist """
304 if (loginbase==None and hostname == None) or (loginbase != None and hostname != None):
305 raise Exception("Please specify a single record to delete: either hostname or loginbase")
306 elif loginbase != None:
307 bl = BlacklistRecord.get_by(loginbase=loginbase)
309 elif hostname != None:
310 bl = BlacklistRecord.get_by(hostname=hostname)