first docs test
[monitor.git] / web / MonitorWeb / monitorweb / monitor_xmlrpc.py
1 import sys
2 import xmlrpclib
3 import cherrypy
4 import turbogears
5 from datetime import datetime, timedelta
6 import time
7
8 from monitor.database.info.model import *
9 from monitor.database.info.interface import *
10
11 try:
12     from PLC.Parameter import Parameter, Mixed
13 except:
14     def Parameter(a = None, b = None): pass
15     def Mixed(a = None, b = None, c = None): pass
16
17 def export_to_docbook(**kwargs):
18
19     keywords = {
20         "group" : "Monitor",
21         "status" : "current",
22         "name": None,
23         "args": None,
24         "roles": [],
25         "accepts": [],
26         "returns": [],
27     }
28     def export(method):
29         def args():
30             # Inspect method. Remove self from the argument list.
31             max_args = method.func_code.co_varnames[0:method.func_code.co_argcount]
32             defaults = method.func_defaults
33             if defaults is None:
34                 defaults = ()
35             min_args = max_args[0:len(max_args) - len(defaults)]
36
37             defaults = tuple([None for arg in min_args]) + defaults
38             return (min_args, max_args, defaults)
39
40         keywords['name'] = method.__name__
41         keywords['args'] = args
42         for arg in keywords:
43             method.__setattr__(arg, keywords[arg])
44
45         for arg in kwargs:
46             method.__setattr__(arg, kwargs[arg])
47         return method
48
49     return export
50
51
52 class MonitorXmlrpcServerMethods:
53         @cherrypy.expose
54         def listMethods(self):
55                 mod = MonitorXmlrpcServer()
56                 ret_list = []
57                 for f in dir(mod):
58                         if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
59                                 ret_list += [f]
60                 return ret_list
61
62 def convert_datetime(d, keys=None):
63         ret = d.copy()
64         n = datetime.now()
65         if keys == None:
66                 keys = d.keys()
67         for k in keys:
68                 if type(d[k]) == type(n):
69                         ret[k] = time.mktime(d[k].utctimetuple())
70         
71         return ret
72
73 class MonitorXmlrpcServer(object):
74
75         @cherrypy.expose
76         def listMethods(self):
77                 mod = MonitorXmlrpcServer()
78                 ret_list = []
79                 for f in dir(mod):
80                         if isinstance(mod.__getattribute__(f),type(mod.__getattribute__('addDowntime'))):
81                                 ret_list += [f]
82                 return ret_list
83
84         @turbogears.expose()
85         def XMLRPC(self):
86                 params, method = xmlrpclib.loads(cherrypy.request.body.read())
87                 try:
88                         if method == "xmlrpc":
89                                 # prevent recursion
90                                 raise AssertionError("method cannot be 'xmlrpc'")
91                         # Get the function and make sure it's exposed.
92                         method = getattr(self, method, None)
93                         # Use the same error message to hide private method names
94                         if method is None or not getattr(method, "exposed", False):
95                                 raise AssertionError("method does not exist")
96
97                         session.clear()
98                         # Call the method, convert it into a 1-element tuple
99                         # as expected by dumps                                     
100                         response = method(*params)
101
102                         session.flush()
103                         response = xmlrpclib.dumps((response,), methodresponse=1, allow_none=1)
104                 except xmlrpclib.Fault, fault:
105                         # Can't marshal the result
106                         response = xmlrpclib.dumps(fault, allow_none=1)
107                 except:
108                         # Some other error; send back some error info
109                         response = xmlrpclib.dumps(
110                                 xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
111                                 )
112
113                 cherrypy.response.headers["Content-Type"] = "text/xml"
114                 return response
115
116         # User-defined functions must use cherrypy.expose; turbogears.expose
117         #       does additional checking of the response type that we don't want.
118         @cherrypy.expose
119         @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'],
120                            accepts=[],
121                                            returns=Parameter(bool, 'True is successful'))
122         def upAndRunning(self):
123                 return True
124
125         # SITES ------------------------------------------------------------
126
127         @cherrypy.expose
128         def getSiteStatus(self, auth):
129                 ret_list = []
130                 sites = HistorySiteRecord.query.all()
131                 for q in sites:
132                         d = q.to_dict(exclude=['timestamp', 'version', ])
133                         d = convert_datetime(d, ['last_checked', 'last_changed', 'message_created'])
134                         ret_list.append(d)
135                 return ret_list
136
137         @cherrypy.expose
138         def clearSitePenalty(self, auth, loginbase):
139                 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
140                 sitehist.clearPenalty()
141                 #sitehist.applyPenalty()
142                 #sitehist.sendMessage('clear_penalty')
143                 sitehist.closeTicket()
144                 return True
145
146         @cherrypy.expose
147         def increaseSitePenalty(self, auth, loginbase):
148                 sitehist = SiteInterface.get_or_make(loginbase=loginbase)
149                 sitehist.increasePenalty()
150                 #sitehist.applyPenalty()
151                 #sitehist.sendMessage('increase_penalty')
152                 return True
153
154         # NODES ------------------------------------------------------------
155
156         @cherrypy.expose
157         def getNodeStatus(self, auth):
158                 ret_list = []
159                 sites = HistoryNodeRecord.query.all()
160                 for q in sites:
161                         d = q.to_dict(exclude=['timestamp', 'version', ])
162                         d = convert_datetime(d, ['last_checked', 'last_changed',])
163                         ret_list.append(d)
164                 return ret_list
165
166         @cherrypy.expose
167         def getRecentActions(self, auth, loginbase=None, hostname=None):
168                 ret_list = []
169                 return ret_list
170
171         # BLACKLIST ------------------------------------------------------------
172
173         @cherrypy.expose
174         def getBlacklist(self, auth):
175                 bl = BlacklistRecord.query.all()
176                 ret_list = []
177                 for q in bl:
178                         d = q.to_dict(exclude=['timestamp', 'version', 'id', ])
179                         d = convert_datetime(d, ['date_created'])
180                         ret_list.append(d)
181
182                 return ret_list
183                 # datetime.datetime.fromtimestamp(time.mktime(time.strptime(mytime, time_format)))
184         
185         @cherrypy.expose
186         def addHostToBlacklist(self, auth, hostname, expires=0):
187                 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
188                 return True
189
190         @cherrypy.expose
191         def addSiteToBlacklist(self, auth, loginbase, expires=0):
192                 bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires)
193                 return True
194
195         @cherrypy.expose
196         def deleteFromBlacklist(self, auth, loginbase=None, hostname=None):
197                 if (loginbase==None and hostname == None) or (loginbase != None and hostname != None):
198                         raise Exception("Please specify a single record to delete: either hostname or loginbase")
199                 elif loginbase != None:
200                         bl = BlacklistRecord.get_by(loginbase=loginbase)
201                         bl.delete()
202                 elif hostname != None:
203                         bl = BlacklistRecord.get_by(hostname=hostname)
204                         bl.delete()
205                 return True