From fd71ce8bab5ea737588b03f6753550587e35519c Mon Sep 17 00:00:00 2001 From: Patrick East Date: Mon, 22 Jun 2015 17:38:30 -0700 Subject: [PATCH] Add Cinder internal tenant support This adds two new config options as well as a helper method to get a RequestContext for the Cinder internal tenant. The current implementation will not create a request context that can be used for calls to other services, it is (as the name implies) only for internal Cinder operations. DocImpact: This adds new config steps that should be covered in the Cinder docs including the new config options: 'cinder_internal_tenant_project_id' and 'cinder_internal_tenant_user_id' Implements: blueprint cinder-internal-tenant Change-Id: I0c3263e71cf1a275a4538c35ebe1c7d750bb16e6 --- cinder/context.py | 36 +++++++++++++++++++++++++++- cinder/tests/unit/test_context.py | 39 +++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/cinder/context.py b/cinder/context.py index 23edc03d8..cd375d2b2 100644 --- a/cinder/context.py +++ b/cinder/context.py @@ -19,14 +19,28 @@ import copy +from oslo_config import cfg from oslo_context import context from oslo_log import log as logging from oslo_utils import timeutils import six -from cinder.i18n import _ +from cinder.i18n import _, _LW from cinder import policy +context_opts = [ + cfg.StrOpt('cinder_internal_tenant_project_id', + default=None, + help='ID of the project which will be used as the Cinder ' + 'internal tenant.'), + cfg.StrOpt('cinder_internal_tenant_user_id', + default=None, + help='ID of the user to be used in volume operations as the ' + 'Cinder internal tenant.'), +] + +CONF = cfg.CONF +CONF.register_opts(context_opts) LOG = logging.getLogger(__name__) @@ -171,3 +185,23 @@ def get_admin_context(read_deleted="no"): is_admin=True, read_deleted=read_deleted, overwrite=False) + + +def get_internal_tenant_context(): + """Build and return the Cinder internal tenant context object + + This request context will only work for internal Cinder operations. It will + not be able to make requests to remote services. To do so it will need to + use the keystone client to get an auth_token. + """ + project_id = CONF.cinder_internal_tenant_project_id + user_id = CONF.cinder_internal_tenant_user_id + + if project_id and user_id: + return RequestContext(user_id=user_id, + project_id=project_id, + is_admin=True) + else: + LOG.warning(_LW('Unable to get internal tenant context: Missing ' + 'required config parameters.')) + return None diff --git a/cinder/tests/unit/test_context.py b/cinder/tests/unit/test_context.py index ea3bd3f91..412cc42ef 100644 --- a/cinder/tests/unit/test_context.py +++ b/cinder/tests/unit/test_context.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import mock + from cinder import context from cinder import test @@ -95,3 +97,40 @@ class ContextTestCase(test.TestCase): project_domain="project-domain") self.assertEqual('user tenant domain user-domain project-domain', ctx.to_dict()["user_identity"]) + + @mock.patch('cinder.context.CONF') + def test_cinder_internal_context(self, mock_conf): + project_id = 'ec729e9946bc43c39ece6dfa7de70eea' + user_id = 'c466a48309794261b64a4f02cfcc3d64' + mock_conf.cinder_internal_tenant_project_id = project_id + mock_conf.cinder_internal_tenant_user_id = user_id + ctx = context.get_internal_tenant_context() + self.assertEqual(user_id, ctx.user_id) + self.assertEqual(project_id, ctx.project_id) + + @mock.patch('cinder.context.CONF') + def test_cinder_internal_context_missing_user(self, mock_conf): + project_id = 'ec729e9946bc43c39ece6dfa7de70eea' + user_id = None + mock_conf.cinder_internal_tenant_project_id = project_id + mock_conf.cinder_internal_tenant_user_id = user_id + ctx = context.get_internal_tenant_context() + self.assertIsNone(ctx) + + @mock.patch('cinder.context.CONF') + def test_cinder_internal_context_missing_project(self, mock_conf): + project_id = None + user_id = 'c466a48309794261b64a4f02cfcc3d64' + mock_conf.cinder_internal_tenant_project_id = project_id + mock_conf.cinder_internal_tenant_user_id = user_id + ctx = context.get_internal_tenant_context() + self.assertIsNone(ctx) + + @mock.patch('cinder.context.CONF') + def test_cinder_internal_context_missing_all(self, mock_conf): + project_id = None + user_id = None + mock_conf.cinder_internal_tenant_project_id = project_id + mock_conf.cinder_internal_tenant_user_id = user_id + ctx = context.get_internal_tenant_context() + self.assertIsNone(ctx) -- 2.45.2