Makes deployed APIs configurable
Uses config options enable_v1_api and enable_v2_api to control which APIs have been deployed. (Thanks markwash for all the help) Fixes bug 1043497 Change-Id: I42dc1d88f94e61b9550c5f114ffc1abad25be7ff
This commit is contained in:
parent
3d4e962dac
commit
39700637e3
|
@ -23,7 +23,7 @@ pipeline = versionnegotiation authtoken context cache rootapp
|
|||
pipeline = versionnegotiation authtoken context cache cachemanage rootapp
|
||||
|
||||
[composite:rootapp]
|
||||
use = egg:Paste#urlmap
|
||||
paste.composite_factory = glance.api:root_app_factory
|
||||
/: apiversions
|
||||
/v1: apiv1app
|
||||
/v2: apiv2app
|
||||
|
|
|
@ -71,6 +71,12 @@ workers = 0
|
|||
# privileges. This only applies when using ContextMiddleware.
|
||||
#allow_anonymous_access = False
|
||||
|
||||
# Allow access to version 1 of glance api
|
||||
# enable_v1_api = True
|
||||
|
||||
# Allow access to version 2 of glance api
|
||||
# enable_v2_api = True
|
||||
|
||||
# ================= Syslog Options ============================
|
||||
|
||||
# Send logs to syslog (/dev/log) instead of to file specified
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011-2012 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -14,3 +14,18 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import paste.urlmap
|
||||
|
||||
from glance.openstack.common import cfg
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def root_app_factory(loader, global_conf, **local_conf):
|
||||
if not CONF.enable_v1_api:
|
||||
del local_conf['/v1']
|
||||
if not CONF.enable_v2_api:
|
||||
del local_conf['/v2']
|
||||
return paste.urlmap.urlmap_factory(loader, global_conf, **local_conf)
|
||||
|
|
|
@ -24,6 +24,9 @@ return
|
|||
from glance.api import versions
|
||||
from glance.common import wsgi
|
||||
import glance.openstack.common.log as logging
|
||||
from glance.openstack.common import cfg
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -77,9 +80,9 @@ class VersionNegotiationFilter(wsgi.Middleware):
|
|||
:returns version found in the subject
|
||||
:raises ValueError if no acceptable version could be found
|
||||
"""
|
||||
if subject in ('v1', 'v1.0', 'v1.1'):
|
||||
if subject in ('v1', 'v1.0', 'v1.1') and CONF.enable_v1_api:
|
||||
major_version = 1
|
||||
elif subject in ('v2', 'v2.0'):
|
||||
elif subject in ('v2', 'v2.0') and CONF.enable_v2_api:
|
||||
major_version = 2
|
||||
else:
|
||||
raise ValueError()
|
||||
|
|
|
@ -21,6 +21,10 @@ import json
|
|||
import webob.dec
|
||||
|
||||
from glance.common import wsgi
|
||||
from glance.openstack.common import cfg
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class Controller(object):
|
||||
|
@ -41,11 +45,15 @@ class Controller(object):
|
|||
],
|
||||
}
|
||||
|
||||
version_objs = [
|
||||
build_version_object(2.0, 'v2', 'EXPERIMENTAL'),
|
||||
build_version_object(1.1, 'v1', 'CURRENT'),
|
||||
build_version_object(1.0, 'v1', 'SUPPORTED'),
|
||||
]
|
||||
version_objs = []
|
||||
if CONF.enable_v2_api:
|
||||
version_objs.append(
|
||||
build_version_object(2.0, 'v2', 'EXPERIMENTAL'))
|
||||
if CONF.enable_v1_api:
|
||||
version_objs.append(
|
||||
build_version_object(1.1, 'v1', 'CURRENT'))
|
||||
version_objs.append(
|
||||
build_version_object(1.0, 'v1', 'SUPPORTED'))
|
||||
|
||||
response = webob.Response(request=req,
|
||||
status=httplib.MULTIPLE_CHOICES,
|
||||
|
|
|
@ -54,6 +54,10 @@ common_opts = [
|
|||
cfg.IntOpt('image_size_cap', default=1099511627776,
|
||||
help=_("Maximum size of image a user can upload in bytes. "
|
||||
"Defaults to 1099511627776 bytes (1 TB).")),
|
||||
cfg.BoolOpt('enable_v1_api', default=True,
|
||||
help=_("Deploy the v1 OpenStack Images API. ")),
|
||||
cfg.BoolOpt('enable_v2_api', default=True,
|
||||
help=_("Deploy the v2 OpenStack Images API. ")),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
|
|
@ -67,6 +67,8 @@ class Server(object):
|
|||
self.exec_env = None
|
||||
self.deployment_flavor = ''
|
||||
self.show_image_direct_url = False
|
||||
self.enable_v1_api = True
|
||||
self.enable_v2_api = True
|
||||
self.server_control_options = ''
|
||||
self.needs_database = False
|
||||
|
||||
|
@ -276,6 +278,8 @@ policy_default_rule = %(policy_default_rule)s
|
|||
db_auto_create = False
|
||||
sql_connection = %(sql_connection)s
|
||||
show_image_direct_url = %(show_image_direct_url)s
|
||||
enable_v1_api = %(enable_v1_api)s
|
||||
enable_v2_api= %(enable_v2_api)s
|
||||
[paste_deploy]
|
||||
flavor = %(deployment_flavor)s
|
||||
"""
|
||||
|
@ -300,7 +304,7 @@ pipeline = versionnegotiation fakeauth context rootapp
|
|||
pipeline = versionnegotiation context rootapp
|
||||
|
||||
[composite:rootapp]
|
||||
use = egg:Paste#urlmap
|
||||
paste.composite_factory = glance.api:root_app_factory
|
||||
/: apiversions
|
||||
/v1: apiv1app
|
||||
/v2: apiv2app
|
||||
|
|
|
@ -25,6 +25,100 @@ from glance.tests import functional
|
|||
|
||||
class TestRootApi(functional.FunctionalTest):
|
||||
|
||||
def test_version_configurations(self):
|
||||
"""Test that versioning is handled properly through all channels"""
|
||||
|
||||
#v1 and v2 api enabled
|
||||
self.cleanup()
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
|
||||
url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
|
||||
versions = {'versions': [
|
||||
{
|
||||
'id': 'v2.0',
|
||||
'status': 'EXPERIMENTAL',
|
||||
'links': [{'rel': 'self', 'href': url % '2'}],
|
||||
},
|
||||
{
|
||||
'id': 'v1.1',
|
||||
'status': 'CURRENT',
|
||||
'links': [{'rel': 'self', 'href': url % '1'}],
|
||||
},
|
||||
{
|
||||
'id': 'v1.0',
|
||||
'status': 'SUPPORTED',
|
||||
'links': [{'rel': 'self', 'href': url % '1'}],
|
||||
},
|
||||
]}
|
||||
versions_json = json.dumps(versions)
|
||||
images = {'images': []}
|
||||
images_json = json.dumps(images)
|
||||
|
||||
# Verify version choices returned.
|
||||
path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 300)
|
||||
self.assertEqual(content, versions_json)
|
||||
self.stop_servers()
|
||||
|
||||
#v2 api enabled
|
||||
self.cleanup()
|
||||
self.api_server.enable_v1_api = False
|
||||
self.api_server.enable_v2_api = True
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
|
||||
url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
|
||||
versions = {'versions': [
|
||||
{
|
||||
'id': 'v2.0',
|
||||
'status': 'EXPERIMENTAL',
|
||||
'links': [{'rel': 'self', 'href': url % '2'}],
|
||||
},
|
||||
]}
|
||||
versions_json = json.dumps(versions)
|
||||
images = {'images': []}
|
||||
images_json = json.dumps(images)
|
||||
|
||||
# Verify version choices returned.
|
||||
path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 300)
|
||||
self.assertEqual(content, versions_json)
|
||||
self.stop_servers()
|
||||
|
||||
#v1 api enabled
|
||||
self.cleanup()
|
||||
self.api_server.enable_v1_api = True
|
||||
self.api_server.enable_v2_api = False
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
|
||||
url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
|
||||
versions = {'versions': [
|
||||
{
|
||||
'id': 'v1.1',
|
||||
'status': 'CURRENT',
|
||||
'links': [{'rel': 'self', 'href': url % '1'}],
|
||||
},
|
||||
{
|
||||
'id': 'v1.0',
|
||||
'status': 'SUPPORTED',
|
||||
'links': [{'rel': 'self', 'href': url % '1'}],
|
||||
},
|
||||
]}
|
||||
versions_json = json.dumps(versions)
|
||||
images = {'images': []}
|
||||
images_json = json.dumps(images)
|
||||
|
||||
# Verify version choices returned.
|
||||
path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 300)
|
||||
self.assertEqual(content, versions_json)
|
||||
self.stop_servers()
|
||||
|
||||
def test_version_variations(self):
|
||||
"""Test that versioning is handled properly through all channels"""
|
||||
|
||||
|
|
|
@ -446,6 +446,28 @@ class TestApi(functional.FunctionalTest):
|
|||
|
||||
self.stop_servers()
|
||||
|
||||
@skip_if_disabled
|
||||
def test_v1_not_enabled(self):
|
||||
self.cleanup()
|
||||
self.api_server.enable_v1_api = False
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 300)
|
||||
self.stop_servers()
|
||||
|
||||
@skip_if_disabled
|
||||
def test_v1_enabled(self):
|
||||
self.cleanup()
|
||||
self.api_server.enable_v1_api = True
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
|
||||
http = httplib2.Http()
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 200)
|
||||
self.stop_servers()
|
||||
|
||||
@skip_if_disabled
|
||||
def test_zero_initial_size(self):
|
||||
"""
|
||||
|
|
|
@ -472,6 +472,22 @@ class TestImageDirectURLVisibility(functional.FunctionalTest):
|
|||
base_headers.update(custom_headers or {})
|
||||
return base_headers
|
||||
|
||||
def test_v2_not_enabled(self):
|
||||
self.api_server.enable_v2_api = False
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
path = self._url('/v2/images')
|
||||
response = requests.get(path, headers=self._headers())
|
||||
self.assertEqual(300, response.status_code)
|
||||
self.stop_servers()
|
||||
|
||||
def test_v2_enabled(self):
|
||||
self.api_server.enable_v2_api = True
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
path = self._url('/v2/images')
|
||||
response = requests.get(path, headers=self._headers())
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.stop_servers()
|
||||
|
||||
def test_image_direct_url_visible(self):
|
||||
|
||||
self.api_server.show_image_direct_url = True
|
||||
|
|
Loading…
Reference in New Issue