--- /dev/null
+#!/usr/bin/python
+
+import os
+import re
+import sys
+import glob
+import time
+import string
+import traceback
+
+from monitor.common import *
+from monitor.database.info.model import FindbadNodeRecord, FindbadPCURecord
+
+class NoKeyException(Exception): pass
+
+def first(path):
+ indexes = path.split(".")
+ return indexes[0]
+
+def get(fb, path):
+ indexes = path.split(".")
+ values = fb
+ for index in indexes:
+ if values and index in values:
+ values = values[index]
+ elif values == {}:
+ values = ""
+ else:
+ print values, index
+ raise NoKeyException(index)
+ return values
+
+def verifyType(constraints, data):
+ """
+ constraints is a list of key, value pairs.
+ # [ {... : ...}==AND , ... , ... , ] == OR
+ """
+ con_or_true = False
+ for con in constraints:
+ #print "con: %s" % con
+ if len(con.keys()) == 0:
+ con_and_true = False
+ else:
+ con_and_true = True
+
+ for key in con.keys():
+ #print "looking at key: %s" % key
+ if data is None:
+ con_and_true = False
+ break
+
+ try:
+ get(data,key)
+ o = con[key]
+ if o.name() == "Match":
+ if get(data,key) is not None:
+ value_re = re.compile(o.value)
+ con_and_true = con_and_true & (value_re.search(get(data,key)) is not None)
+ else:
+ con_and_true = False
+ elif o.name() == "ListMatch":
+ if get(data,key) is not None:
+ match = False
+ for listitem in get(data,key):
+ value_re = re.compile(o.value)
+ if value_re.search(listitem) is not None:
+ match = True
+ break
+ con_and_true = con_and_true & match
+ else:
+ con_and_true = False
+ elif o.name() == "Is":
+ con_and_true = con_and_true & (get(data,key) == o.value)
+ elif o.name() == "FilledIn":
+ con_and_true = con_and_true & (len(get(data,key)) > 0)
+ elif o.name() == "PortOpen":
+ if get(data,key) is not None:
+ v = get(data,key)
+ con_and_true = con_and_true & (v[str(o.value)] == "open")
+ else:
+ con_and_true = False
+ else:
+ value_re = re.compile(o.value)
+ con_and_true = con_and_true & (value_re.search(get(data,key)) is not None)
+
+ except NoKeyException, key:
+ print "missing key %s" % key,
+ pass
+ #print "missing key %s" % key
+ #con_and_true = False
+
+ con_or_true = con_or_true | con_and_true
+
+ return con_or_true
+
+def verifyDBrecord(constraints, record):
+ """
+ constraints is a list of key, value pairs.
+ # [ {... : ...}==AND , ... , ... , ] == OR
+ """
+ def has_key(obj, key):
+ try:
+ x = obj.__getattribute__(key)
+ return True
+ except:
+ return False
+
+ def get_val(obj, key):
+ try:
+ return obj.__getattribute__(key)
+ except:
+ return None
+
+ def get(obj, path):
+ indexes = path.split("/")
+ value = get_val(obj,indexes[0])
+ if value is not None and len(indexes) > 1:
+ for key in indexes[1:]:
+ if key in value:
+ value = value[key]
+ else:
+ raise NoKeyException(key)
+ return value
+
+ #print constraints, record
+
+ con_or_true = False
+ for con in constraints:
+ #print "con: %s" % con
+ if len(con.keys()) == 0:
+ con_and_true = False
+ else:
+ con_and_true = True
+
+ for key in con.keys():
+ #print "looking at key: %s" % key
+ if has_key(record, key):
+ value_re = re.compile(con[key])
+ if type([]) == type(get(record,key)):
+ local_or_true = False
+ for val in get(record,key):
+ local_or_true = local_or_true | (value_re.search(val) is not None)
+ con_and_true = con_and_true & local_or_true
+ else:
+ if get(record,key) is not None:
+ con_and_true = con_and_true & (value_re.search(get(record,key)) is not None)
+ else:
+ print "missing key %s" % key,
+ pass
+
+ con_or_true = con_or_true | con_and_true
+
+ return con_or_true
+
+def verify(constraints, data):
+ """
+ constraints is a list of key, value pairs.
+ # [ {... : ...}==AND , ... , ... , ] == OR
+ """
+ con_or_true = False
+ for con in constraints:
+ #print "con: %s" % con
+ if len(con.keys()) == 0:
+ con_and_true = False
+ else:
+ con_and_true = True
+
+ for key in con.keys():
+ #print "looking at key: %s" % key
+ if first(key) in data:
+ value_re = re.compile(con[key])
+ if type([]) == type(get(data,key)):
+ local_or_true = False
+ for val in get(data,key):
+ local_or_true = local_or_true | (value_re.search(val) is not None)
+ con_and_true = con_and_true & local_or_true
+ else:
+ if get(data,key) is not None:
+ con_and_true = con_and_true & (value_re.search(get(data,key)) is not None)
+ elif first(key) not in data:
+ print "missing key %s" % first(key)
+
+ con_or_true = con_or_true | con_and_true
+
+ return con_or_true
+
+def query_to_dict(query):
+
+ ad = []
+
+ or_queries = query.split('||')
+ for or_query in or_queries:
+ and_queries = or_query.split('&&')
+
+ d = {}
+
+ for and_query in and_queries:
+ (key, value) = and_query.split('=')
+ d[key] = value
+
+ ad.append(d)
+
+ return ad
+
+def pcu_in(fbdata):
+ #if 'plcnode' in fbdata:
+ if 'plc_node_stats' in fbdata:
+ if fbdata['plc_node_stats'] and 'pcu_ids' in fbdata['plc_node_stats']:
+ if len(fbdata['plc_node_stats']['pcu_ids']) > 0:
+ return True
+ return False
+
+def pcu_select(str_query, nodelist=None):
+ pcunames = []
+ nodenames = []
+ if str_query is None: return (nodenames, pcunames)
+
+ if True:
+ fbquery = FindbadNodeRecord.get_all_latest()
+ fb_nodelist = [ n.hostname for n in fbquery ]
+ if True:
+ # NOTE: this doesn't work when there are only a few records current.
+ # pcu_select should apply to all pcus globally, not just the most recent records.
+ fbpcuquery = FindbadPCURecord.get_all_latest()
+ fbpcu_list = [ p.plc_pcuid for p in fbpcuquery ]
+
+ dict_query = query_to_dict(str_query)
+ print "dict_query", dict_query
+ print 'length %s' % len(fbpcuquery)
+
+ #for pcurec in fbpcuquery:
+ # pcuinfo = pcurec.to_dict()
+ # if verify(dict_query, pcuinfo):
+ # #nodenames.append(noderec.hostname)
+ # #print 'appending %s' % pcuinfo['plc_pcuid']
+ # pcunames.append(pcuinfo['plc_pcuid'])
+
+ for noderec in fbquery:
+ if nodelist is not None:
+ if noderec.hostname not in nodelist: continue
+
+ fb_nodeinfo = noderec.to_dict()
+ if pcu_in(fb_nodeinfo):
+ pcu_id = get(fb_nodeinfo, 'plc_node_stats.pcu_ids')[0]
+ pcurec = FindbadPCURecord.get_by(plc_pcuid=pcu_id)
+
+ if pcurec:
+ pcuinfo = pcurec.to_dict()
+ if verify(dict_query, pcuinfo):
+ nodenames.append(noderec.hostname)
+ pcunames.append(pcuinfo['plc_pcuid'])
+
+ return (nodenames, pcunames)
+
+def node_select(str_query, nodelist=None, fb=None):
+
+ hostnames = []
+ if str_query is None: return hostnames
+
+ #print str_query
+ dict_query = query_to_dict(str_query)
+ #print dict_query
+
+ for node in nodelist:
+ #if nodelist is not None:
+ # if node not in nodelist: continue
+
+ try:
+ fb_noderec = None
+ #fb_noderec = FindbadNodeRecord.query.filter(FindbadNodeRecord.hostname==node).order_by(FindbadNodeRecord.date_checked.desc()).first()
+ fb_noderec = FindbadNodeRecord.get_latest_by(hostname=node)
+ except KeyboardInterrupt:
+ print "Exiting at user request: Ctrl-C"
+ sys.exit(1)
+ except:
+ print traceback.print_exc()
+ continue
+
+ if fb_noderec:
+ fb_nodeinfo = fb_noderec.to_dict()
+
+ #fb_nodeinfo['pcu'] = color_pcu_state(fb_nodeinfo)
+ #if 'plcnode' in fb_nodeinfo:
+ # fb_nodeinfo.update(fb_nodeinfo['plcnode'])
+
+ if verify(dict_query, fb_nodeinfo):
+ #print fb_nodeinfo.keys()
+ #print node #fb_nodeinfo
+ hostnames.append(node)
+ else:
+ #print "NO MATCH", node
+ pass
+
+ return hostnames
+
+