summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/openstack/common.py18
-rw-r--r--nova/api/openstack/compute/views/images.py6
-rw-r--r--nova/flags.py8
-rw-r--r--nova/tests/api/openstack/compute/test_flavors.py32
-rw-r--r--nova/tests/api/openstack/compute/test_images.py58
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,