From c02c025a66f1ad64a9626d9cefb962c51d5eedb7 Mon Sep 17 00:00:00 2001 From: Lance Bragstad Date: Tue, 18 Jun 2019 17:52:29 +0000 Subject: [PATCH] Add ksa connection logic This commit pulls the ksa-specific logic from a previous attempt: Ibc35360dd4a952bbe63ee68ddafd5def0608949d Subsequent patches will use this connection to query unified limit information out of keystone. Change-Id: Iae45df091e98904fd6a30db9923b141279fb2cc0 Co-Authored-By: wangxiyuan --- lower-constraints.txt | 2 ++ oslo_limit/exception.py | 23 +++++++++++++++++++++ oslo_limit/limit.py | 37 +++++++++++++++++++++++++++++++++- oslo_limit/opts.py | 7 +++++++ oslo_limit/tests/test_limit.py | 18 +++++++++++++++++ requirements.txt | 2 ++ 6 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 oslo_limit/exception.py diff --git a/lower-constraints.txt b/lower-constraints.txt index 3b357f7..7bf2e20 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -3,7 +3,9 @@ hacking==0.12.0 keystoneauth1==3.9.0 oslo.config==5.2.0 oslo.i18n==3.15.3 +oslo.log==3.44.0 openstackdocstheme==1.20.0 +openstacksdk==0.31.1 oslotest==3.2.0 reno==2.5.0 Sphinx==1.8.0 diff --git a/oslo_limit/exception.py b/oslo_limit/exception.py new file mode 100644 index 0000000..4111f4d --- /dev/null +++ b/oslo_limit/exception.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +# 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_limit._i18n import _ + + +class SessionInitError(Exception): + def __init__(self, reason): + msg = _( + "Can't initialise OpenStackSDK session: %(reason)s." + ) % {'reason': reason} + super(SessionInitError, self).__init__(msg) diff --git a/oslo_limit/limit.py b/oslo_limit/limit.py index 0c6b8e7..0a02604 100644 --- a/oslo_limit/limit.py +++ b/oslo_limit/limit.py @@ -12,8 +12,42 @@ # License for the specific language governing permissions and limitations # under the License. +from keystoneauth1 import exceptions as ksa_exceptions +from keystoneauth1 import loading +from openstack import connection +from oslo_config import cfg +from oslo_log import log import six +from oslo_limit import exception +from oslo_limit import opts + +CONF = cfg.CONF +LOG = log.getLogger(__name__) +_SDK_CONNECTION = None +opts.register_opts(CONF) + + +def _get_keystone_connection(): + global _SDK_CONNECTION + if not _SDK_CONNECTION: + try: + auth = loading.load_auth_from_conf_options( + CONF, group='oslo_limit') + session = loading.load_session_from_conf_options( + CONF, group='oslo_limit', auth=auth) + _SDK_CONNECTION = connection.Connection(session=session).identity + except (ksa_exceptions.NoMatchingPlugin, + ksa_exceptions.MissingRequiredOptions, + ksa_exceptions.MissingAuthPlugin, + ksa_exceptions.DiscoveryFailure, + ksa_exceptions.Unauthorized) as e: + msg = 'Unable to initialize OpenStackSDK session: %s' % e + LOG.error(msg) + raise exception.SessionInitError(e) + + return _SDK_CONNECTION + class Enforcer(object): @@ -31,6 +65,7 @@ class Enforcer(object): raise ValueError(msg) self.usage_callback = usage_callback + self.connection = _get_keystone_connection() def enforce(self, project_id, deltas, resource_filters=None): """Check resource usage against limits and request deltas. @@ -56,6 +91,6 @@ class Enforcer(object): if not isinstance(deltas, dict): msg = 'deltas must be a dictionary.' raise ValueError(msg) - if not isinstance(resource_filters, list): + if resource_filters and not isinstance(resource_filters, list): msg = 'resource_filters must be a list.' raise ValueError(msg) diff --git a/oslo_limit/opts.py b/oslo_limit/opts.py index 723c8c0..a9dc9f9 100644 --- a/oslo_limit/opts.py +++ b/oslo_limit/opts.py @@ -52,4 +52,11 @@ def register_opts(conf): loading.register_session_conf_options(CONF, _option_group) loading.register_adapter_conf_options(CONF, _option_group, include_deprecated=False) + + loading.register_auth_conf_options(CONF, _option_group) + plugin_name = CONF.oslo_limit.auth_type + if plugin_name: + plugin_loader = loading.get_plugin_loader(plugin_name) + plugin_opts = loading.get_auth_plugin_conf_options(plugin_loader) + CONF.register_opts(plugin_opts, group=_option_group) conf.register_opts(_options, group=_option_group) diff --git a/oslo_limit/tests/test_limit.py b/oslo_limit/tests/test_limit.py index 8b53b99..b7ccde9 100644 --- a/oslo_limit/tests/test_limit.py +++ b/oslo_limit/tests/test_limit.py @@ -19,11 +19,17 @@ test_limit Tests for `limit` module. """ +import mock import uuid +from oslo_config import cfg +from oslo_config import fixture as config_fixture from oslotest import base from oslo_limit import limit +from oslo_limit import opts + +CONF = cfg.CONF class TestEnforcer(base.BaseTestCase): @@ -31,6 +37,18 @@ class TestEnforcer(base.BaseTestCase): def setUp(self): super(TestEnforcer, self).setUp() self.deltas = dict() + self.config_fixture = self.useFixture(config_fixture.Config(CONF)) + self.config_fixture.config( + group='oslo_limit', + auth_type='password' + ) + opts.register_opts(CONF) + self.config_fixture.config( + group='oslo_limit', + auth_url='http://identity.example.com' + ) + + limit._SDK_CONNECTION = mock.MagicMock() def _get_usage_for_project(self, project_id): return 8 diff --git a/requirements.txt b/requirements.txt index d42afb2..f523f83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ keystoneauth1>=3.9.0 # Apache-2.0 oslo.config>=5.2.0 # Apache-2.0 oslo.i18n>=3.15.3 # Apache-2.0 +oslo.log>=3.44.0 # Apache-2.0 +openstacksdk>=0.31.1 # Apache-2.0