abb315961e
This commit adds functionality of sending webhook notifications to various projects that require keystone authentications. For which user need to set auth credentials in conf under keystone header. By default it is disabled, which can be enabled in conf. Change-Id: I3e773af8c3ebe0cf1d57e8fa1351b1e725a9cfa0 Partially-Implements: blueprint add-monasca-push-driver Story: 2003105 Task: 23220
169 lines
6.4 KiB
Python
169 lines
6.4 KiB
Python
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
|
|
# Copyright 2016 FUJITSU LIMITED
|
|
|
|
# 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 monascastatsd
|
|
|
|
from keystoneauth1 import exceptions as kaexception
|
|
from keystoneauth1 import loading as kaloading
|
|
from oslo_config import cfg
|
|
from oslo_log import log
|
|
import six
|
|
|
|
from monasca_notification.common.repositories import exceptions
|
|
from monasca_notification.notification import Notification
|
|
|
|
LOG = log.getLogger(__name__)
|
|
CONF = cfg.CONF
|
|
|
|
NOTIFICATION_DIMENSIONS = {'service': 'monitoring',
|
|
'component': 'monasca-notification'}
|
|
|
|
|
|
def get_db_repo():
|
|
repo_driver = CONF.database.repo_driver
|
|
LOG.debug('Enabling the %s RDB repository', repo_driver)
|
|
return repo_driver(CONF)
|
|
|
|
|
|
def construct_notification_object(db_repo, notification_json):
|
|
try:
|
|
notification = Notification(notification_json['id'],
|
|
notification_json['type'],
|
|
notification_json['name'],
|
|
notification_json['address'],
|
|
notification_json['period'],
|
|
notification_json['retry_count'],
|
|
notification_json['raw_alarm'])
|
|
# Grab notification method from database to see if it was changed
|
|
stored_notification = grab_stored_notification_method(db_repo, notification.id)
|
|
# Notification method was deleted
|
|
if stored_notification is None:
|
|
LOG.debug("Notification method {0} was deleted from database. "
|
|
"Will stop sending.".format(notification.id))
|
|
return None
|
|
# Update notification method with most up to date values
|
|
else:
|
|
notification.name = stored_notification[0]
|
|
notification.type = stored_notification[1]
|
|
notification.address = stored_notification[2]
|
|
notification.period = stored_notification[3]
|
|
return notification
|
|
except exceptions.DatabaseException:
|
|
LOG.warn("Error querying mysql for notification method. "
|
|
"Using currently cached method.")
|
|
return notification
|
|
except Exception as e:
|
|
LOG.warn("Error when attempting to construct notification {0}".format(e))
|
|
return None
|
|
|
|
|
|
def grab_stored_notification_method(db_repo, notification_id):
|
|
try:
|
|
stored_notification = db_repo.get_notification(notification_id)
|
|
except exceptions.DatabaseException:
|
|
LOG.debug('Database Error. Attempting reconnect')
|
|
stored_notification = db_repo.get_notification(notification_id)
|
|
|
|
return stored_notification
|
|
|
|
|
|
def get_statsd_client(dimensions=None):
|
|
local_dims = dimensions.copy() if dimensions else {}
|
|
local_dims.update(NOTIFICATION_DIMENSIONS)
|
|
if CONF.statsd.enable:
|
|
LOG.debug("Establishing connection with statsd on {0}:{1}"
|
|
.format(CONF.statsd.host, CONF.statsd.port))
|
|
client = monascastatsd.Client(name='monasca',
|
|
host=CONF.statsd.host,
|
|
port=CONF.statsd.port,
|
|
dimensions=local_dims)
|
|
else:
|
|
LOG.warn("StatsD monitoring disabled. Overriding monascastatsd.Client to use it offline")
|
|
client = OfflineClient(name='monasca',
|
|
host=CONF.statsd.host,
|
|
port=CONF.statsd.port,
|
|
dimensions=local_dims)
|
|
return client
|
|
|
|
|
|
class OfflineClient(monascastatsd.Client):
|
|
|
|
def _set_connection(self, connection, host, port):
|
|
if connection is None:
|
|
self.connection = OfflineConnection(host=host,
|
|
port=port,
|
|
max_buffer_size=self._max_buffer_size)
|
|
else:
|
|
self.connection = connection
|
|
|
|
|
|
class OfflineConnection(monascastatsd.Connection):
|
|
|
|
def __init__(self, host='localhost', port=8125, max_buffer_size=50):
|
|
"""Initialize an Offline Connection object.
|
|
|
|
>>> monascastatsd = MonascaStatsd()
|
|
|
|
:name: the name for this client. Everything sent by this client
|
|
will be prefixed by name
|
|
:param host: the host of the MonascaStatsd server.
|
|
:param port: the port of the MonascaStatsd server.
|
|
:param max_buffer_size: Maximum number of metric to buffer before
|
|
sending to the server if sending metrics in batch
|
|
"""
|
|
self.max_buffer_size = max_buffer_size
|
|
self._send = self._send_to_server
|
|
self.connect(host, port)
|
|
self.encoding = 'utf-8'
|
|
|
|
def connect(self, host, port):
|
|
"""Avoid connecting to the monascastatsd server.
|
|
|
|
"""
|
|
pass
|
|
|
|
def _send_to_server(self, packet):
|
|
pass
|
|
|
|
|
|
def get_keystone_session():
|
|
|
|
auth_details = {}
|
|
auth_details['auth_url'] = CONF.keystone.auth_url
|
|
auth_details['username'] = CONF.keystone.username
|
|
auth_details['password'] = CONF.keystone.password
|
|
auth_details['project_name'] = CONF.keystone.project_name
|
|
auth_details['user_domain_name'] = CONF.keystone.user_domain_name
|
|
auth_details['project_domain_name'] = CONF.keystone.project_domain_name
|
|
loader = kaloading.get_plugin_loader('password')
|
|
auth_plugin = loader.load_from_options(**auth_details)
|
|
session = kaloading.session.Session().load_from_options(
|
|
auth=auth_plugin)
|
|
return session
|
|
|
|
|
|
def get_auth_token():
|
|
error_message = 'Keystone request failed: {}'
|
|
try:
|
|
session = get_keystone_session()
|
|
auth_token = session.get_token()
|
|
return auth_token
|
|
except (kaexception.Unauthorized, kaexception.DiscoveryFailure) as e:
|
|
LOG.exception(error_message.format(six.text_type(e)))
|
|
raise
|
|
except Exception as e:
|
|
LOG.exception(error_message.format(six.text_type(e)))
|
|
raise
|