Skip to content

Commit

Permalink
Merge pull request #236 from sushanthakumar/oceanstor-alert
Browse files Browse the repository at this point in the history
Oceanstor alert model filling
  • Loading branch information
NajmudheenCT authored Jun 27, 2020
2 parents 8b8cbd4 + ec2895f commit 87841ab
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 5 deletions.
4 changes: 2 additions & 2 deletions delfin/alert_manager/alert_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def __init__(self):

def process_alert_info(self, alert):
"""Fills alert model using driver manager interface."""
storage = db.storage_get(context, alert['storage_id'])

ctxt = context.RequestContext()
storage = db.storage_get(ctxt, alert['storage_id'])
# Fill storage specific info
alert['storage_name'] = storage['name']
alert['vendor'] = storage['vendor']
Expand Down
3 changes: 2 additions & 1 deletion delfin/alert_manager/trap_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

# Currently static mib file list is loaded
# Mechanism to be changed to load all mib file
MIB_LOAD_LIST = ['SNMPv2-MIB', 'IF_MIB', 'EMCGATEWAY-MIB', 'FCMGMT-MIB']
MIB_LOAD_LIST = ['SNMPv2-MIB', 'IF_MIB', 'EMCGATEWAY-MIB', 'FCMGMT-MIB',
'ISM-HUAWEI-MIB']

AUTH_PROTOCOL_MAP = {"sha": config.usmHMACSHAAuthProtocol,
"md5": config.usmHMACMD5AuthProtocol}
Expand Down
111 changes: 111 additions & 0 deletions delfin/drivers/huawei/oceanstor/alert_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Copyright 2020 The SODA Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:#www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from oslo_log import log

from delfin import exception
from delfin.i18n import _

LOG = log.getLogger(__name__)


class AlertHandler(object):
"""Alert handling functions for huawei oceanstor driver"""
default_me_category = 'storage-subsystem'

def __init__(self):
pass

"""
Alert model contains below fields
category : Type of the reported notification
occur_time : Time of occurrence of alert. When trap does not contain it,
it will be filled with receive time
match_key : This info uniquely identifies the fault point. Several infos
such as source system id, location, alarm id together can be
used to construct this
me_dn : Unique id at resource module (management system) side. me stands
for management element here
me_name : Unique name at resource module (management system) side
native_me_dn : Unique id of the device at source system that reports the
alarm
location : Alarm location information. It helps to locate the lowest unit
where fault is originated(Name-value pairs)
ex: Location = subtrack, No = 1, Slot No = 5.
shelf Id = 1, board type = ADSL
event_type : Basic classification of the alarm. Probable values such as
status, configuration, topology ....
alarm_id : Identification of alarm
alarm_name : Name of the alarm, might need translation from alarm id
severity : Severity of alarm. Helps admin to decide on action to be taken
Probable values: Critical, Major, Minor, Warning, Info
device_alert_sn : Sequence number of alert generated. This will be helpful
during alert clearing process
manufacturer : Vendor of the device
Product_name : Name of the product
probable_cause : Probable reason for alert generation
clear_type : Alarm clearance type such as manual, automatic, reset clear
me_category : Resource category of the device generating the alarm
Probable value: Network,Server,Storage..
"""

def parse_alert(self, context, alert):
"""Parse alert data got from alert manager and fill the alert model."""

try:
alert_model = {}
# These information are sourced from device registration info
alert_model['me_dn'] = alert['storage_id']
alert_model['me_name'] = alert['storage_name']
alert_model['manufacturer'] = alert['vendor']
alert_model['product_name'] = alert['model']

# Fill default values for alert attributes
alert_model['category'] = alert['hwIsmReportingAlarmFaultCategory']
alert_model['location'] = alert['hwIsmReportingAlarmLocationInfo']
alert_model['event_type'] = alert['hwIsmReportingAlarmFaultType']
alert_model['severity'] = alert['hwIsmReportingAlarmFaultLevel']
alert_model['probable_cause'] \
= alert['hwIsmReportingAlarmAdditionInfo']
alert_model['me_category'] = self.default_me_category
alert_model['occur_time'] = alert['hwIsmReportingAlarmFaultTime']
alert_model['alarm_id'] = alert['hwIsmReportingAlarmAlarmID']
alert_model['alarm_name'] = alert['hwIsmReportingAlarmFaultTitle']
alert_model['device_alert_sn'] = \
alert['hwIsmReportingAlarmSerialNo']
alert_model['clear_type'] = ""
alert_model['match_key'] = ""
alert_model['native_me_dn'] = ""
return alert_model
except Exception as e:
LOG.error(e)
msg = (_("Failed to build alert model as some attributes missing "
"in alert message."))
raise exception.InvalidResults(msg)

def add_trap_config(self, context, storage_id, trap_config):
"""Config the trap receiver in storage system."""
# Currently not implemented
pass

def remove_trap_config(self, context, storage_id, trap_config):
"""Remove trap receiver configuration from storage system."""
# Currently not implemented
pass

def clear_alert(self, context, storage_id, alert):
# Currently not implemented
"""Clear alert from storage system."""
pass
4 changes: 2 additions & 2 deletions delfin/drivers/huawei/oceanstor/oceanstor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from oslo_log import log
from delfin.common import constants
from delfin.drivers.huawei.oceanstor import rest_client, consts
from delfin.drivers.huawei.oceanstor import rest_client, consts, alert_handler
from delfin.drivers import driver
from delfin import exception

Expand Down Expand Up @@ -179,7 +179,7 @@ def remove_trap_config(self, context, trap_config):
pass

def parse_alert(self, context, alert):
pass
return alert_handler.AlertHandler().parse_alert(context, alert)

def clear_alert(self, context, alert):
pass
119 changes: 119 additions & 0 deletions delfin/tests/unit/drivers/huawei/oceanstor/test_alert_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Copyright 2020 The SODA Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:#www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

from oslo_utils import importutils

from delfin import exception


class AlertHandlerTestCase(unittest.TestCase):
ALERT_HANDLER_CLASS = 'delfin.drivers.huawei.oceanstor.alert_handler' \
'.AlertHandler'

def _get_alert_handler(self):
alert_handler_class = importutils.import_class(
self.ALERT_HANDLER_CLASS)
alert_handler = alert_handler_class()
return alert_handler

def _get_fake_alert_info(self):
alert_info = {'storage_id': 'abcd-1234-56789',
'storage_name': 'storage1', 'vendor': 'fake vendor',
'model': 'fake model',
'hwIsmReportingAlarmLocationInfo': 'location1',
'hwIsmReportingAlarmFaultTitle': 'Trap Test Alarm',
'hwIsmReportingAlarmFaultType': 'equipmentFault',
'hwIsmReportingAlarmFaultLevel': 'criticalAlarm',
'hwIsmReportingAlarmAlarmID': '4294967294',
'hwIsmReportingAlarmSerialNo': '4294967295',
'hwIsmReportingAlarmAdditionInfo': 'This is just for '
'testing.Please '
'ignore it',
'hwIsmReportingAlarmFaultCategory': 'faultAlarm',
'hwIsmReportingAlarmLocationAlarmID': '230584300921369',
'hwIsmReportingAlarmFaultTime': '2020-6-25,1:42:26.0'}

return alert_info

def _get_fake_incomplete_alert_info(self):

# hwIsmReportingAlarmFaultCategory is missing here
alert_info = {'storage_id': 'abcd-1234-56789',
'storage_name': 'storage1', 'vendor': 'fake vendor',
'model': 'fake model',
'hwIsmReportingAlarmLocationInfo': 'location1',
'hwIsmReportingAlarmFaultTitle': 'Trap Test Alarm',
'hwIsmReportingAlarmFaultType': 'equipmentFault',
'hwIsmReportingAlarmFaultLevel': 'criticalAlarm',
'hwIsmReportingAlarmAlarmID': '4294967294',
'hwIsmReportingAlarmSerialNo': '4294967295',
'hwIsmReportingAlarmAdditionInfo': 'This is just for '
'testing.Please '
'ignore it',
'hwIsmReportingAlarmLocationAlarmID': '230584300921369',
'hwIsmReportingAlarmFaultTime': '2020-6-25,1:42:26.0'}

return alert_info

def test_parse_alert_with_all_necessary_info(self):
""" Success flow with all necessary parameters"""
alert_handler_inst = self._get_alert_handler()
alert = self._get_fake_alert_info()

expected_alert_model = {'me_dn': alert['storage_id'],
'me_name': alert['storage_name'],
'manufacturer': alert['vendor'],
'product_name': alert['model'],
'category':
alert['hwIsmReportingAlarmFaultCategory'],
'location':
alert['hwIsmReportingAlarmLocationInfo'],
'event_type':
alert['hwIsmReportingAlarmFaultType'],
'severity':
alert['hwIsmReportingAlarmFaultLevel'],
'probable_cause':
alert['hwIsmReportingAlarmAdditionInfo'],
'me_category': 'storage-subsystem',
'alarm_id':
alert['hwIsmReportingAlarmAlarmID'],
'alarm_name':
alert['hwIsmReportingAlarmFaultTitle'],
'device_alert_sn':
alert['hwIsmReportingAlarmSerialNo'],
'occur_time':
alert['hwIsmReportingAlarmFaultTime'],
'clear_type': '',
'match_key': '',
'native_me_dn': ''
}
context = {}
alert_model = alert_handler_inst.parse_alert(context, alert)

# Verify that all other fields are matching
self.assertDictEqual(expected_alert_model, alert_model)

def test_parse_alert_without_mandatory_info(self):
""" Error flow with some mandatory parameters missing"""
alert_handler_inst = self._get_alert_handler()
context = {}
alert = self._get_fake_incomplete_alert_info()
self.assertRaisesRegex(exception.InvalidResults,
"Failed to build alert "
"model as some "
"attributes missing in "
"alert message",
alert_handler_inst.parse_alert, context, alert)

0 comments on commit 87841ab

Please sign in to comment.