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