Massive commit. Just put all local changes into svn.
[monitor.git] / nodequery.py
1 #!/usr/bin/python
2
3 import plc
4 import auth
5 api = plc.PLC(auth.auth, auth.plc)
6
7 import soltesz
8 fb = soltesz.dbLoad("findbad")
9 fbpcu = soltesz.dbLoad("findbadpcus")
10 from nodecommon import *
11 from policy import Diagnose
12
13 import time
14 import re
15
16
17
18 def daysdown_print_nodeinfo(fbnode, hostname):
19         fbnode['hostname'] = hostname
20         fbnode['daysdown'] = Diagnose.getStrDaysDown(fbnode)
21         fbnode['intdaysdown'] = Diagnose.getDaysDown(fbnode)
22
23         print "%(intdaysdown)5s %(hostname)-44s | %(state)10.10s | %(daysdown)s" % fbnode
24
25 def fb_print_nodeinfo(fbnode, hostname):
26         fbnode['hostname'] = hostname
27         fbnode['checked'] = diff_time(fbnode['checked'])
28         if fbnode['bootcd']:
29                 fbnode['bootcd'] = fbnode['bootcd'].split()[-1]
30         else:
31                 fbnode['bootcd'] = "unknown"
32         if 'ERROR' in fbnode['category']:
33                 fbnode['kernel'] = ""
34         else:
35                 fbnode['kernel'] = fbnode['kernel'].split()[2]
36         fbnode['pcu'] = color_pcu_state(fbnode)
37         print "%(hostname)-39s | %(checked)11.11s | %(state)10.10s | %(ssh)5.5s | %(pcu)6.6s | %(bootcd)6.6s | %(category)8.8s | %(kernel)s" % fbnode
38
39 def verify(constraints, data):
40         """
41                 constraints is a list of key, value pairs.
42                 # [ {... : ...}==AND , ... , ... , ] == OR
43         """
44         con_or_true = False
45         for con in constraints:
46                 #print "con: %s" % con
47                 if len(con.keys()) == 0:
48                         con_and_true = False
49                 else:
50                         con_and_true = True
51
52                 for key in con.keys():
53                         #print "looking at key: %s" % key
54                         if key in data: 
55                                 value_re = re.compile(con[key])
56                                 con_and_true = con_and_true & (value_re.search(data[key]) is not None)
57                         elif key not in data:
58                                 print "missing key %s" % key
59                                 con_and_true = False
60
61                 con_or_true = con_or_true | con_and_true
62
63         return con_or_true
64
65 def query_to_dict(query):
66         
67         ad = []
68
69         or_queries = query.split('||')
70         for or_query in or_queries:
71                 and_queries = or_query.split('&&')
72
73                 d = {}
74
75                 for and_query in and_queries:
76                         (key, value) = and_query.split('=')
77                         d[key] = value
78
79                 ad.append(d)
80         
81         return ad
82
83 def _pcu_in(fbdata):
84         if 'plcnode' in fbdata:
85                 if 'pcu_ids' in fbdata['plcnode']:
86                         if len(fbdata['plcnode']['pcu_ids']) > 0:
87                                 return True
88         return False
89
90 def pcu_select(str_query):
91         pcunames = []
92         if str_query is None: return pcunames
93
94         #print str_query
95         dict_query = query_to_dict(str_query)
96         #print dict_query
97
98         for node in fb['nodes'].keys():
99         
100                 fb_nodeinfo  = fb['nodes'][node]['values']
101                 if _pcu_in(fb_nodeinfo):
102                         pcuinfo = fbpcu['nodes']['id_%s' % fb_nodeinfo['plcnode']['pcu_ids'][0]]['values']
103                         if verify(dict_query, pcuinfo):
104                                 pcunames.append(node)
105         
106         return pcunames
107
108 def node_select(str_query):
109         hostnames = []
110         if str_query is None: return hostnames
111
112         #print str_query
113         dict_query = query_to_dict(str_query)
114         #print dict_query
115
116         for node in fb['nodes'].keys():
117         
118                 fb_nodeinfo  = fb['nodes'][node]['values']
119
120                 if verify(dict_query, fb_nodeinfo):
121                         #print node #fb_nodeinfo
122                         hostnames.append(node)
123                 else:
124                         #print "NO MATCH", node
125                         pass
126         
127         return hostnames
128
129
130 def main():
131         from config import config
132         from optparse import OptionParser
133         parser = OptionParser()
134         parser.set_defaults(node=None, select=None, pcuselect=None, nodelist=None, daysdown=None)
135         parser.add_option("", "--daysdown", dest="daysdown", action="store_true",
136                                                 help="List the node state and days down...")
137         parser.add_option("", "--select", dest="select", metavar="key=value", 
138                                                 help="List all nodes with the given key=value pattern")
139         parser.add_option("", "--pcuselect", dest="pcuselect", metavar="key=value", 
140                                                 help="List all nodes with the given key=value pattern")
141         parser.add_option("", "--nodelist", dest="nodelist", metavar="nodelist.txt", 
142                                                 help="A list of nodes to bring out of debug mode.")
143         config = config(parser)
144         config.parse_args()
145
146         if config.nodelist:
147                 nodelist = config.getListFromFile(config.nodelist)
148         elif config.select is not None:
149                 nodelist = node_select(config.select)
150         elif config.pcuselect is not None:
151                 nodelist = pcu_select(config.pcuselect)
152         else:
153                 nodelist = fb['nodes'].keys()
154
155         for node in nodelist:
156                 config.node = node
157
158                 if node not in fb['nodes']:
159                         continue
160
161                 fb_nodeinfo  = fb['nodes'][node]['values']
162
163                 if config.daysdown:
164                         daysdown_print_nodeinfo(fb_nodeinfo, node)
165                 else:
166                         if config.select:
167                                 fb_print_nodeinfo(fb_nodeinfo, node)
168                         elif not config.select and 'state' in fb_nodeinfo:
169                                 fb_print_nodeinfo(fb_nodeinfo, node)
170                         else:
171                                 pass
172                 
173 if __name__ == "__main__":
174         main()