Merge "Add codes of sending parsed snmp trap to datasource"

This commit is contained in:
Zuul 2018-01-17 13:20:06 +00:00 committed by Gerrit Code Review
commit caeb3b6ee6
8 changed files with 124 additions and 11 deletions

View File

@ -306,6 +306,7 @@ function start_vitrage {
run_process vitrage-notifier "$VITRAGE_BIN_DIR/vitrage-notifier --config-file $VITRAGE_CONF" run_process vitrage-notifier "$VITRAGE_BIN_DIR/vitrage-notifier --config-file $VITRAGE_CONF"
run_process vitrage-ml "$VITRAGE_BIN_DIR/vitrage-ml --config-file $VITRAGE_CONF" run_process vitrage-ml "$VITRAGE_BIN_DIR/vitrage-ml --config-file $VITRAGE_CONF"
run_process vitrage-persistor "$VITRAGE_BIN_DIR/vitrage-persistor --config-file $VITRAGE_CONF" run_process vitrage-persistor "$VITRAGE_BIN_DIR/vitrage-persistor --config-file $VITRAGE_CONF"
run_process vitrage-snmp-parsing "$VITRAGE_BIN_DIR/vitrage-snmp-parsing --config-file $VITRAGE_CONF"
write_systemd_dependency vitrage-graph vitrage-collector write_systemd_dependency vitrage-graph vitrage-collector
@ -335,7 +336,7 @@ function stop_vitrage {
disable_apache_site vitrage disable_apache_site vitrage
restart_apache_server restart_apache_server
fi fi
for serv in vitrage-api vitrage-collector vitrage-graph vitrage-notifier vitrage-persistor; do for serv in vitrage-api vitrage-collector vitrage-graph vitrage-notifier vitrage-persistor vitrage-snmp-parsing; do
stop_process $serv stop_process $serv
done done
} }

View File

@ -11,6 +11,8 @@ enable_service vitrage-collector
enable_service vitrage-ml enable_service vitrage-ml
# Persistor # Persistor
enable_service vitrage-persistor enable_service vitrage-persistor
# snmp_parsing
enable_service vitrage-snmp-parsing
# Default directories # Default directories
VITRAGE_DIR=$DEST/vitrage VITRAGE_DIR=$DEST/vitrage

View File

@ -19,6 +19,6 @@ OPTS = [
default=8162, default=8162,
help='The listening port of snmp_parsing service'), help='The listening port of snmp_parsing service'),
cfg.StrOpt('oid_mapping', cfg.StrOpt('oid_mapping',
default='/etc/vitrage/snmp_parsing_conf.yaml', default='',
help='The default path of oid_mapping yaml file'), help='The default path of oid_mapping yaml file.'),
] ]

View File

@ -0,0 +1,19 @@
# Copyright 2018 - ZTE
#
# 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.
class SnmpEventProperties(object):
SYSTEM_OID = 'system_oid'
SYSTEM = 'system'
DATASOURCE = 'datasource'

View File

@ -12,27 +12,37 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from datetime import datetime
import json
from oslo_log import log
import oslo_messaging
from oslo_service import service as os_service
from oslo_utils import uuidutils
from pyasn1.codec.ber import decoder from pyasn1.codec.ber import decoder
from pysnmp.carrier.asyncore.dgram import udp from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.carrier.asyncore.dgram import udp6 from pysnmp.carrier.asyncore.dgram import udp6
from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher from pysnmp.carrier.asyncore.dispatch import AsyncoreDispatcher
from pysnmp.proto import api as snmp_api from pysnmp.proto import api as snmp_api
from pysnmp.proto.rfc1902 import Integer from pysnmp.proto.rfc1902 import Integer
from oslo_log import log
from oslo_service import service as os_service
import sys import sys
from vitrage.common.constants import EventProperties
from vitrage.datasources.transformer_base import extract_field_value
from vitrage.messaging import get_transport
from vitrage.snmp_parsing.properties import SnmpEventProperties as SEProps
from vitrage.utils.file import load_yaml_file
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class SnmpParsingService(os_service.Service): class SnmpParsingService(os_service.Service):
RUN_FORVER = 1 RUN_FOREVER = 1
def __init__(self, conf): def __init__(self, conf):
super(SnmpParsingService, self).__init__() super(SnmpParsingService, self).__init__()
self.conf = conf self.conf = conf
self.listening_port = conf.snmp_parsing.snmp_listening_port self.listening_port = conf.snmp_parsing.snmp_listening_port
self._init_oslo_notifier()
def start(self): def start(self):
LOG.info("Vitrage SNMP Parsing Service - Starting...") LOG.info("Vitrage SNMP Parsing Service - Starting...")
@ -53,7 +63,7 @@ class SnmpParsingService(os_service.Service):
transport_dispatcher.registerTransport(udp6.domainName, udp6_transport) transport_dispatcher.registerTransport(udp6.domainName, udp6_transport)
LOG.info("Vitrage SNMP Parsing Service - Started!") LOG.info("Vitrage SNMP Parsing Service - Started!")
transport_dispatcher.jobStarted(self.RUN_FORVER) transport_dispatcher.jobStarted(self.RUN_FOREVER)
try: try:
transport_dispatcher.runDispatcher() transport_dispatcher.runDispatcher()
except Exception: except Exception:
@ -88,8 +98,8 @@ class SnmpParsingService(os_service.Service):
else p_mod.apiPDU.getVarBinds(req_pdu) else p_mod.apiPDU.getVarBinds(req_pdu)
binds_dict = self._convert_binds_to_dict(ver_binds) binds_dict = self._convert_binds_to_dict(ver_binds)
LOG.debug('Received binds info after convert: %s' % binds_dict) LOG.debug('Receive binds info after convert: %s' % binds_dict)
# TODO(peipei): need to send to message queue self._send_snmp_to_queue(binds_dict)
def _convert_binds_to_dict(self, var_binds): def _convert_binds_to_dict(self, var_binds):
binds_dict = {} binds_dict = {}
@ -104,3 +114,51 @@ class SnmpParsingService(os_service.Service):
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
return str(val).decode('iso-8859-1') return str(val).decode('iso-8859-1')
return str(val) return str(val)
def _init_oslo_notifier(self):
self.oslo_notifier = None
try:
self.publisher = 'vitrage-snmp-parsing'
self.oslo_notifier = oslo_messaging.Notifier(
get_transport(self.conf),
driver='messagingv2',
publisher_id=self.publisher,
topics=['vitrage_notifications'])
except Exception as e:
LOG.warning('Failed to initialize oslo notifier %s', str(e))
def _send_snmp_to_queue(self, snmp_trap):
if str == type(snmp_trap):
snmp_trap = json.loads(snmp_trap)
try:
event_type = self._get_event_type(snmp_trap)
if not event_type:
return
event = {EventProperties.TIME: datetime.utcnow(),
EventProperties.TYPE: event_type,
EventProperties.DETAILS: snmp_trap}
LOG.debug('snmp oslo_notifier event: %s' % event)
self.oslo_notifier.info(
ctxt={'message_id': uuidutils.generate_uuid(),
'publisher_id': self.publisher,
'timestamp': datetime.utcnow()},
event_type=event_type,
payload=event)
except Exception as e:
LOG.warning('Snmp failed to post event. Exception: %s', e)
def _get_event_type(self, snmp_trap):
yaml_file_content = load_yaml_file(self.conf.snmp_parsing.oid_mapping)
if not yaml_file_content:
LOG.warning('No snmp trap is configured!')
return None
for mapping_info in yaml_file_content:
system_oid = extract_field_value(mapping_info, SEProps.SYSTEM_OID)
conf_system = extract_field_value(mapping_info, SEProps.SYSTEM)
if conf_system == extract_field_value(snmp_trap, system_oid):
LOG.debug('snmp trap mapped the system: %s.' % conf_system)
return extract_field_value(mapping_info, SEProps.DATASOURCE)
LOG.error("Snmp trap does not contain system info!")
return None

View File

@ -0,0 +1,3 @@
- system_oid: 1.3.6.1.4.1.3902.4101.1.3.1.12
system: Tecs Director
datasource: vitrage.snmp.event

View File

@ -0,0 +1,15 @@
# Copyright 2018 - ZTE
#
# 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.
__author__ = 'stack'

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
from oslo_config import cfg from oslo_config import cfg
from pysnmp.proto.rfc1902 import Integer from pysnmp.proto.rfc1902 import Integer
@ -112,7 +113,8 @@ class TestSnmpParsing(base.BaseTest):
cfg.IntOpt('snmp_listening_port', default=8162, cfg.IntOpt('snmp_listening_port', default=8162,
help='The listening port of snmp_parsing service'), help='The listening port of snmp_parsing service'),
cfg.StrOpt('oid_mapping', cfg.StrOpt('oid_mapping',
default='/etc/vitrage/snmp_parsing_conf.yaml', default='vitrage/tests/resources/snmp_parsing/'
'snmp_parsing_conf.yaml',
help='The default path of oid_mapping yaml file'), help='The default path of oid_mapping yaml file'),
] ]
@ -127,3 +129,16 @@ class TestSnmpParsing(base.BaseTest):
parsing_service = SnmpParsingService(self.conf) parsing_service = SnmpParsingService(self.conf)
dict_converted = parsing_service._convert_binds_to_dict(BINDS_REPORTED) dict_converted = parsing_service._convert_binds_to_dict(BINDS_REPORTED)
self.assertEqual(dict_converted, DICT_EXPECTED) self.assertEqual(dict_converted, DICT_EXPECTED)
def test_get_event_type(self):
parsing_service = SnmpParsingService(self.conf)
event_type = parsing_service._get_event_type(DICT_EXPECTED)
self.assertEqual(event_type, 'vitrage.snmp.event')
def test_converted_trap_mapping_diff_system(self):
converted_trap_diff_sys = copy.copy(DICT_EXPECTED)
converted_trap_diff_sys.update(
{u'1.3.6.1.4.1.3902.4101.1.3.1.12': u'Different System'})
parsing_service = SnmpParsingService(self.conf)
event_type = parsing_service._get_event_type(converted_trap_diff_sys)
self.assertIsNone(event_type)