Merge registry context with common context
Pull the extra methods defined in glance.registry.context:RequestContext into glance.common.context:RequestContext. This is necessary as the new v2 API implementation talks directly to the database. * Partially implements bp api-2 Change-Id: Ia8c1fde511bdca69be0dcf61ce12976ace5f7dc3
This commit is contained in:
parent
ba939295e3
commit
bd305fa07b
|
@ -47,12 +47,6 @@ information. In order to configure Glance to use Keystone, the
|
|||
Keystone distribution). The ``authtoken`` middleware performs the Keystone
|
||||
token validation, which is the heart of Keystone authentication.
|
||||
|
||||
It is important to note that the Glance API and the Glance Registry
|
||||
use two different context classes; this is because the registry needs
|
||||
advanced methods that are not available in the default context class.
|
||||
The implications of this will be obvious in the below example for
|
||||
configuring the Glance Registry.
|
||||
|
||||
Configuring Glance API to use Keystone
|
||||
--------------------------------------
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ paste.app_factory = glance.common.wsgi:app_factory
|
|||
glance.app_factory = glance.registry.api.v1:API
|
||||
|
||||
[filter:context]
|
||||
context_class = glance.registry.context.RequestContext
|
||||
paste.filter_factory = glance.common.wsgi:filter_factory
|
||||
glance.filter_factory = glance.common.context:ContextMiddleware
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ from glance.common import cfg
|
|||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance.common import wsgi
|
||||
from glance.registry.db import api as db_api
|
||||
|
||||
|
||||
class RequestContext(object):
|
||||
|
@ -51,6 +52,79 @@ class RequestContext(object):
|
|||
return True
|
||||
return False
|
||||
|
||||
def is_image_visible(self, image):
|
||||
"""Return True if the image is visible in this context."""
|
||||
# Is admin == image visible
|
||||
if self.is_admin:
|
||||
return True
|
||||
|
||||
# No owner == image visible
|
||||
if image.owner is None:
|
||||
return True
|
||||
|
||||
# Image is_public == image visible
|
||||
if image.is_public:
|
||||
return True
|
||||
|
||||
# Perform tests based on whether we have an owner
|
||||
if self.owner is not None:
|
||||
if self.owner == image.owner:
|
||||
return True
|
||||
|
||||
# Figure out if this image is shared with that tenant
|
||||
try:
|
||||
tmp = db_api.image_member_find(self, image.id, self.owner)
|
||||
return not tmp['deleted']
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
# Private image
|
||||
return False
|
||||
|
||||
def is_image_mutable(self, image):
|
||||
"""Return True if the image is mutable in this context."""
|
||||
# Is admin == image mutable
|
||||
if self.is_admin:
|
||||
return True
|
||||
|
||||
# No owner == image not mutable
|
||||
if image.owner is None or self.owner is None:
|
||||
return False
|
||||
|
||||
# Image only mutable by its owner
|
||||
return image.owner == self.owner
|
||||
|
||||
def is_image_sharable(self, image, **kwargs):
|
||||
"""Return True if the image can be shared to others in this context."""
|
||||
# Only allow sharing if we have an owner
|
||||
if self.owner is None:
|
||||
return False
|
||||
|
||||
# Is admin == image sharable
|
||||
if self.is_admin:
|
||||
return True
|
||||
|
||||
# If we own the image, we can share it
|
||||
if self.owner == image.owner:
|
||||
return True
|
||||
|
||||
# Let's get the membership association
|
||||
if 'membership' in kwargs:
|
||||
membership = kwargs['membership']
|
||||
if membership is None:
|
||||
# Not shared with us anyway
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
membership = db_api.image_member_find(self, image.id,
|
||||
self.owner)
|
||||
except exception.NotFound:
|
||||
# Not shared with us anyway
|
||||
return False
|
||||
|
||||
# It's the can_share attribute we're now interested in
|
||||
return membership.can_share
|
||||
|
||||
|
||||
class ContextMiddleware(wsgi.Middleware):
|
||||
|
||||
|
@ -62,12 +136,6 @@ class ContextMiddleware(wsgi.Middleware):
|
|||
def __init__(self, app, conf, **local_conf):
|
||||
self.conf = conf
|
||||
self.conf.register_opts(self.opts)
|
||||
|
||||
# Determine the context class to use
|
||||
self.ctxcls = RequestContext
|
||||
if 'context_class' in local_conf:
|
||||
self.ctxcls = utils.import_class(local_conf['context_class'])
|
||||
|
||||
super(ContextMiddleware, self).__init__(app)
|
||||
|
||||
def make_context(self, *args, **kwargs):
|
||||
|
@ -76,7 +144,7 @@ class ContextMiddleware(wsgi.Middleware):
|
|||
"""
|
||||
kwargs.setdefault('owner_is_tenant', self.conf.owner_is_tenant)
|
||||
|
||||
return self.ctxcls(*args, **kwargs)
|
||||
return RequestContext(*args, **kwargs)
|
||||
|
||||
def process_request(self, req):
|
||||
"""
|
||||
|
|
|
@ -23,10 +23,10 @@ import logging
|
|||
|
||||
import eventlet
|
||||
|
||||
from glance.common import context
|
||||
from glance.common import exception
|
||||
from glance.image_cache import ImageCache
|
||||
from glance import registry
|
||||
from glance.registry import context
|
||||
import glance.store
|
||||
import glance.store.filesystem
|
||||
import glance.store.http
|
||||
|
|
|
@ -23,10 +23,10 @@ import logging
|
|||
|
||||
import eventlet
|
||||
|
||||
from glance.common import context
|
||||
from glance.common import exception
|
||||
from glance.image_cache import ImageCache
|
||||
from glance import registry
|
||||
from glance.registry import context
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 glance.common import context
|
||||
from glance.common import exception
|
||||
from glance.registry.db import api as db_api
|
||||
|
||||
|
||||
class RequestContext(context.RequestContext):
|
||||
"""
|
||||
Stores information about the security context under which the user
|
||||
accesses the system, as well as additional request information.
|
||||
Also provides tests for image visibility and sharability.
|
||||
"""
|
||||
|
||||
def is_image_visible(self, image):
|
||||
"""Return True if the image is visible in this context."""
|
||||
# Is admin == image visible
|
||||
if self.is_admin:
|
||||
return True
|
||||
|
||||
# No owner == image visible
|
||||
if image.owner is None:
|
||||
return True
|
||||
|
||||
# Image is_public == image visible
|
||||
if image.is_public:
|
||||
return True
|
||||
|
||||
# Perform tests based on whether we have an owner
|
||||
if self.owner is not None:
|
||||
if self.owner == image.owner:
|
||||
return True
|
||||
|
||||
# Figure out if this image is shared with that tenant
|
||||
try:
|
||||
tmp = db_api.image_member_find(self, image.id, self.owner)
|
||||
return not tmp['deleted']
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
# Private image
|
||||
return False
|
||||
|
||||
def is_image_mutable(self, image):
|
||||
"""Return True if the image is mutable in this context."""
|
||||
# Is admin == image mutable
|
||||
if self.is_admin:
|
||||
return True
|
||||
|
||||
# No owner == image not mutable
|
||||
if image.owner is None or self.owner is None:
|
||||
return False
|
||||
|
||||
# Image only mutable by its owner
|
||||
return image.owner == self.owner
|
||||
|
||||
def is_image_sharable(self, image, **kwargs):
|
||||
"""Return True if the image can be shared to others in this context."""
|
||||
# Only allow sharing if we have an owner
|
||||
if self.owner is None:
|
||||
return False
|
||||
|
||||
# Is admin == image sharable
|
||||
if self.is_admin:
|
||||
return True
|
||||
|
||||
# If we own the image, we can share it
|
||||
if self.owner == image.owner:
|
||||
return True
|
||||
|
||||
# Let's get the membership association
|
||||
if 'membership' in kwargs:
|
||||
membership = kwargs['membership']
|
||||
if membership is None:
|
||||
# Not shared with us anyway
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
membership = db_api.image_member_find(self, image.id,
|
||||
self.owner)
|
||||
except exception.NotFound:
|
||||
# Not shared with us anyway
|
||||
return False
|
||||
|
||||
# It's the can_share attribute we're now interested in
|
||||
return membership.can_share
|
|
@ -347,7 +347,6 @@ paste.app_factory = glance.common.wsgi:app_factory
|
|||
glance.app_factory = glance.registry.api.v1:API
|
||||
|
||||
[filter:context]
|
||||
context_class = glance.registry.context.RequestContext
|
||||
paste.filter_factory = glance.common.wsgi:filter_factory
|
||||
glance.filter_factory = glance.common.context:ContextMiddleware
|
||||
|
||||
|
|
|
@ -67,14 +67,12 @@ def stub_out_registry_and_store_server(stubs, base_dir):
|
|||
def getresponse(self):
|
||||
sql_connection = os.environ.get('GLANCE_SQL_CONNECTION',
|
||||
"sqlite://")
|
||||
context_class = 'glance.registry.context.RequestContext'
|
||||
conf = utils.TestConfigOpts({
|
||||
'sql_connection': sql_connection,
|
||||
'verbose': VERBOSE,
|
||||
'debug': DEBUG
|
||||
})
|
||||
api = context.ContextMiddleware(rserver.API(conf),
|
||||
conf, context_class=context_class)
|
||||
api = context.ContextMiddleware(rserver.API(conf), conf)
|
||||
res = self.req.get_response(api)
|
||||
|
||||
# httplib.Response has a read() method...fake it out
|
||||
|
@ -237,14 +235,12 @@ def stub_out_registry_server(stubs, **kwargs):
|
|||
|
||||
def getresponse(self):
|
||||
sql_connection = kwargs.get('sql_connection', "sqlite:///")
|
||||
context_class = 'glance.registry.context.RequestContext'
|
||||
conf = utils.TestConfigOpts({
|
||||
'sql_connection': sql_connection,
|
||||
'verbose': VERBOSE,
|
||||
'debug': DEBUG
|
||||
})
|
||||
api = context.ContextMiddleware(rserver.API(conf),
|
||||
conf, context_class=context_class)
|
||||
api = context.ContextMiddleware(rserver.API(conf), conf)
|
||||
res = self.req.get_response(api)
|
||||
|
||||
# httplib.Response has a read() method...fake it out
|
||||
|
|
|
@ -22,12 +22,12 @@ import unittest
|
|||
|
||||
from glance import client
|
||||
from glance.common import client as base_client
|
||||
from glance.common import context
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance.registry.db import api as db_api
|
||||
from glance.registry.db import models as db_models
|
||||
from glance.registry import client as rclient
|
||||
from glance.registry import context as rcontext
|
||||
from glance.tests.unit import base
|
||||
from glance.tests import utils as test_utils
|
||||
|
||||
|
@ -149,7 +149,7 @@ class TestRegistryClient(base.IsolatedUnitTest):
|
|||
"""Establish a clean test environment"""
|
||||
super(TestRegistryClient, self).setUp()
|
||||
db_api.configure_db(self.conf)
|
||||
self.context = rcontext.RequestContext(is_admin=True)
|
||||
self.context = context.RequestContext(is_admin=True)
|
||||
self.FIXTURES = [
|
||||
{'id': UUID1,
|
||||
'name': 'fake image #1',
|
||||
|
@ -1228,7 +1228,7 @@ class TestClient(base.IsolatedUnitTest):
|
|||
'size': 19,
|
||||
'location': "file:///%s/%s" % (self.test_dir, UUID2),
|
||||
'properties': {}}]
|
||||
self.context = rcontext.RequestContext(is_admin=True)
|
||||
self.context = context.RequestContext(is_admin=True)
|
||||
self.destroy_fixtures()
|
||||
self.create_fixtures()
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
import unittest
|
||||
|
||||
from glance.registry import context
|
||||
from glance.common import context
|
||||
|
||||
|
||||
class FakeImage(object):
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
import datetime
|
||||
import random
|
||||
|
||||
from glance.common import context
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance.registry import context as rcontext
|
||||
from glance.registry.db import api as db_api
|
||||
from glance.registry.db import models as db_models
|
||||
from glance.tests.unit import base
|
||||
|
@ -90,8 +90,8 @@ class TestRegistryDb(base.IsolatedUnitTest):
|
|||
"""Establish a clean test environment"""
|
||||
super(TestRegistryDb, self).setUp()
|
||||
conf = test_utils.TestConfigOpts(CONF)
|
||||
self.adm_context = rcontext.RequestContext(is_admin=True)
|
||||
self.context = rcontext.RequestContext(is_admin=False)
|
||||
self.adm_context = context.RequestContext(is_admin=True)
|
||||
self.context = context.RequestContext(is_admin=False)
|
||||
db_api.configure_db(conf)
|
||||
self.destroy_fixtures()
|
||||
self.create_fixtures()
|
||||
|
@ -186,8 +186,8 @@ class TestPagingOrder(base.IsolatedUnitTest):
|
|||
"""Establish a clean test environment"""
|
||||
super(TestPagingOrder, self).setUp()
|
||||
conf = test_utils.TestConfigOpts(CONF)
|
||||
self.adm_context = rcontext.RequestContext(is_admin=True)
|
||||
self.context = rcontext.RequestContext(is_admin=False)
|
||||
self.adm_context = context.RequestContext(is_admin=True)
|
||||
self.context = context.RequestContext(is_admin=False)
|
||||
db_api.configure_db(conf)
|
||||
self.destroy_fixtures()
|
||||
self.create_fixtures()
|
||||
|
|
|
@ -29,7 +29,6 @@ from glance.api.v1 import images
|
|||
from glance.api.v1 import router
|
||||
from glance.common import context
|
||||
from glance.common import utils
|
||||
from glance.registry import context as rcontext
|
||||
from glance.registry.api import v1 as rserver
|
||||
from glance.registry.db import api as db_api
|
||||
from glance.registry.db import models as db_models
|
||||
|
@ -94,10 +93,7 @@ class TestRegistryAPI(base.IsolatedUnitTest):
|
|||
def setUp(self):
|
||||
"""Establish a clean test environment"""
|
||||
super(TestRegistryAPI, self).setUp()
|
||||
context_class = 'glance.registry.context.RequestContext'
|
||||
self.api = context.ContextMiddleware(rserver.API(self.conf),
|
||||
self.conf,
|
||||
context_class=context_class)
|
||||
self.api = context.ContextMiddleware(rserver.API(self.conf), self.conf)
|
||||
self.FIXTURES = [
|
||||
{'id': UUID1,
|
||||
'name': 'fake image #1',
|
||||
|
@ -131,7 +127,7 @@ class TestRegistryAPI(base.IsolatedUnitTest):
|
|||
'size': 19,
|
||||
'location': "file:///%s/%s" % (self.test_dir, UUID2),
|
||||
'properties': {}}]
|
||||
self.context = rcontext.RequestContext(is_admin=True)
|
||||
self.context = context.RequestContext(is_admin=True)
|
||||
db_api.configure_db(self.conf)
|
||||
self.destroy_fixtures()
|
||||
self.create_fixtures()
|
||||
|
@ -1989,7 +1985,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
|
|||
'size': 19,
|
||||
'location': "file:///%s/%s" % (self.test_dir, UUID2),
|
||||
'properties': {}}]
|
||||
self.context = rcontext.RequestContext(is_admin=True)
|
||||
self.context = context.RequestContext(is_admin=True)
|
||||
db_api.configure_db(self.conf)
|
||||
self.destroy_fixtures()
|
||||
self.create_fixtures()
|
||||
|
@ -2991,9 +2987,9 @@ class TestImageSerializer(base.IsolatedUnitTest):
|
|||
super(TestImageSerializer, self).setUp()
|
||||
self.receiving_user = 'fake_user'
|
||||
self.receiving_tenant = 2
|
||||
self.context = rcontext.RequestContext(is_admin=True,
|
||||
user=self.receiving_user,
|
||||
tenant=self.receiving_tenant)
|
||||
self.context = context.RequestContext(is_admin=True,
|
||||
user=self.receiving_user,
|
||||
tenant=self.receiving_tenant)
|
||||
self.serializer = images.ImageSerializer(self.conf)
|
||||
|
||||
def image_iter():
|
||||
|
|
|
@ -7,7 +7,6 @@ import keystoneclient.v2_0.client
|
|||
|
||||
import glance.common.context
|
||||
import glance.common.cfg
|
||||
import glance.registry.context
|
||||
import glance.registry.db.api as db_api
|
||||
|
||||
|
||||
|
@ -77,7 +76,7 @@ if __name__ == "__main__":
|
|||
|
||||
db_api.configure_db(config)
|
||||
|
||||
context = glance.registry.context.RequestContext(is_admin=True)
|
||||
context = glance.common.context.RequestContext(is_admin=True)
|
||||
|
||||
auth_uri = config.keystone_auth_uri
|
||||
admin_tenant_name = config.keystone_admin_tenant_name
|
||||
|
|
Loading…
Reference in New Issue