diff options
-rw-r--r-- | nova/api/openstack/common.py | 18 | ||||
-rw-r--r-- | nova/api/openstack/compute/views/images.py | 6 | ||||
-rw-r--r-- | nova/flags.py | 8 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/test_flavors.py | 32 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/test_images.py | 58 |
5 files changed, 120 insertions, 2 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index b46a6c1eb..c19b8f103 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -457,14 +457,18 @@ class ViewBuilder(object): """Return href string with proper limit and marker params.""" params = request.params.copy() params["marker"] = identifier - url = os.path.join(request.application_url, + prefix = self._update_link_prefix(request.application_url, + FLAGS.osapi_compute_link_prefix) + url = os.path.join(prefix, request.environ["nova.context"].project_id, self._collection_name) return "%s?%s" % (url, dict_to_query_str(params)) def _get_href_link(self, request, identifier): """Return an href string pointing to this object.""" - return os.path.join(request.application_url, + prefix = self._update_link_prefix(request.application_url, + FLAGS.osapi_compute_link_prefix) + return os.path.join(prefix, request.environ["nova.context"].project_id, self._collection_name, str(identifier)) @@ -472,6 +476,8 @@ class ViewBuilder(object): def _get_bookmark_link(self, request, identifier): """Create a URL that refers to a specific resource.""" base_url = remove_version_from_href(request.application_url) + base_url = self._update_link_prefix(base_url, + FLAGS.osapi_compute_link_prefix) return os.path.join(base_url, request.environ["nova.context"].project_id, self._collection_name, @@ -492,3 +498,11 @@ class ViewBuilder(object): "href": self._get_next_link(request, last_item_id), }) return links + + def _update_link_prefix(self, orig_url, prefix): + if not prefix: + return orig_url + url_parts = list(urlparse.urlsplit(orig_url)) + prefix_parts = list(urlparse.urlsplit(prefix)) + url_parts[1] = prefix_parts[1] + return urlparse.urlunsplit(url_parts) diff --git a/nova/api/openstack/compute/views/images.py b/nova/api/openstack/compute/views/images.py index 5ef1af59b..865e7df85 100644 --- a/nova/api/openstack/compute/views/images.py +++ b/nova/api/openstack/compute/views/images.py @@ -18,9 +18,13 @@ import os.path from nova.api.openstack import common +from nova import flags from nova import utils +FLAGS = flags.FLAGS + + class ViewBuilder(common.ViewBuilder): _collection_name = "images" @@ -109,6 +113,8 @@ class ViewBuilder(common.ViewBuilder): def _get_alternate_link(self, request, identifier): """Create an alternate link for a specific flavor id.""" glance_url = utils.generate_glance_url() + glance_url = self._update_link_prefix(glance_url, + FLAGS.osapi_glance_link_prefix) return os.path.join(glance_url, request.environ["nova.context"].project_id, self._collection_name, diff --git a/nova/flags.py b/nova/flags.py index 3decb2976..3f3560057 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -338,6 +338,14 @@ global_opts = [ cfg.StrOpt('osapi_path', default='/v1.1/', help='suffix for openstack'), + cfg.StrOpt('osapi_compute_link_prefix', + default=None, + help='Base URL that will be presented to users in links ' + 'to the Openstack Compute API'), + cfg.StrOpt('osapi_glance_link_prefix', + default=None, + help='Base URL that will be presented to users in links ' + 'to glance resources'), cfg.IntOpt('osapi_max_limit', default=1000, help='max number of items returned in a collection response'), diff --git a/nova/tests/api/openstack/compute/test_flavors.py b/nova/tests/api/openstack/compute/test_flavors.py index 8ad5eea0c..465a57497 100644 --- a/nova/tests/api/openstack/compute/test_flavors.py +++ b/nova/tests/api/openstack/compute/test_flavors.py @@ -24,11 +24,15 @@ from nova.api.openstack.compute import flavors from nova.api.openstack import xmlutil import nova.compute.instance_types from nova import exception +from nova import flags from nova import test from nova import utils from nova.tests.api.openstack import fakes +FLAGS = flags.FLAGS + + NS = "{http://docs.openstack.org/compute/api/v1.1}" ATOMNS = "{http://www.w3.org/2005/Atom}" @@ -130,6 +134,34 @@ class FlavorsTest(test.TestCase): } self.assertEqual(flavor, expected) + def test_get_flavor_with_custom_link_prefix(self): + self.flags(osapi_compute_link_prefix='http://zoo.com:42', + osapi_glance_link_prefix='http://circus.com:34') + req = fakes.HTTPRequest.blank('/v2/fake/flavors/1') + flavor = self.controller.show(req, '1') + expected = { + "flavor": { + "id": "1", + "name": "flavor 1", + "ram": "256", + "disk": "10", + "rxtx_factor": "", + "swap": "", + "vcpus": "", + "links": [ + { + "rel": "self", + "href": "http://zoo.com:42/v2/fake/flavors/1", + }, + { + "rel": "bookmark", + "href": "http://zoo.com:42/fake/flavors/1", + }, + ], + }, + } + self.assertEqual(flavor, expected) + def test_get_flavor_list(self): req = fakes.HTTPRequest.blank('/v2/fake/flavors') flavor = self.controller.index(req) diff --git a/nova/tests/api/openstack/compute/test_images.py b/nova/tests/api/openstack/compute/test_images.py index 893574241..460bf437f 100644 --- a/nova/tests/api/openstack/compute/test_images.py +++ b/nova/tests/api/openstack/compute/test_images.py @@ -26,6 +26,7 @@ from lxml import etree import stubout import webob +from nova import flags from nova.api.openstack.compute import images from nova.api.openstack.compute.views import images as images_view from nova.api.openstack import xmlutil @@ -34,6 +35,9 @@ from nova import utils from nova.tests.api.openstack import fakes +FLAGS = flags.FLAGS + + NS = "{http://docs.openstack.org/compute/api/v1.1}" ATOMNS = "{http://www.w3.org/2005/Atom}" NOW_API_FORMAT = "2010-10-11T10:30:22Z" @@ -117,6 +121,60 @@ class ImagesControllerTest(test.TestCase): self.assertDictMatch(expected_image, actual_image) + def test_get_image_with_custom_prefix(self): + self.flags(osapi_compute_link_prefix='http://zoo.com:42', + osapi_glance_link_prefix='http://circus.com:34') + fake_req = fakes.HTTPRequest.blank('/v2/fake/images/123') + actual_image = self.controller.show(fake_req, '124') + href = "http://zoo.com:42/v2/fake/images/124" + bookmark = "http://zoo.com:42/fake/images/124" + alternate = "http://circus.com:34/fake/images/124" + server_uuid = "aa640691-d1a7-4a67-9d3c-d35ee6b3cc74" + server_href = "http://localhost/v2/servers/" + server_uuid + server_bookmark = "http://localhost/servers/" + server_uuid + + expected_image = { + "image": { + "id": "124", + "name": "queued snapshot", + "updated": NOW_API_FORMAT, + "created": NOW_API_FORMAT, + "status": "SAVING", + "progress": 25, + "minDisk": 0, + "minRam": 0, + 'server': { + 'id': server_uuid, + "links": [{ + "rel": "self", + "href": server_href, + }, + { + "rel": "bookmark", + "href": server_bookmark, + }], + }, + "metadata": { + "instance_uuid": server_uuid, + "user_id": "fake", + }, + "links": [{ + "rel": "self", + "href": href, + }, + { + "rel": "bookmark", + "href": bookmark, + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": alternate + }], + }, + } + self.assertDictMatch(expected_image, actual_image) + def test_get_image_404(self): fake_req = fakes.HTTPRequest.blank('/v2/fake/images/unknown') self.assertRaises(webob.exc.HTTPNotFound, |