Ejemplo n.º 1
0
 def __init__(self, context):
     ''' Constructor '''
     trace_id = (0, 'Analyze')
     self.description = ''
     self.rules = []
     self.new_alerts = []
     self.trace_id = trace_id
     self.ruleset = context
     self.error_handlers = GearErrorHandlers(context)
     self.always_gets_event = []
     self.gets_event_by_key = defaultdict(set)
     return
Ejemplo n.º 2
0
class GearAnalyzeRules(object):
    ''' The rules that do the analysis of the events '''
    
    def __init__(self, context):
        ''' Constructor '''
        trace_id = (0, 'Analyze')
        self.description = ''
        self.rules = []
        self.new_alerts = []
        self.trace_id = trace_id
        self.ruleset = context
        self.error_handlers = GearErrorHandlers(context)
        self.always_gets_event = []
        self.gets_event_by_key = defaultdict(set)
        return
    
    def __str__(self):
        outstr = ''
        for rule in self.rules:
            outstr += str(rule)
        return outstr
    
    def read_from_xml(self, xml_element, trace_dict):
        '''Add event info defined in an XML events element'''
        self.trace_id = trace_dict[xml_element]
        for rule_entry in xml_element:
            entry_name = rule_entry.tag.split('}')[-1]
            if entry_name == 'rule':
                self.rules.append(GearRule(rule_entry, trace_dict, self.ruleset))
            elif entry_name == 'on_error':
                self.error_handlers.read_from_xml_element(rule_entry, trace_dict)
            elif entry_name == 'description':
                self.description = rule_entry.text
            else:
                self.parse_error(self.trace_id[0], 'unexpected element {0}'.format(entry_name))
        return
    
    def resolve_and_validate(self):
        '''Resolve and validate the rules using the gear control info'''
        self.error_handlers.resolve_and_validate()
        if len(self.rules) == 0:
            self.ruleset.parse_error(self.trace_id[0], 'analyze element must contain at least one \'rule\' element')
        for rule in self.rules:
            rule.resolve_and_validate()
            event_checked_info = rule.get_checked_event_info()
            if event_checked_info is None:
                self.always_gets_event.append(rule)
            else:
                for ec in event_checked_info:
                    self.gets_event_by_key[ec].add(rule)

        if self.ruleset[GRSE_ANALYZE].error_handlers.check_locations() == True: 
            # Get the locations to check
            used_locs = set()
            for rule in self.rules:
                t_used_locs = rule.get_used_locations()
                if t_used_locs is not None:
                    used_locs.update(t_used_locs)
            self.chk_rpt_loc = False
            self.chk_ext_data = set()
            for used_loc in used_locs:
                gear_var_parts = _parse_gear_variable(used_loc.strip()).split('.')
                if gear_var_parts[1] == 'ext':
                    self.chk_ext_data.add(gear_var_parts[2])
                elif gear_var_parts[1] == 'rpt_loc':
                    self.chk_rpt_loc = True
                elif gear_var_parts[1] == 'src_loc':
                    pass  # assuming this one 
                else:
                    get_logger().debug('Unexpected value in location: {0}'.format(used_loc))
            if len(self.chk_ext_data) == 0:
                self.chk_ext_data = None
            
            self.prime = self.prime_CHECK_LOC
            self.analyze_event = self.analyze_event_CHECK_LOC
        else:
            self.prime = self.prime_NO_CHECK
            self.analyze_event = self.analyze_event_NO_CHECK
           
        #self.print_cross_ref()
        #print str(self.gets_event_by_key)
        return
    
    def _check_loc_ok(self, event):
        ''' Check the location '''
        if event.src_loc.is_unprocessable() == True:
            self.error_handlers.location_error(event, event.src_loc)
            return False
            
        if self.chk_rpt_loc == True \
         and event.rpt_loc is not None \
         and event.rpt_loc.is_unprocessable() == True:
            self.error_handlers.location_error(event, event.rpt_loc)
            return False
            
        if self.chk_ext_data is not None:
            for ext_var in self.chk_ext_data:
                if event.raw_data is not None \
                 and ext_var in event.raw_data \
                 and event.raw_data[ext_var] is not None \
                 and event.raw_data[ext_var].is_unprocessable() == True:
                    self.error_handlers.location_error(event, event.raw_data[ext_var])
                    return False
        return True
    
    def prime_CHECK_LOC(self, event, pool, gear_ctl):
        if self._check_loc_ok(event) == True:
            self.prime_NO_CHECK(event, pool, gear_ctl)
        return
    
    def analyze_event_CHECK_LOC(self, event, pool, gear_ctl):
        if self._check_loc_ok(event) == True:
            self.analyze_event_NO_CHECK(event, pool, gear_ctl)
        return
    
    def analyze_event_NO_CHECK(self, event, pool, gear_ctl):
        ''' Fire the events ''' 
        get_logger().debug('Accumulating event {0}'.format(str(event)))
#        for rule in self.rules:
#            rule.accumulate(event)
        for rule in self.always_gets_event:
            rule.accumulate(event)
        for rule in self.gets_event_by_key[(event.src_comp, event.event_id)]:
            rule.accumulate(event)
        return
    
    def prime_NO_CHECK(self, event, pool, gear_ctl):
        ''' Prime the condition with the event '''
        get_logger().debug('Priming rule group with event {0}'.format(str(event)))
#        for rule in self.rules:
#            rule.prime(event)
        for rule in self.always_gets_event:
            rule.prime(event)
        for rule in self.gets_event_by_key[(event.src_comp, event.event_id)]:
            rule.prime(event)
        return
    
    def get_new_alerts(self):
        ''' Get any new alerts created by the actions '''
        ret_alerts = list(self.new_alerts)
        self.new_alerts = []
        return ret_alerts
    
    def reset(self):
        ''' reset the rules '''
        get_logger().debug('Reset rule group')
        for rule in self.rules:
            rule.reset()
        return
    
    def get_cross_ref(self):
        ''' get cross reference information ''' 
        condition_cref = defaultdict(list)
        suppression_cref = defaultdict(list)
        alert_cref = defaultdict(list)
        for rule in self.rules:
            conditions, suppressions, alerts = rule.get_cross_ref()
            line_num = rule.trace_id[0]
            for condition in conditions:
                condition_cref[condition].append(line_num)
            for suppression in suppressions:
                suppression_cref[suppression].append(line_num)
            for alert in alerts:
                alert_cref[alert].append(line_num)
        return {'condition': condition_cref, 'suppression': suppression_cref, 'create alert': alert_cref}

    def print_cross_ref(self):
        ''' print the cross reference '''
        cref_dict = self.get_cross_ref()
        cref_keys = cref_dict.keys()
        cref_keys.sort()
        for cref_key in cref_keys:
            print '\nCross reference where id is referenced by {0} (list of rule start line numbers)'.format(cref_key)
            entry_keys = cref_dict[cref_key].keys()
            entry_keys.sort()
            for entry_key in entry_keys:
                print '   {0}: {1}'.format(str(entry_key), str(cref_dict[cref_key][entry_key]))
        return 

    def close_pool(self, pool, gear_ctl):
        ''' Close pool processing '''
        alerts = []
        for rule in self.rules:
            rule.execute_suppression_stage(pool, gear_ctl)
        for rule in self.rules:
            new_alerts = rule.execute_alert_stage(pool, gear_ctl)
            if new_alerts is not None and len(new_alerts) != 0:
                alerts.extend(new_alerts)
        #print 'returning alerts ' + str(alerts)
        return alerts