clearer names for actions, and infer actions better
[monitor.git] / monitor / common.py
index 051cd61..ae32156 100644 (file)
@@ -1,14 +1,14 @@
 
 import time
 import struct
-from pcucontrol import reboot
-
+from monitor import reboot
 from monitor import util
-from monitor import database
-from monitor.wrapper import plc, plccache
+from monitor import query
+from monitor.wrapper import plc
 
-from datetime import datetime 
-from monitor.model import PersistFlags
+from datetime import datetime, timedelta
+from monitor.model import Message
+from monitor.database.info import HistoryNodeRecord
 
 esc = struct.pack('i', 27)
 RED    = esc + "[1;31m"
@@ -43,12 +43,17 @@ def get_current_state(fbnode):
        return l
 
 def color_pcu_state(fbnode):
+       if fbnode['plc_pcuid'] is None:
+               return 'NOPCU'
+       else:
+               return 'PCU'
 
        if 'plcnode' in fbnode and 'pcu_ids' in fbnode['plcnode'] and len(fbnode['plcnode']['pcu_ids']) > 0 :
                values = reboot.get_pcu_values(fbnode['plcnode']['pcu_ids'][0])
                if values == None:
                        return fbnode['pcu']
        else:
+               print fbnode.keys()
                if 'pcu' not in fbnode:
                        return 'NOPCU'
                else:
@@ -58,26 +63,26 @@ def color_pcu_state(fbnode):
                rb = values['reboot']
                if rb == 0 or rb == "0":
                        return fbnode['pcu'] + "OK  "
-                       #return fbnode['pcu'] + "OK  "
-                       #return green(fbnode['pcu'])
                elif "NetDown" == rb  or "Not_Run" == rb:
                        return fbnode['pcu'] + "DOWN"
-                       #return yellow(fbnode['pcu'])
                else:
                        return fbnode['pcu'] + "BAD "
-                       #return red(fbnode['pcu'])
        else:
-               #return red(fbnode['pcu'])
                return fbnode['pcu'] + "BAD "
 
 def color_boot_state(l):
        if    l == "dbg": return yellow("debg")
        elif  l == "dbg ": return yellow("debg")
+       elif  l == "failboot": return yellow("debg")
        elif  l == "diag": return lightblue(l)
+       elif  l == "diagnose": return lightblue(l)
+       elif  l == "safeboot": return lightblue(l)
        elif  l == "disable": return red("dsbl")
+       elif  l == "disabled": return red("dsbl")
        elif  l == "down": return red(l)
        elif  l == "boot": return green(l)
        elif  l == "rins": return blue(l)
+       elif  l == "reinstall": return blue(l)
        else:
                return l
 
@@ -86,6 +91,8 @@ def diff_time(timestamp, abstime=True):
        now = time.time()
        if timestamp == None:
                return "unknown"
+       if type(timestamp) == type(datetime.now()):
+               timestamp = time.mktime(timestamp.timetuple())
        if abstime:
                diff = now - timestamp
        else:
@@ -154,7 +161,7 @@ def nodegroup_display(node, fbdata, conf=None):
                node['pcu'] = "PCU"
        node['lastupdate'] = diff_time(node['last_contact'])
 
-       pf = PersistFlags(node['hostname'], 1, db='node_persistflags')
+       pf = HistoryNodeRecord.get_by(hostname=node['hostname'])
        try:
                node['lc'] = diff_time(pf.last_changed)
        except:
@@ -185,6 +192,7 @@ def get_nodeset(config):
                Given the config values passed in, return the set of hostnames that it
                evaluates to.
        """
+       from monitor.wrapper import plccache
        api = plc.getAuthAPI()
        l_nodes = plccache.l_nodes
 
@@ -199,16 +207,89 @@ def get_nodeset(config):
                l_nodes = api.GetNodes(ng[0]['node_ids'], ['hostname'])
        elif config.site:
                site = api.GetSites(config.site)
-               l_nodes = api.GetNodes(site[0]['node_ids'], ['hostname'])
+               if len(site) > 0:
+                       l_nodes = api.GetNodes(site[0]['node_ids'], ['hostname'])
+               else:
+                       print "No site returned for : %s" % config.site
+                       return []
                
        l_nodes = [node['hostname'] for node in l_nodes]
 
        # perform this query after the above options, so that the filter above
        # does not break.
        if config.nodeselect:
-               fbquery = FindbadNodeRecord.get_all_latest()
+               fbquery = HistoryNodeRecord.query.all()
                node_list = [ n.hostname for n in fbquery ]
-               l_nodes = node_select(config.nodeselect, node_list, None)
+               l_nodes = query.node_select(config.nodeselect, node_list, None)
 
        return l_nodes
+
+def email_exception(content=None, title=None):
+    import config
+    from monitor.model import Message
+    import traceback
+    msg=traceback.format_exc()
+    if content:
+        msg = content + "\n" + msg
+
+    full_title = "exception running monitor"
+    if title:
+        full_title = "exception running monitor %s" % title
+
+    m=Message(full_title, msg, False)
+    m.send([config.exception_email])
+    return
+
+def changed_lessthan(last_changed, days):
+       if datetime.now() - last_changed <= timedelta(days):
+               #print "last changed less than %s" % timedelta(days)
+               return True
+       else:
+               #print "last changed more than %s" % timedelta(days)
+               return False
+
+def changed_greaterthan(last_changed, days):
+       if last_changed is None:
+               return False
+
+       if datetime.now() - last_changed > timedelta(days):
+               #print "last changed more than %s" % timedelta(days)
+               return True
+       else:
+               #print "last changed less than %s" % timedelta(days)
+               return False
+
+def found_between(recent_actions, action_type, lower, upper):
+       return found_before(recent_actions, action_type, upper) and found_within(recent_actions, action_type, lower)
+
+def found_before(recent_actions, action_type, within):
+       for action in recent_actions:
+               if action_type == action.action_type and \
+                               action.date_created < (datetime.now() - timedelta(within)):
+                       return True
+       return False
+       
+def found_within(recent_actions, action_type, within):
+       for action in recent_actions:
+               #print "%s - %s %s > %s - %s (%s) ==> %s" % (action.loginbase, action.action_type, action.date_created, datetime.now(), timedelta(within), datetime.now()-timedelta(within), action.date_created > (datetime.now() - timedelta(within)) )
+               if action_type == action.action_type and \
+                               action.date_created > (datetime.now() - timedelta(within)):
+                               #datetime.now() - action.date_created < timedelta(within):
+                       # recent action of given type.
+                       #print "%s found_within %s in recent_actions from %s" % (action_type, timedelta(within), action.date_created)
+                       return True
+
+       print "%s NOT found_within %s in recent_actions" % (action_type, timedelta(within) )
+       return False
        
+
+#class Time:
+#    @classmethod
+#    def dt_to_ts(cls, dt):
+#        t = time.mktime(dt.timetuple())
+#        return t
+#
+#    @classmethod
+#    def ts_to_dt(cls, ts):
+#        d = datetime.fromtimestamp(ts)
+#        return d