changes for 3.0
[monitor.git] / unified_model.py
index acc89d8..df4024e 100755 (executable)
@@ -3,8 +3,6 @@
 from monitor import database
 
 import plc
-api = plc.getAuthAPI()
-
 import mailer
 import time
 
@@ -15,9 +13,6 @@ 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,7 +36,11 @@ def cmpValMap(v1, v2, map):
                raise Exception("No index %s or %s in map" % (v1, v2))
 
 def cmpCategoryVal(v1, v2):
-       map = array_to_priority_map([ None, 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'FORCED', 'ERROR', ])
+       # 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', 'OLDPROD', 'OLDBOOTCD', 'UNKNOWN', 'FORCED', 'ERROR', ])
        return cmpValMap(v1,v2,map)
 
 
@@ -91,7 +90,7 @@ class RT(object):
                return self.status
 
        def closeTicket(self):
-               mailer.closeTicketViaRT(self.ticket_id) 
+               mailer.closeTicketViaRT(self.ticket_id, "Ticket CLOSED automatically by SiteAssist."
 
        def email(self, subject, body, to):
                self.ticket_id = mailer.emailViaRT(subject, body, to, self.ticket_id)
@@ -229,13 +228,13 @@ class PersistMessage(Message):
 
                #print pm
                if id in pm:
-                       print "Using existing object"
+                       #print "Using existing object"
                        obj = pm[id]
                else:
-                       print "creating new object"
+                       #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:
@@ -252,18 +251,20 @@ class PersistMessage(Message):
        def reset(self):
                self.actiontracker.unsetRecent()
 
+       def save(self):
+               pm = database.dbLoad(self.db)
+               pm[self.id] = self
+               database.dbDump(self.db, pm)
+
        def send(self, to):
                if not self.actiontracker.isRecent():
                        self.ticket_id = Message.send(self, to)
                        self.actiontracker.setRecent()
-
-                       #print "recording object for persistance"
-                       pm = database.dbLoad(self.db)
-                       pm[self.id] = self
-                       database.dbDump(self.db, pm)
+                       self.save()
                else:
                        # NOTE: only send a new message every week, regardless.
-                       print "Not sending to host b/c not within window of %s days" % (self.actiontracker.withintime // 60*60*24)
+                       # 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):
        def __new__(typ, id, *args, **kwargs):
@@ -354,7 +355,7 @@ class PersistSitePenalty(SitePenalty):
 
                #print pm
                if id in pm:
-                       print "Using existing object"
+                       print "PersistSitePenalty Using existing object"
                        obj = pm[id]
                else:
                        print "creating new object"
@@ -427,6 +428,11 @@ class Record(object):
        def severity(self):
                category = self.data['category']
                prev_category = self.data['prev_category']
+               print "SEVERITY: ", category, prev_category
+               try:
+                       print "SEVERITY state: ", self.data['state'], self.data['prev_state']
+               except:
+                       print "SEVERITY state: unknown unknown"
                val = cmpCategoryVal(category, prev_category)
                return val 
 
@@ -448,7 +454,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)
@@ -502,35 +508,52 @@ class Record(object):
        #               return "%d days up"% -daysdown
        #getStrDaysDown = classmethod(getStrDaysDown)
 
-       def takeAction(self):
+       def takeAction(self, index=0):
                pp = PersistSitePenalty(self.hostname, 0, db='persistpenalty_hostnames')
-               if 'improvement' in self.data['stage'] or self.improved():
-                       print "decreasing penalty for %s"%self.hostname
+               if 'improvement' in self.data['stage'] or self.improved() or \
+                       'monitor-end-record' in self.data['stage']:
+                       print "takeAction: decreasing penalty for %s"%self.hostname
+                       pp.decrease()
                        pp.decrease()
                else:
-                       print "increasing penalty for %s"%self.hostname
+                       print "takeAction: increasing penalty for %s"%self.hostname
                        pp.increase()
+               print "takeAction: applying penalty to %s as index %s"% (self.hostname, index)
+               pp.index = index
                pp.apply(self.hostname)
                pp.save()
 
        def _format_diaginfo(self):
                info = self.data['info']
+               print "FORMAT : STAGE: ", self.data['stage']
                if self.data['stage'] == 'monitor-end-record':
+                       if info[2] == "ALPHA": info = (info[0], info[1], "PROD")
                        hlist = "    %s went from '%s' to '%s'\n" % (info[0], info[1], info[2]) 
                else:
                        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:
+                       return True
+               else:
+                       return False
 
        def getMessage(self, ticket_id=None):
                self.data['args']['hostname'] = self.hostname
                self.data['args']['loginbase'] = self.loginbase
                self.data['args']['hostname_list'] = self._format_diaginfo()
-               message = PersistMessage(self.hostname, 
+               #print self.data['message']
+               if self.data['message']:
+                       message = PersistMessage(self.hostname, 
                                                                 self.data['message'][0] % self.data['args'],
                                                                 self.data['message'][1] % self.data['args'],
                                                                 True, db='monitor_persistmessages',
                                                                 ticket_id=ticket_id)
-               return message
+                       if self.data['stage'] == "improvement":
+                               message.reset()
+                       return message
+               else:
+                       return None
        
        def getContacts(self):
                roles = self.data['email']
@@ -545,14 +568,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.getPIEmails(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
@@ -579,6 +605,7 @@ class NodeRecord:
        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 
 
@@ -659,6 +686,15 @@ def node_end_record(node):
                del act_all
                return False
 
+       pm = database.dbLoad("monitor_persistmessages")
+       if node not in pm:
+               del pm
+               return False
+       else:
+               print "deleting node record"
+               del pm[node]
+               database.dbDump("monitor_persistmessages", pm)
+
        a = Action(node, act_all[node][0])
        a.delField('rt')
        a.delField('found_rt_ticket')
@@ -667,8 +703,9 @@ def node_end_record(node):
        a.delField('first-found')
        rec = a.get()
        rec['action'] = ["close_rt"]
-       rec['category'] = "UNKNOWN"
+       rec['category'] = "ALPHA"       # assume that it's up...
        rec['stage'] = "monitor-end-record"
+       rec['ticket_id'] = None
        rec['time'] = time.time() - 7*60*60*24
        act_all[node].insert(0,rec)
        database.dbDump("act_all", act_all)