Ejemplo n.º 1
0
    def take_action(self, alert, action, text, **kwargs):

        if action == 'invalid':
            raise InvalidAction(
                '{} is not a valid action for this status'.format(action))

        return alert, action, text
Ejemplo n.º 2
0
    def take_action(self, alert, action, text, **kwargs):

        if action == 'invalid':
            raise InvalidAction(
                f'{action} is not a valid action for this status')

        return alert, action, text
Ejemplo n.º 3
0
    def take_action(self, alert, action, text, **kwargs):

        alert.tags.remove('aDouble:Tag')

        if action == 'invalid':
            raise InvalidAction('{} is not a valid action for this status'.format(action))

        return alert, action, text
Ejemplo n.º 4
0
    def take_action(self, alert, action, text, **kwargs):

        if action == ACTION_ESCALATE:
            severity_level = str(alarm_model.Severity[alert.severity])
            try:
                alert.severity = escalate_map.get(severity_level)[0]
                text = 'alert severity escalated'
            except TypeError:
                raise InvalidAction(
                    f'Can not escalate alert severity beyond "{alert.severity}".'
                )

        return alert, action, text
Ejemplo n.º 5
0
    def transition(self, alert, current_status=None, previous_status=None, action=None, **kwargs):
        current_status = current_status or StateMachine.DEFAULT_STATUS
        previous_status = previous_status or StateMachine.DEFAULT_STATUS

        current_severity = alert.severity
        previous_severity = alert.previous_severity or StateMachine.DEFAULT_PREVIOUS_SEVERITY

        valid_severities = sorted(StateMachine.Severity, key=StateMachine.Severity.get)
        if current_severity not in StateMachine.Severity:
            raise ApiError(f"Severity ({current_severity}) is not one of {', '.join(valid_severities)}", 400)

        def next_state(rule, severity, status):
            current_app.logger.info(
                'State Transition: Rule #{} STATE={:8s} ACTION={:8s} SET={:8s} '
                'SEVERITY={:13s}-> {:8s} HISTORY={:8s}-> {:8s} => SEVERITY={:8s}, STATUS={:8s}'.format(
                    rule,
                    current_status,
                    action or '',
                    alert.status,
                    previous_severity,
                    current_severity,
                    previous_status,
                    current_status,
                    severity,
                    status
                ))
            return severity, status

        # if an unrecognised action is passed then assume state transition has been handled
        # by a take_action() plugin and return the current severity and status unchanged
        if action and action not in ACTION_ALL:
            return next_state('ACT-1', current_severity, alert.status)

        # if alert has non-default status then assume state transition has been handled
        # by a pre_receive() plugin and return the current severity and status, accounting
        # for auto-closing normal alerts, otherwise unchanged
        if not action and alert.status != StateMachine.DEFAULT_STATUS:
            if StateMachine.Severity[current_severity] == StateMachine.NORMAL_SEVERITY_LEVEL:
                return next_state('SET-1', StateMachine.DEFAULT_NORMAL_SEVERITY, Status.Closed)
            return next_state('SET-*', current_severity, alert.status)

        # state transition determined by operator action, if any, or severity changes
        state = current_status

        if action == Action.UNACK:
            if state == Status.Ack:
                return next_state('UNACK-1', current_severity, previous_status)
            else:
                raise InvalidAction(f'invalid action for current {state} status')

        if action == Action.UNSHELVE:
            if state == Status.Shelved:
                # as per ISA 18.2 recommendation 11.7.3 manually unshelved alarms transition to previous status
                return next_state('UNSHL-1', current_severity, previous_status)
            else:
                raise InvalidAction(f'invalid action for current {state} status')

        if action == Action.EXPIRED:
            return next_state('EXP-0', current_severity, Status.Expired)

        if action == Action.TIMEOUT:
            if previous_status == Status.Ack:
                return next_state('ACK-0', current_severity, Status.Ack)
            else:
                return next_state('OPEN-0', current_severity, Status.Open)

        if state == Status.Open:
            if action == Action.OPEN:
                raise InvalidAction(f'alert is already in {state} status')
            if action == Action.ACK:
                return next_state('OPEN-1', current_severity, Status.Ack)
            if action == Action.SHELVE:
                return next_state('OPEN-2', current_severity, Status.Shelved)
            if action == Action.CLOSE:
                return next_state('OPEN-3', StateMachine.DEFAULT_NORMAL_SEVERITY, Status.Closed)

        if state == Status.Assign:
            pass

        if state == Status.Ack:
            if action == Action.OPEN:
                return next_state('ACK-1', current_severity, Status.Open)
            if action == Action.ACK:
                raise InvalidAction(f'alert is already in {state} status')
            if action == Action.SHELVE:
                return next_state('ACK-2', current_severity, Status.Shelved)
            if action == Action.CLOSE:
                return next_state('ACK-3', StateMachine.DEFAULT_NORMAL_SEVERITY, Status.Closed)

            # re-open ack'ed alerts if the severity actually increases
            # not just because the previous severity is the default
            if previous_severity != StateMachine.DEFAULT_PREVIOUS_SEVERITY:
                if self.trend(previous_severity, current_severity) == TrendIndication.More_Severe:
                    return next_state('ACK-4', current_severity, Status.Open)

        if state == Status.Shelved:
            if action == Action.OPEN:
                return next_state('SHL-1', current_severity, Status.Open)
            if action == Action.ACK:
                raise InvalidAction(f'invalid action for current {state} status')
            if action == Action.SHELVE:
                raise InvalidAction(f'alert is already in {state} status')
            if action == Action.CLOSE:
                return next_state('SHL-2', StateMachine.DEFAULT_NORMAL_SEVERITY, Status.Closed)

        if state == Status.Blackout:
            if action == Action.CLOSE:
                return next_state('BLK-1', StateMachine.DEFAULT_NORMAL_SEVERITY, Status.Closed)

            if previous_status != Status.Blackout:
                return next_state('BLK-2', current_severity, previous_status)
            else:
                return next_state('BLK-*', current_severity, alert.status)

        if state == Status.Closed:
            if action == Action.OPEN:
                return next_state('CLS-1', previous_severity, Status.Open)
            if action == Action.ACK:
                raise InvalidAction(f'invalid action for current {state} status')
            if action == Action.SHELVE:
                raise InvalidAction(f'invalid action for current {state} status')
            if action == Action.CLOSE:
                raise InvalidAction(f'alert is already in {state} status')

            if StateMachine.Severity[current_severity] != StateMachine.NORMAL_SEVERITY_LEVEL:
                if previous_status == Status.Shelved:
                    return next_state('CLS-2', previous_severity, Status.Shelved)
                else:
                    return next_state('CLS-3', previous_severity, Status.Open)

        # auto-close normal severity alerts from ANY state
        if StateMachine.Severity[current_severity] == StateMachine.NORMAL_SEVERITY_LEVEL:
            return next_state('CLS-*', StateMachine.DEFAULT_NORMAL_SEVERITY, Status.Closed)

        if state == Status.Expired:
            if action and action != Action.OPEN:
                raise InvalidAction(f'invalid action for current {state} status')
            if StateMachine.Severity[current_severity] != StateMachine.NORMAL_SEVERITY_LEVEL:
                return next_state('EXP-1', current_severity, Status.Open)

        return next_state('ALL-*', current_severity, current_status)
Ejemplo n.º 6
0
    def transition(self, alert, current_status=None, previous_status=None, action=None, **kwargs):
        current_status = current_status or StateMachine.DEFAULT_STATUS
        previous_status = previous_status or StateMachine.DEFAULT_STATUS

        current_severity = alert.severity
        previous_severity = alert.previous_severity or StateMachine.DEFAULT_PREVIOUS_SEVERITY

        valid_severities = sorted(StateMachine.Severity, key=StateMachine.Severity.get)
        assert current_severity in StateMachine.Severity, 'Severity is not one of %s' % ', '.join(valid_severities)

        def next_state(rule, severity, status):
            current_app.logger.info(
                'State Transition: Rule #{} STATE={:8s} ACTION={:8s} SET={:8s} '
                'SEVERITY={:13s}-> {:8s} HISTORY={:8s}-> {:8s} => SEVERITY={:8s}, STATUS={:8s}'.format(
                    rule,
                    current_status,
                    action or '',
                    alert.status,
                    previous_severity,
                    current_severity,
                    previous_status,
                    current_status,
                    severity,
                    status
                ))
            return severity, status

        # if an unrecognised action is passed then assume state transition has been handled
        # by a take_action() plugin and return the current severity and status unchanged
        if action and action not in ACTION_ALL:
            return next_state('ACT-1', current_severity, alert.status)

        # if alert has non-default status then assume state transition has been handled
        # by a pre_receive() plugin and return the current severity and status, accounting
        # for auto-closing normal alerts, otherwise unchanged
        if not action and alert.status != StateMachine.DEFAULT_STATUS:
            if StateMachine.Severity[current_severity] == StateMachine.NORMAL_SEVERITY_LEVEL:
                return next_state('SET-1', StateMachine.DEFAULT_NORMAL_SEVERITY, CLOSED)
            return next_state('SET-*', current_severity, alert.status)

        # state transition determined by operator action, if any, or severity changes
        state = current_status

        if action == ACTION_UNACK:
            if state == ACK:
                return next_state('UNACK-1', current_severity, previous_status)
            else:
                raise InvalidAction('invalid action for current {} status'.format(state))

        if action == ACTION_UNSHELVE:
            if state == SHELVED:
                # as per ISA 18.2 recommendation 11.7.3 manually unshelved alarms transition to previous status
                return next_state('UNSHL-1', current_severity, previous_status)
            else:
                raise InvalidAction('invalid action for current {} status'.format(state))

        if state == OPEN:
            if action == ACTION_OPEN:
                raise InvalidAction('alert is already in {} status'.format(state))
            if action == ACTION_ACK:
                return next_state('OPEN-1', current_severity, ACK)
            if action == ACTION_SHELVE:
                return next_state('OPEN-2', current_severity, SHELVED)
            if action == ACTION_CLOSE:
                return next_state('OPEN-3', StateMachine.DEFAULT_NORMAL_SEVERITY, CLOSED)

        if state == ASSIGN:
            pass

        if state == ACK:
            if action == ACTION_OPEN:
                return next_state('ACK-1', current_severity, OPEN)
            if action == ACTION_ACK:
                raise InvalidAction('alert is already in {} status'.format(state))
            if action == ACTION_SHELVE:
                return next_state('ACK-2', current_severity, SHELVED)
            if action == ACTION_CLOSE:
                return next_state('ACK-3', StateMachine.DEFAULT_NORMAL_SEVERITY, CLOSED)

            # re-open ack'ed alerts if the severity actually increases
            # not just because the previous severity is the default
            if previous_severity != StateMachine.DEFAULT_PREVIOUS_SEVERITY:
                if self.trend(previous_severity, current_severity) == MORE_SEVERE:
                    return next_state('ACK-4', current_severity, OPEN)

        if state == SHELVED:
            if action == ACTION_OPEN:
                return next_state('SHL-1', current_severity, OPEN)
            if action == ACTION_ACK:
                raise InvalidAction('invalid action for current {} status'.format(state))
            if action == ACTION_SHELVE:
                raise InvalidAction('alert is already in {} status'.format(state))
            if action == ACTION_CLOSE:
                return next_state('SHL-2', StateMachine.DEFAULT_NORMAL_SEVERITY, CLOSED)

        if state == BLACKOUT:
            if action == ACTION_CLOSE:
                return next_state('BLK-1', StateMachine.DEFAULT_NORMAL_SEVERITY, CLOSED)

            if previous_status != BLACKOUT:
                return next_state('BLK-2', current_severity, previous_status)
            else:
                return next_state('BLK-*', current_severity, alert.status)

        if state == CLOSED:
            if action == ACTION_OPEN:
                return next_state('CLS-1', previous_severity, OPEN)
            if action == ACTION_ACK:
                raise InvalidAction('invalid action for current {} status'.format(state))
            if action == ACTION_SHELVE:
                raise InvalidAction('invalid action for current {} status'.format(state))
            if action == ACTION_CLOSE:
                raise InvalidAction('alert is already in {} status'.format(state))

            if StateMachine.Severity[current_severity] != StateMachine.NORMAL_SEVERITY_LEVEL:
                if previous_status == SHELVED:
                    return next_state('CLS-2', previous_severity, SHELVED)
                else:
                    return next_state('CLS-3', previous_severity, OPEN)

        # auto-close normal severity alerts from ANY state
        if StateMachine.Severity[current_severity] == StateMachine.NORMAL_SEVERITY_LEVEL:
            return next_state('CLS-*', StateMachine.DEFAULT_NORMAL_SEVERITY, CLOSED)

        if state == EXPIRED:
            if StateMachine.Severity[current_severity] != StateMachine.NORMAL_SEVERITY_LEVEL:
                return next_state('EXP-1', current_severity, OPEN)

        return next_state('ALL-*', current_severity, current_status)