From bb018b14fb8786090b2cf8b23723fa97defef9ce Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 20 Sep 2011 12:41:23 -0500 Subject: Added function to construct a glance URL and unit test. --- nova/flags.py | 4 +++- nova/image/glance.py | 7 +++++++ nova/tests/image/test_glance.py | 11 +++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nova/flags.py b/nova/flags.py index 971e78807..ffb313cec 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -271,8 +271,10 @@ DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake') DEFINE_string('aws_access_key_id', 'admin', 'AWS Access ID') DEFINE_string('aws_secret_access_key', 'admin', 'AWS Access Key') # NOTE(sirp): my_ip interpolation doesn't work within nested structures +DEFINE_string('glance_host', _get_my_ip(), 'default glance host') +DEFINE_integer('glance_port', 9292, 'default glance port') DEFINE_list('glance_api_servers', - ['%s:9292' % _get_my_ip()], + ['%s:%d' % (FLAGS.glance_host, FLAGS.glance_port)], 'list of glance api servers available to nova (host:port)') DEFINE_integer('s3_port', 3333, 's3 port') DEFINE_string('s3_host', '$my_ip', 's3 host (for infrastructure)') diff --git a/nova/image/glance.py b/nova/image/glance.py index 5ee1d2b8a..e4d9edc93 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -42,6 +42,13 @@ FLAGS = flags.FLAGS GlanceClient = utils.import_class('glance.client.Client') +def _construct_glance_url(): + """Generate the default URL to glance.""" + # TODO(jk0): This will eventually need to take SSL into consideration + # when supported in glance. + return "http://%s:%d" % (FLAGS.glance_host, FLAGS.glance_port) + + def _parse_image_ref(image_href): """Parse an image href into composite parts. diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index 290c9a04a..9f866d790 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -22,11 +22,15 @@ import stubout from nova.tests.api.openstack import fakes from nova import context from nova import exception +from nova import flags from nova.image import glance from nova import test from nova.tests.glance import stubs as glance_stubs +FLAGS = flags.FLAGS + + class NullWriter(object): """Used to test ImageService.get which takes a writer object""" @@ -451,3 +455,10 @@ class TestGlanceImageService(test.TestCase): image_meta = self.service.get(self.context, image_id, writer) self.assertEqual(image_meta['created_at'], self.NOW_DATETIME) self.assertEqual(image_meta['updated_at'], self.NOW_DATETIME) + + def test_contruct_glance_url(self): + # TODO(jk0): This will eventually need to take SSL into consideration + # when supported in glance. + generated_url = glance._construct_glance_url() + actual_url = "http://%s:%d" % (FLAGS.glance_host, FLAGS.glance_port) + self.assertEqual(generated_url, actual_url) -- cgit From 13e346df0bc88279242ed1c56ad39b36a22c8a39 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 20 Sep 2011 13:56:15 -0500 Subject: Refactored alternate link generation. --- nova/api/openstack/views/images.py | 19 ++++++++++++++++++- nova/image/glance.py | 7 ------- nova/tests/api/openstack/test_images.py | 14 ++++++++++++++ nova/tests/image/test_glance.py | 11 ----------- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index 86e8d7f3a..c41123f5e 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -18,6 +18,10 @@ import os.path from nova.api.openstack import common +from nova import flags + + +FLAGS = flags.FLAGS class ViewBuilder(object): @@ -139,6 +143,7 @@ class ViewBuilderV11(ViewBuilder): image = ViewBuilder.build(self, image_obj, detail) href = self.generate_href(image_obj["id"]) bookmark = self.generate_bookmark(image_obj["id"]) + alternate = self.generate_alternate(image_obj["id"]) image["links"] = [ { @@ -149,6 +154,11 @@ class ViewBuilderV11(ViewBuilder): "rel": "bookmark", "href": bookmark, }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": alternate, + }, ] @@ -158,6 +168,13 @@ class ViewBuilderV11(ViewBuilder): return image def generate_bookmark(self, image_id): - """Create an url that refers to a specific flavor id.""" + """Create a URL that refers to a specific flavor id.""" return os.path.join(common.remove_version_from_href(self.base_url), self.project_id, "images", str(image_id)) + + def generate_alternate(self, image_id): + """Create an alternate link for a specific flavor id.""" + # TODO(jk0): This will eventually need to take SSL into consideration + # when supported in glance. + return "http://%s:%d/%s/images/%s" % (FLAGS.glance_host, + FLAGS.glance_port, self.project_id, str(image_id)) diff --git a/nova/image/glance.py b/nova/image/glance.py index e4d9edc93..5ee1d2b8a 100644 --- a/nova/image/glance.py +++ b/nova/image/glance.py @@ -42,13 +42,6 @@ FLAGS = flags.FLAGS GlanceClient = utils.import_class('glance.client.Client') -def _construct_glance_url(): - """Generate the default URL to glance.""" - # TODO(jk0): This will eventually need to take SSL into consideration - # when supported in glance. - return "http://%s:%d" % (FLAGS.glance_host, FLAGS.glance_port) - - def _parse_image_ref(image_href): """Parse an image href into composite parts. diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index e5fd4764a..7053db37d 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -30,13 +30,18 @@ import stubout import webob from nova import context +from nova import flags import nova.api.openstack from nova.api.openstack import images from nova.api.openstack import xmlutil +from nova.api.openstack.views import images as images_view from nova import test 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" @@ -963,6 +968,15 @@ class ImagesTest(test.TestCase): response = req.get_response(fakes.wsgi_app()) self.assertEqual(400, response.status_int) + def test_generate_alternate(self): + # TODO(jk0): This will eventually need to take SSL into consideration + # when supported in glance. + view = images_view.ViewBuilderV11(1) + generated_url = view.generate_alternate(1) + actual_url = "http://%s:%d//images/1" % (FLAGS.glance_host, + FLAGS.glance_port) + self.assertEqual(generated_url, actual_url) + class ImageXMLSerializationTest(test.TestCase): diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py index 9f866d790..290c9a04a 100644 --- a/nova/tests/image/test_glance.py +++ b/nova/tests/image/test_glance.py @@ -22,15 +22,11 @@ import stubout from nova.tests.api.openstack import fakes from nova import context from nova import exception -from nova import flags from nova.image import glance from nova import test from nova.tests.glance import stubs as glance_stubs -FLAGS = flags.FLAGS - - class NullWriter(object): """Used to test ImageService.get which takes a writer object""" @@ -455,10 +451,3 @@ class TestGlanceImageService(test.TestCase): image_meta = self.service.get(self.context, image_id, writer) self.assertEqual(image_meta['created_at'], self.NOW_DATETIME) self.assertEqual(image_meta['updated_at'], self.NOW_DATETIME) - - def test_contruct_glance_url(self): - # TODO(jk0): This will eventually need to take SSL into consideration - # when supported in glance. - generated_url = glance._construct_glance_url() - actual_url = "http://%s:%d" % (FLAGS.glance_host, FLAGS.glance_port) - self.assertEqual(generated_url, actual_url) -- cgit From c07b24cdd6606950b0a4fef730c277b499eb65f4 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 20 Sep 2011 15:21:06 -0500 Subject: Fixed unit tests with some minor refactoring. --- nova/api/openstack/views/images.py | 13 ++-- nova/tests/api/openstack/test_images.py | 102 ++++++++++++++++++++++++++++++-- nova/utils.py | 7 +++ 3 files changed, 108 insertions(+), 14 deletions(-) diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/views/images.py index c41123f5e..659bfd463 100644 --- a/nova/api/openstack/views/images.py +++ b/nova/api/openstack/views/images.py @@ -18,10 +18,7 @@ import os.path from nova.api.openstack import common -from nova import flags - - -FLAGS = flags.FLAGS +from nova import utils class ViewBuilder(object): @@ -174,7 +171,7 @@ class ViewBuilderV11(ViewBuilder): def generate_alternate(self, image_id): """Create an alternate link for a specific flavor id.""" - # TODO(jk0): This will eventually need to take SSL into consideration - # when supported in glance. - return "http://%s:%d/%s/images/%s" % (FLAGS.glance_host, - FLAGS.glance_port, self.project_id, str(image_id)) + glance_url = utils.generate_glance_url() + + return "%s/%s/images/%s" % (glance_url, self.project_id, + str(image_id)) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 7053db37d..c0a246a91 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -30,18 +30,15 @@ import stubout import webob from nova import context -from nova import flags import nova.api.openstack from nova.api.openstack import images from nova.api.openstack import xmlutil from nova.api.openstack.views import images as images_view 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}" NOW_API_FORMAT = "2010-10-11T10:30:22Z" @@ -124,6 +121,7 @@ class ImagesTest(test.TestCase): href = "http://localhost/v1.1/fake/images/124" bookmark = "http://localhost/fake/images/124" + alternate = "%s/fake/images/124" % utils.generate_glance_url() server_href = "http://localhost/v1.1/servers/42" server_bookmark = "http://localhost/servers/42" @@ -157,6 +155,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": bookmark, + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": alternate }], }, } @@ -294,6 +297,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/123", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/123" % + utils.generate_glance_url() + }, ], }, { @@ -308,6 +317,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/124", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/124" % + utils.generate_glance_url() + }, ], }, { @@ -322,6 +337,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/125", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/125" % + utils.generate_glance_url() + }, ], }, { @@ -336,6 +357,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/126", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/126" % + utils.generate_glance_url() + }, ], }, { @@ -350,6 +377,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/127", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/127" % + utils.generate_glance_url() + }, ], }, { @@ -364,6 +397,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/128", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/128" % + utils.generate_glance_url() + }, ], }, { @@ -378,6 +417,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/129", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/129" % + utils.generate_glance_url() + }, ], }, { @@ -392,6 +437,12 @@ class ImagesTest(test.TestCase): "rel": "bookmark", "href": "http://localhost/fake/images/130", }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/130" % + utils.generate_glance_url() + }, ], }, ] @@ -498,6 +549,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/123", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/123" % utils.generate_glance_url() }], }, { @@ -529,6 +585,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/124", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/124" % utils.generate_glance_url() }], }, { @@ -560,6 +621,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/125", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/125" % utils.generate_glance_url() }], }, { @@ -591,6 +657,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/126", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/126" % utils.generate_glance_url() }], }, { @@ -622,6 +693,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/127", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/127" % utils.generate_glance_url() }], }, { @@ -653,6 +729,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/128", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/128" % utils.generate_glance_url() }], }, { @@ -684,6 +765,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/129", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/129" % utils.generate_glance_url() }], }, { @@ -701,6 +787,11 @@ class ImagesTest(test.TestCase): { "rel": "bookmark", "href": "http://localhost/fake/images/130", + }, + { + "rel": "alternate", + "type": "application/vnd.openstack.image", + "href": "%s/fake/images/130" % utils.generate_glance_url() }], }, ] @@ -973,8 +1064,7 @@ class ImagesTest(test.TestCase): # when supported in glance. view = images_view.ViewBuilderV11(1) generated_url = view.generate_alternate(1) - actual_url = "http://%s:%d//images/1" % (FLAGS.glance_host, - FLAGS.glance_port) + actual_url = "%s//images/1" % utils.generate_glance_url() self.assertEqual(generated_url, actual_url) diff --git a/nova/utils.py b/nova/utils.py index 81157a4cd..57c93d9d0 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -910,3 +910,10 @@ def convert_to_list_dict(lst, label): if not isinstance(lst, list): lst = [lst] return [{label: x} for x in lst] + + +def generate_glance_url(): + """Generate the URL to glance.""" + # TODO(jk0): This will eventually need to take SSL into consideration + # when supported in glance. + return "http://%s:%d" % (FLAGS.glance_host, FLAGS.glance_port) -- cgit From 525ad7c6b033a7da2fe023d42745696c9bae1e74 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 20 Sep 2011 15:35:23 -0500 Subject: Added another unit test. --- nova/tests/test_utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py index 1ba794a1a..19a15332d 100644 --- a/nova/tests/test_utils.py +++ b/nova/tests/test_utils.py @@ -20,10 +20,14 @@ import tempfile import nova from nova import exception +from nova import flags from nova import test from nova import utils +FLAGS = flags.FLAGS + + class ExecuteTestCase(test.TestCase): def test_retry_on_failure(self): fd, tmpfilename = tempfile.mkstemp() @@ -291,6 +295,11 @@ class GenericUtilsTestCase(test.TestCase): self.assertFalse(utils.bool_from_str(None)) self.assertFalse(utils.bool_from_str('junk')) + def test_generate_glance_url(self): + generated_url = utils.generate_glance_url() + actual_url = "http://%s:%d" % (FLAGS.glance_host, FLAGS.glance_port) + self.assertEqual(generated_url, actual_url) + class IsUUIDLikeTestCase(test.TestCase): def assertUUIDLike(self, val, expected): -- cgit From a1256381c107fd0cf91bd11a319c38918778079b Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 20 Sep 2011 15:38:44 -0500 Subject: Minor cleanup. --- nova/tests/api/openstack/test_images.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index c0a246a91..886efb6ac 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -1060,8 +1060,6 @@ class ImagesTest(test.TestCase): self.assertEqual(400, response.status_int) def test_generate_alternate(self): - # TODO(jk0): This will eventually need to take SSL into consideration - # when supported in glance. view = images_view.ViewBuilderV11(1) generated_url = view.generate_alternate(1) actual_url = "%s//images/1" % utils.generate_glance_url() -- cgit From 10589faa5fbde09689641d5e64ddd41a341eaade Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 20 Sep 2011 16:11:49 -0500 Subject: Include 'type' in XML output. --- nova/api/openstack/images.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 4340cbe3e..d579ae716 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -251,6 +251,8 @@ class ImageXMLSerializer(wsgi.XMLDictSerializer): elem = etree.SubElement(image_elem, '{%s}link' % xmlutil.XMLNS_ATOM) elem.set('rel', link['rel']) + if 'type' in link: + elem.set('type', link['type']) elem.set('href', link['href']) return image_elem -- cgit