1 import turbogears as tg
2 from turbogears import controllers, expose, flash, exception_handler, redirect
3 from turbogears import widgets
4 from cherrypy import request, response
6 # from monitorweb import model
8 # log = logging.getLogger("monitorweb.controllers")
11 from monitor.database.info.model import *
12 #from monitor.database.zabbixapi.model import *
13 from monitor_xmlrpc import MonitorXmlrpcServer
14 from controllers_local import LocalExtensions
15 from pcucontrol.reboot import pcu_name
17 from monitor import util
18 from monitor import reboot
19 from monitor import bootman
20 from monitor import scanapi
21 from monitor import config
24 from monitor.wrapper.plccache import plcdb_hn2lb as site_hn2lb
26 from monitorweb.templates.links import *
28 class ObjectQueryFields(widgets.WidgetsList):
29 """The WidgetsList defines the fields of the form."""
34 class NodeQueryFields(widgets.WidgetsList):
35 """The WidgetsList defines the fields of the form."""
37 object = widgets.RadioButtonList(label="Query Type", options=[('nodes', 'All Nodes'),
38 ('nodehistory', 'Single Node History'),
39 #('sites', 'All Sites'),
40 #('sitehistory', 'Single Site History'),
42 nodehistory_hostname = widgets.TextField(label="Hostname Node History", attrs={'size':30})
44 hostname = widgets.CheckBox(label="Hostname")
45 firewall = widgets.CheckBox(label="Firewall?")
46 fs_status = widgets.CheckBox(label="Filesystem Status")
47 ssh_status = widgets.CheckBox(label="SSH Status")
48 ssh_error = widgets.CheckBox(label="SSH Errors")
49 dns_status = widgets.CheckBox(label="DNS Status")
50 iptables_status = widgets.CheckBox(label="IP Tables Status")
51 nm_status = widgets.CheckBox(label="NM Status")
52 princeton_comon_dir = widgets.CheckBox(label="CoMon Dir")
53 princeton_comon_running = widgets.CheckBox(label="CoMon Running")
54 princeton_comon_procs = widgets.CheckBox(label="CoMon Processes")
55 external_dns_status = widgets.CheckBox(label="Hostname Resolves?")
56 kernel_version = widgets.CheckBox(label="Kernel")
57 bootcd_version = widgets.CheckBox(label="BootCD")
58 boot_server = widgets.CheckBox(label="Boot Server")
59 install_date = widgets.CheckBox(label="Installation Date")
60 observed_status = widgets.CheckBox(label="Observed Status")
61 uptime = widgets.CheckBox(label="Uptime")
62 traceroute = widgets.CheckBox(label="Traceroute")
63 port_status = widgets.CheckBox(label="Port Status")
64 plc_pcuid = widgets.CheckBox(label="PCU ID")
65 rpms = widgets.CheckBox(label="RPM")
66 rpmvalue = widgets.TextField(label="RPM Pattern")
68 class QueryForm(widgets.TableForm):
70 <form xmlns:py="http://purl.org/kid/ns#"
78 <div py:for="field in hidden_fields"
79 py:replace="field.display(value_for(field), **params_for(field))"
81 <table border="0" cellspacing="0" cellpadding="2" py:attrs="table_attrs">
82 <tr py:for="i, field in enumerate(fields)"
83 class="${i%2 and 'odd' or 'even'}"
86 <label class="fieldlabel" for="${field.field_id}" py:content="field.label" />
89 <span py:replace="field.display(value_for(field), **params_for(field))" />
90 <span py:if="error_for(field)" class="fielderror" py:content="error_for(field)" />
91 <span py:if="field.help_text" class="fieldhelp" py:content="field.help_text" />
96 <td py:content="submit.display(submit_text)" />
102 def getNodeQueryForm():
103 return QueryForm(fields=NodeQueryFields(), action="query")
105 # make it easier group objects without invoking the elixir auto-write feature.
106 class aggregate: pass
109 def query_to_dict(query):
110 """ take a url query string and chop it up """
112 query_fields = query.split('&')
113 for f in query_fields:
114 (k,v) = urllib.splitvalue(f)
119 def format_ports(data, pcumodel=None):
124 supported_ports=reboot.model_to_object(pcumodel).supported_ports
126 # ports of a production node
127 supported_ports=[22,80,806]
129 if data and len(data.keys()) > 0 :
130 for port in supported_ports:
132 state = data[str(port)]
136 if state == "filtered":
139 retval.append( (port, state) )
142 retval = [( "Closed/Filtered", "state" )]
144 if filtered_length == len(supported_ports):
145 retval = [( "All Filtered", "state" )]
149 def format_pcu_shortstatus(pcu):
152 if pcu.reboot_trial_status == str(0) or pcu.reboot_trial_status == "Test: No error":
154 elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
155 status = pcu.reboot_trial_status
161 def prep_pcu_for_display(pcu):
166 agg.loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
168 agg.loginbase = "unknown"
170 agg.pcuhist = HistoryPCURecord.query.get(pcu.plc_pcuid)
172 agg.ports = format_ports(pcu.port_status, pcu.plc_pcu_stats['model'])
173 agg.status = format_pcu_shortstatus(pcu)
174 agg.pcu_name = pcu_name(pcu.plc_pcu_stats)
176 #print pcu.entry_complete
177 agg.entry_complete_str = pcu.entry_complete
178 #pcu.entry_complete_str += "".join([ f[0] for f in pcu.entry_complete.split() ])
179 if pcu.dns_status == "NOHOSTNAME":
180 agg.dns_short_status = 'NoHost'
181 elif pcu.dns_status == "DNS-OK":
182 agg.dns_short_status = 'Ok'
183 elif pcu.dns_status == "DNS-NOENTRY":
184 agg.dns_short_status = 'NoEntry'
185 elif pcu.dns_status == "NO-DNS-OR-IP":
186 agg.dns_short_status = 'NoHostOrIP'
187 elif pcu.dns_status == "DNS-MISMATCH":
188 agg.dns_short_status = 'Mismatch'
191 class ActionListWidget(widgets.Widget):
194 class NodeWidget(widgets.Widget):
197 def prep_nodehist(node):
200 agg.loginbase = "unknown"
202 agg.loginbase = PlcSite.query.get(node.plc_siteid).plc_site_stats['login_base']
204 agg.loginbase = "exception"
209 def prep_node_for_display(node, pcuhash=None, preppcu=True, asofdate=None):
213 if node.plc_pcuid and preppcu:
215 pcu = pcuhash[node.plc_pcuid]
217 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid)
220 agg.pcu_status = pcu.reboot_trial_status
221 agg.pcu_short_status = format_pcu_shortstatus(pcu)
222 agg.pcu = prep_pcu_for_display(pcu)
224 agg.pcu_short_status = "none"
225 agg.pcu_status = "nodata"
229 agg.pcu_status = "nopcu"
230 agg.pcu_short_status = "none"
234 if node.kernel_version:
235 agg.kernel = node.kernel_version.split()[2]
240 agg.loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
242 agg.loginbase = "unknown"
245 agg.site = HistorySiteRecord.by_loginbase(agg.loginbase)
248 agg.site = agg.site.get_as_of(asofdate)
251 # TODO: need a cleaner fix for this...
252 agg.site = HistorySiteRecord.by_loginbase("pl")
254 agg.site = HistorySiteRecord.by_loginbase("ple")
256 agg.history = HistoryNodeRecord.by_hostname(node.hostname)
258 agg.history = agg.history.get_as_of(asofdate)
260 agg.ports = format_ports(node.port_status)
263 exists = node.plc_node_stats['last_contact']
265 # TODO: this should not assign to the fb object!
266 node.plc_node_stats = {'last_contact' : None}
271 class Root(controllers.RootController, MonitorXmlrpcServer, LocalExtensions):
272 @expose(template="monitorweb.templates.welcome")
274 # log.debug("Happy TurboGears Controller Responding For Duty")
275 flash("Welcome To MyOps!")
276 return dict(now=time.ctime())
278 @expose(template="monitorweb.templates.nodelist", allow_json=True)
279 def node3(self, filter=None):
280 nhquery = HistoryNodeRecord.query.all()
284 if nh.status == filter:
291 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
294 return dict(now=time.ctime(), query=rquery)
296 def node_query(self, filter):
297 nhquery = HistoryNodeRecord.query.all()
301 if nh.status == filter:
308 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
309 agg = prep_node_for_display(fb)
313 @expose("cheetah:monitorweb.templates.nodelist_plain", as_format="plain",
314 accept_format="text/plain", content_type="text/plain")
315 @expose(template="monitorweb.templates.nodelist", allow_json=True)
316 def node2(self, filter=None):
317 rquery=self.node_query(filter)
318 widget = NodeWidget(template='monitorweb.templates.node_template')
319 return dict(now=time.ctime(), query=rquery, nodewidget=widget)
321 @expose("cheetah:monitorweb.templates.query_plain", as_format="plain",
322 accept_format="text/plain", content_type="text/plain")
323 @expose(template="monitorweb.templates.query", allow_json=True)
324 def query(self, **data):
332 if 'object' in data and data['object'] == "nodes":
333 fbquery = FindbadNodeRecord.get_all_latest()
334 elif 'object' in data and data['object'] == "nodehistory":
335 hostname = data['nodehistory_hostname']
336 data['date_checked'] = 'date_checked'
337 fbrecord = FindbadNodeRecord.get_by(hostname=hostname)
338 fbquery = fbrecord.versions[-500:]
342 # NOTE: reformat some fields.
343 if type(node) is not type(FindbadNodeRecord):
344 agg = node.__dict__.copy()
347 if agg['plc_node_stats']:
348 agg.update(agg['plc_node_stats'])
349 if agg['install_date']:
350 agg['install_date'] = time.mktime(time.strptime(agg['install_date'], "%a %b %d %H:%M:%S %Y"))
351 if agg['kernel_version']:
352 agg['kernel_version'] = agg['kernel_version'].split()[2]
353 if 'traceroute' in data and agg['traceroute']:
354 agg['traceroute'] = "<pre>" + agg['traceroute'] + "</pre>"
355 if 'rpmvalue' in data and 'rpms' in data:
357 rpm_list = agg['rpms'].split()
358 rpm_list = filter(lambda x: re.match(data['rpmvalue'], x, re.I),
360 agg['rpms'] = " ".join(rpm_list)
368 del fields['rpmvalue']
369 del fields['nodehistory_hostname']
371 return dict(now=time.ctime(), query=query, fields=fields, data=data, queryform=getNodeQueryForm())
373 @expose(template="monitorweb.templates.nodefast", allow_json=True)
374 def node(self, filter=None):
375 nhquery = HistoryNodeRecord.query.all()
379 if nh.status == filter:
380 agg = prep_nodehist(nh)
383 agg = prep_nodehist(nh)
386 return dict(now=time.ctime(), query=query)
388 @expose(template="monitorweb.templates.nodelist")
389 def nodeslow(self, filter='boot'):
390 print "NODE------------------"
391 print "befor-len: ", len( [ i for i in session] )
392 session.flush(); session.clear()
393 print "after-len: ", len( [ i for i in session] )
394 fbquery = FindbadNodeRecord.get_all_latest()
396 filtercount = {'down' : 0, 'boot': 0, 'debug' : 0, 'diagnose' : 0, 'disabled': 0,
397 'neverboot' : 0, 'pending' : 0, 'all' : 0, None : 0}
399 # NOTE: reformat some fields.
400 agg = prep_node_for_display(node)
405 if agg.history.status in ['down', 'offline']:
406 if node.plc_node_stats and node.plc_node_stats['last_contact'] != None:
407 filtercount['down'] += 1
409 filtercount['neverboot'] += 1
410 elif agg.history.status in ['good', 'online']:
411 filtercount['boot'] += 1
412 elif agg.history.status in ['debug', 'monitordebug']:
413 filtercount['debug'] += 1
415 if filtercount.has_key(agg.history.status):
416 filtercount[agg.history.status] += 1
420 if filter == "neverboot":
421 if not node.plc_node_stats or node.plc_node_stats['last_contact'] == None:
423 elif filter == "all":
425 elif filter == agg.history.status:
427 elif filter == 'boot':
431 widget = NodeWidget(template='monitorweb.templates.node_template')
432 return dict(now=time.ctime(), query=query, fc=filtercount, nodewidget=widget)
434 def nodeaction_handler(self, tg_exceptions=None):
435 """Handle any kind of error."""
436 print "NODEACTION_HANDLER------------------"
438 if 'pcuid' in request.params:
439 pcuid = request.params['pcuid']
441 refurl = request.headers.get("Referer",link("pcu"))
444 # TODO: do this more intelligently...
445 uri_fields = urllib.splitquery(refurl)
446 if uri_fields[1] is not None:
447 val = query_to_dict(uri_fields[1])
450 elif 'hostname' in val:
451 pcuid = FindbadNodeRecord.get_latest_by(hostname=val['hostname']).plc_pcuid
457 cherry_trail = cherrypy._cputil.get_object_trail()
458 for i in cherry_trail:
462 return self.pcuview(None, pcuid, **dict(exceptions=tg_exceptions))
464 def nodeaction(self, **data):
465 print "NODEACTION------------------"
466 for item in data.keys():
467 print "%s %s" % ( item, data[item] )
469 if 'hostname' in data:
470 hostname = data['hostname']
472 flash("No hostname given in submitted data")
475 if 'submit' in data or 'type' in data:
477 action = data['submit']
479 action = data['type']
481 flash("No submit action given in submitted data")
484 if action == "Reboot":
485 print "REBOOT: %s" % hostname
486 ret = reboot.reboot_str(str(hostname))
488 if ret: raise RuntimeError("Error using PCU: " + str(ret))
489 flash("Reboot appeared to work. Allow at most 5 minutes. Then run ExternalScan to check current status.")
491 elif action == "ExternalScan":
492 scanapi.externalprobe(str(hostname))
493 flash("External Scan Successful!")
494 elif action == "InternalScan":
495 scanapi.internalprobe(str(hostname))
496 flash("Internal Scan Successful!")
499 raise RuntimeError("Unknown action given")
502 @expose(template="monitorweb.templates.simpleview")
503 def simpleview(self, **data):
504 return self.pre_view(**data)
506 @expose(template="monitorweb.templates.simpleview")
507 def pcuview(self, **data):
508 return self.pre_view(**data)
510 @expose(template="monitorweb.templates.detailview")
511 def detailview(self, **data):
512 return self.pre_view(**data)
515 def pre_view(self, **data):
516 session.flush(); session.clear()
523 # if objtype is not None, then treat 'hostname' or 'loginbase' as a search pattern
538 fields = obj.split(":")
541 obj = fields[1].replace("*", "%")
544 if len(obj.split(".")) > 1 or objtype == "node":
549 if 'loginbase' in data:
550 loginbase = data['loginbase']
552 if 'hostname' in data:
553 hostname = data['hostname']
556 try: pcuid = int(data['pcuid'])
560 try: since = int(since)
564 print "pcuid: %s" % pcuid
565 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
566 loginbase_list += [ PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base'] ]
570 nodes = [ FindbadNodeRecord.get_latest_by(hostname=hostname) ]
572 nodes = FindbadNodeRecord.query.filter(FindbadNodeRecord.hostname.like(hostname))
575 lb = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
576 if lb not in loginbase_list:
577 loginbase_list += [ lb ]
581 loginbase_list = [ loginbase ]
583 loginbase_list = HistorySiteRecord.query.filter(HistorySiteRecord.loginbase.like(loginbase))
584 loginbase_list = [ l.loginbase for l in loginbase_list ]
588 for loginbase in loginbase_list:
589 actions = ActionRecord.query.filter_by(loginbase=loginbase
590 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
591 ).order_by(ActionRecord.date_created.desc())
592 actions_list += [ a for a in actions ]
593 site = HistorySiteRecord.by_loginbase(loginbase)
595 sitequery.append(site)
596 # NOTE: because a single pcu may be assigned to multiple hosts,
597 # track unique pcus by their plc_pcuid, then turn dict into list
599 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
600 # NOTE: reformat some fields.
601 agg = prep_node_for_display(node)
604 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
606 for pcuid_key in pcus:
607 pcuquery += [pcus[pcuid_key]]
611 # print type(a.node.hostname)
612 nodequery.sort(lambda a,b: cmp(a.node.hostname,b.node.hostname))
613 pcuquery.sort(lambda a,b: cmp(a.pcu_name,b.pcu_name))
615 actionlist_widget = ActionListWidget(template='monitorweb.templates.actionlist_template')
616 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions_list, actionlist_widget=actionlist_widget, since=since, exceptions=exceptions)
619 # TODO: add form validation
620 @expose(template="monitorweb.templates.pcuview")
621 @exception_handler(nodeaction_handler,"isinstance(tg_exceptions,RuntimeError)")
622 def pcuviewold(self, loginbase=None, pcuid=None, hostname=None, since=20, **data):
623 session.flush(); session.clear()
630 try: since = int(since)
636 if 'submit' in data.keys() or 'type' in data.keys():
637 if hostname: data['hostname'] = hostname
638 self.nodeaction(**data)
639 if 'exceptions' in data:
640 exceptions = data['exceptions']
644 if len(obj.split(".")) > 1: hostname = obj
648 print "pcuid: %s" % pcuid
649 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
650 loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
653 node = FindbadNodeRecord.get_latest_by(hostname=hostname)
654 loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
657 actions = ActionRecord.query.filter_by(loginbase=loginbase
658 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
659 ).order_by(ActionRecord.date_created.desc())
660 actions = [ a for a in actions ]
661 sitequery = [HistorySiteRecord.by_loginbase(loginbase)]
663 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
664 # NOTE: reformat some fields.
665 agg = prep_node_for_display(node)
667 if agg.pcu: #.pcu.plc_pcuid: # not None
668 #pcu = FindbadPCURecord.get_latest_by(plc_pcuid=agg.plc_pcuid)
669 #prep_pcu_for_display(pcu)
670 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
672 for pcuid_key in pcus:
673 pcuquery += [pcus[pcuid_key]]
675 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions, since=since, exceptions=exceptions)
677 @expose(template="monitorweb.templates.pcuhistory")
678 def pcuhistory(self, pcu_id=None):
681 fbnode = HistoryPCURecord.get_by(plc_pcuid=pcu_id)
682 l = fbnode.versions[-1000:]
685 #prep_node_for_display(node)
688 return dict(query=query, pcu_id=pcu_id)
690 @expose(template="monitorweb.templates.nodescanhistory")
691 def nodescanhistory(self, hostname=None, length=10):
692 try: length = int(length)
695 fbnode = FindbadNodeRecord.get_by(hostname=hostname)
696 # TODO: add links for earlier history if desired.
697 l = fbnode.versions[-length:]
701 agg = prep_node_for_display(node, pcuhash=None, preppcu=False, asofdate=node.timestamp)
704 if 'length' in request.params:
705 del request.params['length']
706 return dict(query=query, hostname=hostname, params=request.params)
708 @expose(template="monitorweb.templates.nodehistory")
709 def nodehistory(self, hostname=None):
712 fbnode = HistoryNodeRecord.get_by(hostname=hostname)
713 l = fbnode.versions[-100:]
716 #prep_node_for_display(node)
719 return dict(query=query, hostname=hostname)
721 @expose(template="monitorweb.templates.sitehistory")
722 def sitehistory(self, loginbase=None):
725 fbsite = HistorySiteRecord.get_by(loginbase=loginbase)
726 # TODO: add links for earlier history if desired.
727 l = fbsite.versions[-1000:]
731 return dict(query=query, loginbase=loginbase)
734 @expose("cheetah:monitorweb.templates.pculist_plain", as_format="plain",
735 accept_format="text/plain", content_type="text/plain")
736 @expose(template="monitorweb.templates.pculist")
737 def pcu(self, filter='all'):
738 print "PCUVIEW------------------"
739 print "befor-len: ", len( [ i for i in session] )
740 session.flush(); session.clear()
741 print "after-len: ", len( [ i for i in session] )
742 fbquery = FindbadPCURecord.get_all_latest()
744 filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
748 if node.reboot_trial_status == str(0):
749 filtercount['ok'] += 1
750 elif node.reboot_trial_status == 'NetDown' or node.reboot_trial_status == 'Not_Run':
751 filtercount[node.reboot_trial_status] += 1
753 filtercount['pending'] += 1
755 pcuagg = prep_pcu_for_display(node)
760 elif filter == "ok" and node.reboot_trial_status == str(0):
762 elif filter == node.reboot_trial_status:
764 elif filter == "pending":
765 # TODO: look in message logs...
766 if node.reboot_trial_status != str(0) and \
767 node.reboot_trial_status != 'NetDown' and \
768 node.reboot_trial_status != 'Not_Run':
772 return dict(query=query, fc=filtercount)
774 @expose(template="monitorweb.templates.sitelist")
775 def site(self, filter='all'):
776 print "SITE------------------"
777 print "befor-len: ", len( [ i for i in session] )
778 session.flush(); session.clear()
779 print "after-len: ", len( [ i for i in session] )
780 filtercount = {'good' : 0, 'down': 0, 'online':0, 'offline' : 0, 'new' : 0, 'pending' : 0, 'all' : 0}
781 fbquery = HistorySiteRecord.query.all()
785 filtercount['all'] += 1
786 if site.new and site.slices_used == 0 and not site.enabled:
787 filtercount['new'] += 1
788 elif not site.enabled:
789 filtercount['pending'] += 1
790 elif site.status in ['good', 'online']:
791 filtercount['good'] += 1
792 elif site.status in ['down', 'offline']:
793 filtercount['down'] += 1
798 elif filter == 'new' and site.new and site.slices_used == 0 and not site.enabled:
800 elif filter == "pending" and not site.enabled:
802 elif filter == 'good' and site.status in ['good', 'online']:
804 elif filter == 'down' and site.status in ['down', 'offline']:
807 return dict(query=query, fc=filtercount)
808 @expose(template="monitorweb.templates.sitesummary")
809 def sitesummary(self, loginbase="princeton"):
811 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
812 agg = prep_node_for_display(node)
815 return dict(nodequery=nodequery, loginbase=loginbase)
817 @expose(template="monitorweb.templates.summary")
818 def summary(self, since=7):
820 sumdata['nodes'] = {}
821 sumdata['sites'] = {}
824 def summarize(query, type):
826 if o.status not in sumdata[type]:
827 sumdata[type][o.status] = 0
828 sumdata[type][o.status] += 1
830 fbquery = HistorySiteRecord.query.all()
831 summarize(fbquery, 'sites')
832 fbquery = HistoryPCURecord.query.all()
833 summarize(fbquery, 'pcus')
834 fbquery = HistoryNodeRecord.query.all()
835 summarize(fbquery, 'nodes')
837 if 'monitordebug' in sumdata['nodes']:
838 d = sumdata['nodes']['monitordebug']
839 del sumdata['nodes']['monitordebug']
840 sumdata['nodes']['failboot'] = d
842 return dict(sumdata=sumdata, setorder=['good', 'offline', 'down', 'online'])
844 @expose(template="monitorweb.templates.actionsummary")
845 def actionsummary(self, since=7):
846 from monitor.wrapper.emailTxt import mailtxt
848 types = filter(lambda x: 'notice' in x, dir(mailtxt))
851 print mon_metadata.bind
852 if session.bind is None:
853 #TODO: figure out why this value gets cleared out...
854 session.bind = mon_metadata.bind
855 result = session.execute("select distinct(action_type) from actionrecord;")
857 types = [r[0] for r in result]
859 try: since = int(since)
863 acts = ActionRecord.query.filter(ActionRecord.action_type==t
864 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since))
865 results[t] = acts.count()
866 return dict(results=results)
868 @expose(template="monitorweb.templates.actionlist")
869 def actionlist(self, since=7, action_type=None, loginbase=None):
871 try: since = int(since)
874 acts_query = ActionRecord.query.filter(
875 ActionRecord.date_created >= datetime.now() - timedelta(since)
878 acts_query = acts_query.filter_by(loginbase=loginbase)
881 acts_query = acts_query.filter(ActionRecord.action_type==action_type)
883 acts = acts_query.order_by(ActionRecord.date_created.desc())
885 query = [ a for a in acts ]
887 return dict(actions=query, action_type=action_type, since=since)
890 def upload(self, log, **keywords):
893 logtype_list = ['bm.log', ]
895 if 'hostname' in keywords:
896 hostname = keywords['hostname']
897 if 'type' in keywords and keywords['type'] in logtype_list:
898 logtype = keywords['type']
900 if not hostname: return ""
901 if not logtype: return "unknown logtype: %s" % logtype
903 short_target_filename = bootman.bootmanager_log_name(hostname)
904 abs_target_filename = os.path.join(config.MONITOR_BOOTMANAGER_LOG, short_target_filename)
905 print "write data: %s" % abs_target_filename
906 util.file.dumpFile(abs_target_filename, log.file.read())
907 bootman.bootmanager_log_action(hostname, short_target_filename, logtype)
910 print "redirecting 3"