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 session.expunge_all()
103 except AttributeError: # SQLAlchemy < 0.5.1
105 # Call the method, convert it into a 1-element tuple
106 # as expected by dumps
107 response = method(*params)
110 response = xmlrpclib.dumps((response,), methodresponse=1, allow_none=1)
111 except xmlrpclib.Fault, fault:
112 # Can't marshal the result
113 response = xmlrpclib.dumps(fault, allow_none=1)
115 # Some other error; send back some error info
116 response = xmlrpclib.dumps(
117 xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
120 cherrypy.response.headers["Content-Type"] = "text/xml"
123 # User-defined functions must use cherrypy.expose; turbogears.expose
124 # does additional checking of the response type that we don't want.
126 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
128 returns=Parameter(bool, 'True if successful'))
129 def upAndRunning(self,noop=None):
130 """ This call can indicate to a script whether the server is up
131 and running before trying any more sophisticated operations. """
134 # BOOTMAN SEQUENCE ------------------------------------------------------------
137 @export_to_docbook(roles=['admin'],
138 accepts=[Parameter(dict, "Auth struct"),
139 Parameter(str, "The bootman sequence returned by MyOps"),
140 Parameter(str, "The action string that identifies what to do when this sequence occurs")],
141 returns=Parameter(bool, 'True on success.'))
142 def setBootmanSequence(self, auth, sequence, action):
143 """ Using this call, you can set a new sequence to identify an Unknown
144 Error sqeuence returned by MyOps and associate it with a pre-defined
145 action, (i.e. reboot, reinstall, or others). Please see the
146 documentation for automated actions to see a list of supported
148 api = plc.getAuthAPI()
151 bms = BootmanSequenceRecord.get_by(sequence=sequence)
153 bms = BootmanSequenceRecord(sequence=sequence, action=action)
163 @export_to_docbook(roles=['admin'],
164 accepts=[Parameter(dict, "Auth struct")],
165 returns=Parameter(list, 'Array of bootman sequences'))
166 def getBootmanSequences(self, auth):
167 """ Using this call, you can learn all currently defined bootman
168 sequences and their associated actions. """
169 api = plc.getAuthAPI()
173 bms = BootmanSequenceRecord.query.all()
176 d = convert_datetime(d, ['date_created'])
182 # SITES ------------------------------------------------------------
185 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
186 accepts=[Parameter(dict, "Auth struct")],
187 returns=Parameter(list, 'array of SiteStatus records'))
188 def getSiteStatus(self, auth):
189 """ This call returns a list that includes the status and observations
190 of all sites, including those blacklisted. At this time, there is no
191 indication which sites are blacklisted from this list. """
193 sites = HistorySiteRecord.query.all()
195 d = q.to_dict(exclude=['timestamp', 'version', ])
196 d = convert_datetime(d, ['last_checked', 'last_changed', 'message_created'])
201 @export_to_docbook(roles=['admin'],
202 accepts=[Parameter(dict, "Auth struct")],
203 returns=Parameter(bool, 'True on success.'))
204 def clearSitePenalty(self, auth, loginbase):
205 """ Rather than waiting for monitor to run automatically, this call
206 will manually clear a site's penalties. """
207 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
208 sitehist.clearPenalty()
209 #sitehist.applyPenalty()
210 #sitehist.sendMessage('clear_penalty')
211 sitehist.closeTicket()
215 @export_to_docbook(roles=['admin'],
216 accepts=[Parameter(dict, "Auth struct")],
217 returns=Parameter(bool, 'True on success.'))
218 def increaseSitePenalty(self, auth, loginbase):
219 """ Rather than waiting for monitor to run automatically, this call
220 will manually increase a site's penalties."""
221 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
222 sitehist.increasePenalty()
223 #sitehist.applyPenalty()
224 #sitehist.sendMessage('increase_penalty')
227 # NODES ------------------------------------------------------------
230 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
231 accepts=[Parameter(dict, "Auth struct")],
232 returns=Parameter(list, 'array of NodeStatus records.'))
233 def getNodeStatus(self, auth):
234 """ This call returns a list of all nodes, including those
235 blacklisted. The current observation and recorded status of each node
238 sites = HistoryNodeRecord.query.all()
240 d = q.to_dict(exclude=['timestamp', 'version', ])
241 d = convert_datetime(d, ['last_checked', 'last_changed',])
246 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
247 accepts=[Parameter(dict, "Auth struct")],
248 returns=Parameter(bool, 'True on success.'))
249 def getRecentActions(self, auth, loginbase=None, hostname=None):
250 """ Monitor takes various actions on sites (such as applying
251 penalties) and nodes (such as repairing a node installation via
252 BootManager). As well, it makes a log of every email message sent
253 out, or believed to be sent. This call returns a list of all actions,
254 filtered on site or for a specific node. """
258 # BLACKLIST ------------------------------------------------------------
261 @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
262 accepts=[Parameter(dict, "Auth struct")],
263 returns=Parameter(bool, 'True on success.'))
264 def getBlacklist(self, auth):
265 """ Return a list of all nodes and sites that are excluded from
266 penalties. Currently there is no way to exclude a node or site
267 from being monitored. """
268 bl = BlacklistRecord.query.all()
271 d = q.to_dict(exclude=['timestamp', 'version', 'id', ])
272 d = convert_datetime(d, ['date_created'])
278 @export_to_docbook(roles=['admin'],
279 accepts=[Parameter(dict, "Auth struct"),
280 Parameter(str, "hostname"),
281 Parameter(int, "expires number of seconds from time.now()")],
282 returns=Parameter(bool, 'True on success.'))
283 def addHostToBlacklist(self, auth, hostname, expires=0):
284 """ Add a host to the blacklist, with an optional expiration time"""
285 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
289 @export_to_docbook(roles=['admin'],
290 accepts=[Parameter(dict, "Auth struct"),
291 Parameter(str, "loginbase"),
292 Parameter(int, "expires number of seconds from time.now()")],
293 returns=Parameter(bool, 'True on success.'))
294 def addSiteToBlacklist(self, auth, loginbase, expires=0):
295 """ Add a site to the blacklist, with an optional expiration time"""
296 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
300 @export_to_docbook(roles=['admin'],
301 accepts=[Parameter(dict, "Auth struct"),
302 Parameter(str, "loginbase"),
303 Parameter(str, "hostname"),],
304 returns=Parameter(bool, 'True on success.'))
305 def deleteFromBlacklist(self, auth, loginbase=None, hostname=None):
306 """ Remove a host or site from the blacklist """
307 if (loginbase==None and hostname == None) or (loginbase != None and hostname != None):
308 raise Exception("Please specify a single record to delete: either hostname or loginbase")
309 elif loginbase != None:
310 bl = BlacklistRecord.get_by(loginbase=loginbase)
312 elif hostname != None:
313 bl = BlacklistRecord.get_by(hostname=hostname)