From abb315961ed185be581f3f2059d2b2f4b182a371 Mon Sep 17 00:00:00 2001 From: akhil Date: Fri, 20 Jul 2018 15:42:25 +0530 Subject: [PATCH] Enable keystone authentication with webhook notification 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 --- monasca_notification/common/utils.py | 33 ++++++++++++ monasca_notification/conf/__init__.py | 3 ++ monasca_notification/conf/keystone.py | 52 +++++++++++++++++++ .../plugins/webhook_notifier.py | 8 +++ notification.yaml | 12 ++++- requirements.txt | 1 + 6 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 monasca_notification/conf/keystone.py diff --git a/monasca_notification/common/utils.py b/monasca_notification/common/utils.py index cf84203..67c9b61 100644 --- a/monasca_notification/common/utils.py +++ b/monasca_notification/common/utils.py @@ -15,8 +15,11 @@ # 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 @@ -133,3 +136,33 @@ class OfflineConnection(monascastatsd.Connection): 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 diff --git a/monasca_notification/conf/__init__.py b/monasca_notification/conf/__init__.py index b20e5b2..9dc80aa 100644 --- a/monasca_notification/conf/__init__.py +++ b/monasca_notification/conf/__init__.py @@ -22,6 +22,7 @@ from oslo_utils import importutils from monasca_notification.conf import cli from monasca_notification.conf import database from monasca_notification.conf import kafka +from monasca_notification.conf import keystone from monasca_notification.conf import notifiers from monasca_notification.conf import processors from monasca_notification.conf import queues @@ -36,6 +37,7 @@ CONF_OPTS = [ cli, database, kafka, + keystone, notifiers, processors, queues, @@ -144,6 +146,7 @@ def load_from_yaml(yaml_config, conf=None): ], 'queues': [lambda d: _plain_override(g='queues', **d)], 'kafka': [lambda d: _plain_override(g='kafka', **d)], + 'keystone': [lambda d: _plain_override(g='keystone', **d)], 'zookeeper': [lambda d: _plain_override(g='zookeeper', **d)], 'notification_types': [lambda d: _load_plugin_settings(**d)], 'logging': [_configure_and_warn_the_logging] diff --git a/monasca_notification/conf/keystone.py b/monasca_notification/conf/keystone.py new file mode 100644 index 0000000..b05fe5d --- /dev/null +++ b/monasca_notification/conf/keystone.py @@ -0,0 +1,52 @@ +# Copyright 2017 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. + +from oslo_config import cfg + +keystone_group = cfg.OptGroup('keystone', + title='Keystone Options', + help='Options under this group allow to configure ' + 'valid connection via Keystone' + 'authentication.') + +keystone_opts = [ + cfg.BoolOpt(name='auth_required', default='False', + help='This option enable or disable authentication using ' + 'keystone'), + cfg.StrOpt(name='auth_url', default='http://127.0.0.1/identity/v3', + help='URL of identity service'), + cfg.StrOpt(name='username', default='admin', + help='Username'), + cfg.StrOpt(name='password', default='password', + help='Password of identity service'), + cfg.StrOpt(name='project_name', default='admin', + help='Name of project'), + cfg.StrOpt(name='user_domain_name', default='default', + help='User domain name'), + cfg.StrOpt(name='project_domain_name', default='default', + help='Project domain name'), + cfg.StrOpt(name='auth_type', default='password', + help='Type of authentication') +] + + +def register_opts(conf): + conf.register_group(keystone_group) + conf.register_opts(keystone_opts, group=keystone_group) + + +def list_opts(): + return { + keystone_group: keystone_opts + } diff --git a/monasca_notification/plugins/webhook_notifier.py b/monasca_notification/plugins/webhook_notifier.py index ac21040..7f22619 100644 --- a/monasca_notification/plugins/webhook_notifier.py +++ b/monasca_notification/plugins/webhook_notifier.py @@ -20,6 +20,7 @@ import ujson as json from debtcollector import removals from oslo_config import cfg +from monasca_notification.common import utils from monasca_notification.plugins import abstract_notifier CONF = cfg.CONF @@ -73,6 +74,13 @@ class WebhookNotifier(abstract_notifier.AbstractNotifier): headers = {'content-type': 'application/json'} + # Checks if keystone authentication is enabled and adds authentication + # token to the request headers + if CONF.keystone.auth_required: + auth_token = utils.get_auth_token() + headers = {'content-type': 'application/json', + 'X-Auth-Token': auth_token} + url = notification.address try: diff --git a/notification.yaml b/notification.yaml index 10c6a6a..841fb5c 100644 --- a/notification.yaml +++ b/notification.yaml @@ -126,4 +126,14 @@ logging: # Used in logging.dictConfig level: DEBUG statsd: host: 'localhost' - port: 8125 \ No newline at end of file + port: 8125 + +keystone: + auth_required: False + auth_url: 'http://127.0.0.1/identity/v3' + username: 'admin' + password: 'password' + project_name: 'admin' + user_domain_name: 'default' + project_domain_name: 'default' + auth_type: 'password' diff --git a/requirements.txt b/requirements.txt index 0fc38a7..30904c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 debtcollector>=1.2.0 # Apache-2.0 +keystoneauth1>=3.4.0 # Apache-2.0 monasca-statsd>=1.4.0 # Apache-2.0 requests>=2.14.2 # Apache-2.0 PyYAML>=3.12 # MIT