Add a new zaqar notifier
also did some minor refactorings to the other notifiers Story: 2002681 Task: 22499 Change-Id: I06dfae2b67d1966eed472123f5bb6627d4cb19d0
This commit is contained in:
parent
30383d2dea
commit
cbf1b32498
@ -38,6 +38,7 @@ Notifiers
|
||||
notifier-snmp-plugin
|
||||
mistral-config
|
||||
notifier-webhook-plugin
|
||||
zaqar_notifier
|
||||
|
||||
|
||||
Machine_Learning
|
||||
|
21
doc/source/contributor/zaqar_notifier.rst
Normal file
21
doc/source/contributor/zaqar_notifier.rst
Normal file
@ -0,0 +1,21 @@
|
||||
===================
|
||||
Zaqar Configuration
|
||||
===================
|
||||
|
||||
Vitrage can be configured to notify raised or cleared alarms to Zaqar (the OpenStack Messaging service)
|
||||
|
||||
|
||||
Enable Zaqar Notifier
|
||||
---------------------
|
||||
|
||||
To enable Zaqar notifier, add zaqar to the list of notifiers and add the zaqar queue in
|
||||
/etc/vitrage/vitrage.conf file:
|
||||
|
||||
.. code::
|
||||
|
||||
[DEFAULT]
|
||||
notifiers = zaqar
|
||||
|
||||
[zaqar]
|
||||
queue = <zaqar queue name to post the message>
|
||||
|
@ -141,3 +141,4 @@ Werkzeug==0.14.1
|
||||
wrapt==1.10.11
|
||||
futures==3.0.0
|
||||
docutils==0.11
|
||||
python-zaqarclient==1.2.0
|
||||
|
@ -0,0 +1,3 @@
|
||||
features:
|
||||
- A new ``zaqar notifier`` was added, in order to send alrmas from Vitrage
|
||||
to zaqar messaging framework.
|
@ -16,6 +16,7 @@ python-heatclient>=1.14.0 # Apache-2.0
|
||||
python-mistralclient>=3.3.0 # Apache-2.0
|
||||
python-openstackclient>=3.12.0 # Apache-2.0
|
||||
python-troveclient>=2.2.0 # Apache-2.0
|
||||
python-zaqarclient >=1.2.0
|
||||
gnocchiclient>=3.3.1 # Apache-2.0
|
||||
pyzabbix>=0.7.4 # LGPL
|
||||
networkx>=2.0 # BSD
|
||||
|
@ -120,8 +120,8 @@ class GraphAction(object):
|
||||
class NotifierEventTypes(object):
|
||||
ACTIVATE_DEDUCED_ALARM_EVENT = 'vitrage.deduced_alarm.activate'
|
||||
DEACTIVATE_DEDUCED_ALARM_EVENT = 'vitrage.deduced_alarm.deactivate'
|
||||
ACTIVATE_ALARM_EVENT = 'vitrage.alarm.activate'
|
||||
DEACTIVATE_ALARM_EVENT = 'vitrage.alarm.deactivate'
|
||||
ACTIVATE_ALARM_EVENT = 'vitrage.alarm.activate' # also deduce
|
||||
DEACTIVATE_ALARM_EVENT = 'vitrage.alarm.deactivate' # also deduce
|
||||
CHANGE_IN_ALARM_EVENT = 'vitrage.alarm.change'
|
||||
CHANGE_PROJECT_ID_EVENT = 'vitrage.alarm.change_project_id'
|
||||
ACTIVATE_MARK_DOWN_EVENT = 'vitrage.mark_down.activate'
|
||||
@ -129,6 +129,7 @@ class NotifierEventTypes(object):
|
||||
EXECUTE_EXTERNAL_ACTION = 'vitrage.execute_external_action'
|
||||
ACTIVATE_CAUSAL_RELATION = 'vitrage.causal_relationship.activate'
|
||||
DEACTIVATE_CAUSAL_RELATION = 'vitrage.causal_relationship.deactivate'
|
||||
ALARMS = {ACTIVATE_ALARM_EVENT, DEACTIVATE_ALARM_EVENT}
|
||||
|
||||
|
||||
class TemplateTopologyFields(object):
|
||||
|
@ -1,15 +0,0 @@
|
||||
# Copyright 2016 - Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
pass
|
@ -56,12 +56,12 @@ class AodhNotifier(NotifierBase):
|
||||
if response and response.alarm_id:
|
||||
LOG.info('Aodh Alarm id %s: ', response.alarm_id)
|
||||
else:
|
||||
LOG.error('Failed to %s Aodh Alarm \n%s', event_type, str(data))
|
||||
LOG.error('Failed to %s Aodh Alarm \n%s', event_type, data)
|
||||
|
||||
def _create_aodh_alarm(self, alarm, state):
|
||||
alarm_request = _alarm_request(alarm, state)
|
||||
try:
|
||||
LOG.info('Aodh Alarm - Activate: ' + str(alarm_request))
|
||||
LOG.info('Aodh Alarm - Activate: ' + alarm_request)
|
||||
return self.client.alarm.create(alarm_request)
|
||||
except Exception:
|
||||
LOG.exception('Failed to activate Aodh Alarm. Got Exception.')
|
||||
|
@ -51,7 +51,7 @@ class NovaNotifier(NotifierBase):
|
||||
if action:
|
||||
action(data.get(VProps.ID), is_down)
|
||||
else:
|
||||
LOG.warning('Unsupport datasource type %s for mark_down '
|
||||
LOG.warning('Unsupported datasource type %s for mark_down '
|
||||
'action', data.get(VProps.VITRAGE_TYPE))
|
||||
|
||||
def _mark_host_down(self, host_id, is_down):
|
||||
@ -68,7 +68,7 @@ class NovaNotifier(NotifierBase):
|
||||
state = InstanceState.ERROR if is_down else InstanceState.ACTIVE
|
||||
try:
|
||||
LOG.info('Nova servers.reset_state - server: %s, state: %s',
|
||||
str(server_id), str(state))
|
||||
server_id, state)
|
||||
response = self.client.servers.reset_state(server_id, state)
|
||||
LOG.info('RESPONSE %s', str(response))
|
||||
except Exception:
|
||||
|
@ -67,17 +67,15 @@ class Webhook(NotifierBase):
|
||||
|
||||
def __init__(self, conf):
|
||||
super(Webhook, self).__init__(conf)
|
||||
self.conf = conf
|
||||
self._db = storage.get_connection_from_config(self.conf)
|
||||
self.max_retries = self.conf.webhook.max_retries
|
||||
self.default_headers = {'content-type': 'application/json'}
|
||||
|
||||
def process_event(self, data, event_type):
|
||||
|
||||
if event_type == NotifierEventTypes.ACTIVATE_ALARM_EVENT \
|
||||
or event_type == NotifierEventTypes.DEACTIVATE_ALARM_EVENT:
|
||||
if event_type in NotifierEventTypes.ALARMS:
|
||||
|
||||
LOG.info('Webhook notifier started processing %s', str(data))
|
||||
LOG.info('Webhook notifier started processing %s', data)
|
||||
|
||||
webhooks = self._load_webhooks()
|
||||
|
||||
@ -89,32 +87,31 @@ class Webhook(NotifierBase):
|
||||
data = self._filter_fields(data)
|
||||
|
||||
LOG.debug('webhook_filter: %s, filtered data: %s',
|
||||
str(webhook_filters), str(data))
|
||||
webhook_filters, data)
|
||||
|
||||
if self._check_against_filter(webhook_filters, data)\
|
||||
and self._check_correct_tenant(webhook, data):
|
||||
LOG.info('Going to post data to webhook %s',
|
||||
str(webhook))
|
||||
LOG.info('Going to post data to webhook %s', webhook)
|
||||
self._post_data(webhook, event_type, data)
|
||||
|
||||
LOG.info('Webhook notifier finished processing %s', str(data))
|
||||
LOG.info('Webhook notifier finished processing %s', data)
|
||||
|
||||
def _post_data(self, webhook, event_type, data):
|
||||
try:
|
||||
webhook_data = {'notification': event_type, 'payload': data}
|
||||
webhook_headers = self._get_webhook_headers(webhook)
|
||||
session = requests.Session()
|
||||
session.mount(str(webhook[URL]),
|
||||
session.mount(webhook[URL],
|
||||
requests.adapters.HTTPAdapter(
|
||||
max_retries=self.max_retries))
|
||||
resp = session.post(str(webhook[URL]),
|
||||
data=jsonutils.dumps(webhook_data),
|
||||
headers=webhook_headers)
|
||||
LOG.info('posted %s to %s. Response status %s, reason %s',
|
||||
str(webhook_data), str(webhook[URL]),
|
||||
webhook_data, webhook[URL],
|
||||
resp.status_code, resp.reason)
|
||||
except Exception:
|
||||
LOG.exception("Could not post to webhook '%s'", str(webhook['id']))
|
||||
LOG.exception("Could not post to webhook '%s'", webhook['id'])
|
||||
|
||||
def _load_webhooks(self):
|
||||
db_webhooks = self._db.webhooks.query()
|
||||
|
28
vitrage/notifier/plugins/zaqar/__init__.py
Normal file
28
vitrage/notifier/plugins/zaqar/__init__.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright 2019 - Nokia Corporation
|
||||
# #
|
||||
# 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_config import cfg
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('notifier',
|
||||
default='vitrage.notifier.plugins.zaqar.'
|
||||
'zaqar_notifier.ZaqarNotifier',
|
||||
help='zaqar notifier class path',
|
||||
required=True),
|
||||
|
||||
cfg.StrOpt('queue',
|
||||
default='alarms',
|
||||
help='zaqar queue to post messages',
|
||||
required=True),
|
||||
]
|
40
vitrage/notifier/plugins/zaqar/zaqar_notifier.py
Normal file
40
vitrage/notifier/plugins/zaqar/zaqar_notifier.py
Normal file
@ -0,0 +1,40 @@
|
||||
# Copyright 2019 - Nokia Corporation
|
||||
# #
|
||||
# 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 vitrage.common.constants import NotifierEventTypes
|
||||
from vitrage.notifier.plugins.base import NotifierBase
|
||||
from vitrage import os_clients
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class ZaqarNotifier(NotifierBase):
|
||||
|
||||
def __init__(self, conf):
|
||||
super(ZaqarNotifier, self).__init__(conf)
|
||||
client = os_clients.zaqar_client(self.conf)
|
||||
self._queue = client.queue(self.conf.zaqar.queue)
|
||||
|
||||
@staticmethod
|
||||
def get_notifier_name():
|
||||
return 'zaqar'
|
||||
|
||||
def process_event(self, data, event_type):
|
||||
if event_type in NotifierEventTypes.ALARMS:
|
||||
try:
|
||||
self._queue.post(data)
|
||||
except Exception:
|
||||
LOG.exception('Failed to post message to zaqar')
|
@ -29,6 +29,7 @@ import vitrage.machine_learning.plugins.jaccard_correlation
|
||||
import vitrage.notifier
|
||||
import vitrage.notifier.plugins.snmp
|
||||
import vitrage.notifier.plugins.webhook
|
||||
import vitrage.notifier.plugins.zaqar
|
||||
import vitrage.os_clients
|
||||
import vitrage.persistency
|
||||
import vitrage.rpc
|
||||
@ -61,6 +62,7 @@ def list_opts():
|
||||
('snmp', vitrage.notifier.plugins.snmp.OPTS),
|
||||
('webhook', vitrage.notifier.plugins.webhook.OPTS),
|
||||
('snmp_parsing', vitrage.snmp_parsing.OPTS),
|
||||
('zaqar', vitrage.notifier.plugins.zaqar.OPTS),
|
||||
('DEFAULT', itertools.chain(
|
||||
vitrage.os_clients.OPTS,
|
||||
vitrage.rpc.OPTS,
|
||||
|
@ -192,3 +192,16 @@ def mistral_client(conf):
|
||||
return client
|
||||
except Exception:
|
||||
LOG.exception('Create Mistral client - Got Exception.')
|
||||
|
||||
|
||||
def zaqar_client(conf):
|
||||
"""Get an instance of Zaqar client"""
|
||||
try:
|
||||
z_client = driver_module('zaqar')
|
||||
client = z_client.Client(
|
||||
session=keystone_client.get_session(conf),
|
||||
)
|
||||
LOG.info('Zaqar client created')
|
||||
return client
|
||||
except Exception:
|
||||
LOG.exception('Create Zaqar client - Got Exception.')
|
||||
|
Loading…
Reference in New Issue
Block a user