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
This commit is contained in:
Patrick East 2015-06-22 17:38:30 -07:00 committed by Tomoki Sekiyama
parent 0cc4b6d511
commit fd71ce8bab
2 changed files with 74 additions and 1 deletions

View File

@ -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

View File

@ -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)