Moved some files around and merged from 1.0 branch:
[monitor.git] / unified_model.py
index 8c5fb7f..891bab0 100755 (executable)
@@ -2,22 +2,17 @@
 
 from monitor import database
 
-import plc
-api = plc.getAuthAPI()
-
-import mailer
+from monitor.wrapper import plc, plccache
+from monitor.wrapper import mailer
 import time
 
 from model import *
-from const import *
-import util.file
-import config
+from monitor.const import *
+from monitor import util
+from monitor import config
 
 def gethostlist(hostlist_file):
        return util.file.getListFromFile(hostlist_file)
-       
-       #nodes = api.GetNodes({'peer_id' : None}, ['hostname'])
-       #return [ n['hostname'] for n in nodes ]
 
 def array_to_priority_map(array):
        """ Create a mapping where each entry of array is given a priority equal
@@ -41,6 +36,10 @@ def cmpValMap(v1, v2, map):
                raise Exception("No index %s or %s in map" % (v1, v2))
 
 def cmpCategoryVal(v1, v2):
+       # Terrible hack to manage migration to no more 'ALPHA' states.
+       if v1 == 'ALPHA': v1 = "PROD"
+       if v2 == 'ALPHA': v2 = "PROD"
+       #map = array_to_priority_map([ None, 'PROD', 'ALPHA', 'OLDBOOTCD', 'UNKNOWN', 'FORCED', 'ERROR', ])
        map = array_to_priority_map([ None, 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'FORCED', 'ERROR', ])
        return cmpValMap(v1,v2,map)
 
@@ -70,8 +69,6 @@ class PenaltyMap:
        #       condition/penalty is applied, move to the next phase.
 
 
-#fb = database.dbLoad("findbad")
-
 class RT(object):
        def __init__(self, ticket_id = None):
                self.ticket_id = ticket_id
@@ -235,7 +232,7 @@ class PersistMessage(Message):
                        #print "creating new object"
                        obj = super(PersistMessage, typ).__new__(typ, [id, subject, message, via_rt], **kwargs)
                        obj.id = id
-                       obj.actiontracker = Recent(3*60*60*24)
+                       obj.actiontracker = Recent(1*60*60*24)
                        obj.ticket_id = None
 
                if 'ticket_id' in kwargs and kwargs['ticket_id'] is not None:
@@ -264,6 +261,7 @@ class PersistMessage(Message):
                        self.save()
                else:
                        # NOTE: only send a new message every week, regardless.
+                       # NOTE: can cause thank-you messages to be lost, for instance when node comes back online within window.
                        print "Not sending to host b/c not within window of %s days" % (self.actiontracker.withintime // (60*60*24))
 
 class MonitorMessage(object):
@@ -414,7 +412,7 @@ class Record(object):
        def __init__(self, hostname, data):
                self.hostname = hostname
                self.data = data
-               self.plcdb_hn2lb = database.dbLoad("plcdb_hn2lb")
+               self.plcdb_hn2lb = plccache.plcdb_hn2lb
                self.loginbase = self.plcdb_hn2lb[self.hostname]
                return
 
@@ -450,7 +448,7 @@ class Record(object):
 
        def getDaysDown(cls, diag_record):
                daysdown = -1
-               if diag_record['comonstats']['uptime'] != "null":
+               if diag_record['comonstats']['uptime'] != "null" and diag_record['comonstats']['uptime'] != "-1":
                        daysdown = - int(float(diag_record['comonstats']['uptime'])) // (60*60*24)
                #elif diag_record['comonstats']['sshstatus'] != "null":
                #       daysdown = int(diag_record['comonstats']['sshstatus']) // (60*60*24)
@@ -494,17 +492,29 @@ class Record(object):
                return daysdown
        getStrDaysDown = classmethod(getStrDaysDown)
 
-       #def getStrDaysDown(cls, diag_record):
-       #       daysdown = cls.getDaysDown(diag_record)
-       #       if daysdown > 0:
-       #               return "%d days down"%daysdown
-       #       elif daysdown == -1:
-       #               return "Never online"
-       #       else:
-       #               return "%d days up"% -daysdown
-       #getStrDaysDown = classmethod(getStrDaysDown)
-
-       def takeAction(self):
+       def getSendEmailFlag(self):
+               if not config.mail:
+                       return False
+
+               # resend if open & created longer than 30 days ago.
+               if  'rt' in self.data and \
+                       'Status' in self.data['rt'] and \
+                       "open" in self.data['rt']['Status'] and \
+                       self.data['rt']['Created'] > int(time.time() - 60*60*24*30):
+                       # if created-time is greater than the thirty days ago from the current time
+                       return False
+
+               return True
+
+       def getMostRecentStage(self):
+               lastact = self.data['last_action_record']
+               return lastact.stage
+
+       def getMostRecentTime(self):
+               lastact = self.data['last_action_record']
+               return lastact.date_action_taken
+
+       def takeAction(self, index=0):
                pp = PersistSitePenalty(self.hostname, 0, db='persistpenalty_hostnames')
                if 'improvement' in self.data['stage'] or self.improved() or \
                        'monitor-end-record' in self.data['stage']:
@@ -514,6 +524,7 @@ class Record(object):
                else:
                        print "takeAction: increasing penalty for %s"%self.hostname
                        pp.increase()
+               pp.index = index
                pp.apply(self.hostname)
                pp.save()
 
@@ -527,7 +538,7 @@ class Record(object):
                        hlist = "    %s %s - %s\n" % (info[0], info[2], info[1]) #(node,ver,daysdn)
                return hlist
        def saveAction(self):
-               if 'save-act-all' in self.data and self.data['save-act-all'] == True:
+               if 'save_act_all' in self.data and self.data['save_act_all'] == True:
                        return True
                else:
                        return False
@@ -543,6 +554,8 @@ class Record(object):
                                                                 self.data['message'][1] % self.data['args'],
                                                                 True, db='monitor_persistmessages',
                                                                 ticket_id=ticket_id)
+                       if self.data['stage'] == "improvement":
+                               message.reset()
                        return message
                else:
                        return None
@@ -560,14 +573,17 @@ class Record(object):
                if ADMIN & roles:
                        contacts += [config.email]
                if TECH & roles:
-                       contacts += [TECHEMAIL % self.loginbase]
+                       #contacts += [TECHEMAIL % self.loginbase]
+                       contacts += plc.getTechEmails(self.loginbase)
                if PI & roles:
-                       contacts += [PIEMAIL % self.loginbase]
+                       #contacts += [PIEMAIL % self.loginbase]
+                       contacts += plc.getSliceUserEmails(self.loginbase)
                if USER & roles:
+                       contacts += plc.getSliceUserEmails(self.loginbase)
                        slices = plc.slices(self.loginbase)
                        if len(slices) >= 1:
-                               for slice in slices:
-                                       contacts += [SLICEMAIL % slice]
+                               #for slice in slices:
+                               #       contacts += [SLICEMAIL % slice]
                                print "SLIC: %20s : %d slices" % (self.loginbase, len(slices))
                        else:
                                print "SLIC: %20s : 0 slices" % self.loginbase
@@ -580,79 +596,6 @@ class NodeRecord:
                self.hostname = hostname
                self.ticket = None
                self.target = target
-               #if hostname in fb['nodes']:
-               #       self.data = fb['nodes'][hostname]['values']
-               #else:
-               #       raise Exception("Hostname not in scan database")
-
-       def stageIswaitforever(self):
-               if 'waitforever' in self.data['stage']:
-                       return True
-               else:
-                       return False
-
-       def severity(self):
-               category = self.data['category']
-               prev_category = self.data['prev_category']
-               print "IMPROVED: ", category, prev_category
-               val = cmpCategoryVal(category, prev_category)
-               return val 
-
-       def improved(self):
-               return self.severity() > 0
-       
-       def end_record(self):
-               return node_end_record(self.hostname)
-
-       def reset_stage(self):
-               self.data['stage'] = 'findbad'
-               return True
-
-       def open_tickets(self):
-               if self.ticket and self.ticket.status['status'] == 'open':
-                       return 1
-               return 0
-       def setIntrospect(self):
-               pass
-
-       def email_notice(self):
-               message = self._get_message_for_condition()
-               message.send(self._get_contacts_for_condition())
-               return True
-       def close_ticket(self):
-               if self.ticket:
-                       self.ticket.closeTicket()
-
-       def exempt_from_penalties(self):
-               bl = database.dbLoad("l_blacklist")
-               return self.hostname in bl
-
-       def penalties(self):
-               return []
-       def escellate_penalty(self):
-               return True
-       def reduce_penalty(self):
-               return True
-
-
-       def atTarget(self):
-               return self.target.verify(self.data)
-
-       def _get_condition(self):
-               return self.data['category'].lower()
-
-       def _get_stage(self):
-               "improvement"
-               "firstnotice_noop"
-               "secondnotice_noslicecreation"
-               "thirdnotice_disableslices"
-
-               delta = current_time - self.data['time']
-
-       def _get_message_for_condition(self):
-               pass
-       def _get_contacts_for_condition(self):
-               pass
 
 class Action(MonRecord):
        def __init__(self, host, data):