114 lines
3.8 KiB
Python
114 lines
3.8 KiB
Python
from statement import Rule, GrouperRule, AllenRule, Field, Arg
|
|
from pytables import FlowRecordsTable
|
|
import os
|
|
|
|
def flatten(l):
|
|
if isinstance(l,list):
|
|
return sum(map(flatten,l))
|
|
else:
|
|
return l
|
|
|
|
def if_exists_delete(path):
|
|
if os.path.exists(path):
|
|
if path[path.find('h5'):] == 'h5':
|
|
os.remove(path)
|
|
def iterate_subrules(rule):
|
|
for arg in rule.args:
|
|
if type(arg) in [Rule, GrouperRule, AllenRule]:
|
|
for r in iterate_subrules(arg):
|
|
yield r
|
|
yield arg
|
|
|
|
def iterate_args(rule):
|
|
for arg in rule.args:
|
|
yield arg
|
|
|
|
def iterate_rules(filter):
|
|
for rule_list in filter.rules:
|
|
for rule in rule_list:
|
|
if type(rule) not in [Rule, GrouperRule, AllenRule]:
|
|
continue
|
|
yield rule
|
|
for r in iterate_subrules(rule):
|
|
yield r
|
|
|
|
# returns the operation implementation from operators.py
|
|
# module, based on the operation contained in rule.op attribute
|
|
def find_op(rule, module='operators'):
|
|
imp = __import__(module)
|
|
op_name = rule.op
|
|
# print getattr(imp, op_name)
|
|
try:
|
|
return getattr(imp, op_name)
|
|
except AttributeError:
|
|
try:
|
|
external_imp = getattr(imp, 'external_import')
|
|
return getattr(external_imp, op_name)
|
|
except AttributeError:
|
|
raise SyntaxError('Uknown operator %s at line %s.'%(op_name,
|
|
rule.line))
|
|
|
|
def get_input_reader(parser):
|
|
"""Returns a reader for the parser's input"""
|
|
return FlowRecordsTable(parser.input.name) # parser.input.name is the ./netflow-trace.h5 file
|
|
|
|
def get_input_fields_types(input_reader):
|
|
return dict((f, t) for f, t in zip(input_reader.fields,
|
|
input_reader.types))
|
|
|
|
def check_rule_fields(rule, fields):
|
|
for arg in rule.args:
|
|
if type(arg) is Field:
|
|
if arg.name in fields:
|
|
continue
|
|
else:
|
|
msg = 'There is no such field %s, '%arg.name
|
|
msg += 'referenced at line %s'%rule.line
|
|
raise SyntaxError(msg)
|
|
|
|
def replace_bound_rules(filter):
|
|
'''
|
|
Iterate over the rules replacing evaluatable rules with their values
|
|
until there's nothing left to replace i.e. all remaining rules have
|
|
field references.
|
|
'''
|
|
def evaluate_rule(rule):
|
|
'''
|
|
Evaluates rule if possible i.e. rule contains no record field
|
|
references. If evaluation is not possible returns the original
|
|
rule.
|
|
'''
|
|
arg_types = [type(x) for x in rule.args]
|
|
if Rule in arg_types or Field in arg_types:
|
|
return rule
|
|
else:
|
|
# no references to record fields evaluate now
|
|
replace_bound_rules.count += 1
|
|
op = find_op(rule)
|
|
# hasattr() takes care of already replaced values
|
|
args = [a.value if hasattr(a, 'value') else a
|
|
for a in rule.args]
|
|
result = op(*args) if not rule.NOT else not op(*args)
|
|
|
|
return result
|
|
replace_bound_rules.count = 0
|
|
for rule in iterate_rules(filter):
|
|
newargs = [evaluate_rule(arg) if type(arg) is Rule else arg
|
|
for arg in rule.args]
|
|
rule.args = newargs
|
|
|
|
# we have to break because nasty stuff happens
|
|
# because the iterable is being changed
|
|
if replace_bound_rules.count !=0:
|
|
break
|
|
|
|
if replace_bound_rules.count != 0:
|
|
replace_bound_rules.count = 0
|
|
replace_bound_rules(filter)
|
|
|
|
def replace_with_vals(filter):
|
|
for rule in iterate_rules(filter):
|
|
for i, arg in enumerate(rule.args):
|
|
if type(arg) is Arg:
|
|
rule.args[i] = arg.value
|
|
|