Merge lp:~bcwaldon/nova/osapi-servers-links into lp:~hudson-openstack/nova/trunk

Proposed by Brian Waldon
Status: Superseded
Proposed branch: lp:~bcwaldon/nova/osapi-servers-links
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 223 lines (+116/-15)
3 files modified
nova/api/openstack/servers.py (+7/-3)
nova/api/openstack/views/servers.py (+53/-10)
nova/tests/api/openstack/test_servers.py (+56/-2)
To merge this branch: bzr merge lp:~bcwaldon/nova/osapi-servers-links
Reviewer Review Type Date Requested Status
Paul Voccio (community) Approve
Thierry Carrez (community) ffe Approve
Matt Dietz (community) Approve
Titan Pending
Review via email: mp+54264@code.launchpad.net

This proposal supersedes a proposal from 2011-03-18.

This proposal has been superseded by a proposal from 2011-03-25.

Commit message

Adding links container to openstack api v1.1 servers entities.

Description of the change

Adding links container to openstack api v1.1 servers entities. Resubmitted without prerequisite.

To post a comment you must log in.
Revision history for this message
Matt Dietz (cerberus) wrote :

You've got some conflicts you need to look at

review: Needs Fixing
Revision history for this message
Brian Waldon (bcwaldon) wrote :

> You've got some conflicts you need to look at

Resolved. The branch got a little stale while I was looking at other things.

Revision history for this message
Matt Dietz (cerberus) wrote :

115 +import re
116 +from nova import exception
117 +from webob import exc

Pep8 says modules should be ordered as such:

1. standard library imports
2. related third party imports
3. local application/library specific imports

So it should be re, webob and finally nova. Most people seem to be leaving a line of whitespace between each "tier" of module import

519 + if inst.get('instance_type') != None:

A little nit-picky, but you don't need to be this explicit. If inst.get(...): would be sufficient

540 + flavor_id = inst.get("instance_type", None)

Get already by default returns None

For the *_id cases near the above, you probably want to leave them the way they are since 0 obviously equates to false.

review: Needs Fixing
Revision history for this message
Brian Waldon (bcwaldon) wrote :

I decided to not do any value testing at all, and simply use whatever value was there.

I should also point out that this branch has a prerequisite branch (~rackspace-titan/nova/openstack-api-versioned-controllers) that hasn't landed yet. I prematurely removed it from this merge prop. It's a hassle to deal with prereqs and merge props, so I'm not going to resubmit it another two times. We can just wait to merge it.

Revision history for this message
Matt Dietz (cerberus) wrote :

lgtm.

review: Approve
Revision history for this message
Thierry Carrez (ttx) wrote :

This is really close to getting merged and is reasonable, FFe granted for late merging before EOD Monday

review: Approve (ffe)
Revision history for this message
Paul Voccio (pvo) wrote :

lgtm.

review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/api/openstack/servers.py'
--- nova/api/openstack/servers.py 2011-03-25 12:51:35 +0000
+++ nova/api/openstack/servers.py 2011-03-25 15:12:57 +0000
@@ -48,11 +48,15 @@
48 """ The Server API controller for the OpenStack API """48 """ The Server API controller for the OpenStack API """
4949
50 _serialization_metadata = {50 _serialization_metadata = {
51 'application/xml': {51 "application/xml": {
52 "attributes": {52 "attributes": {
53 "server": ["id", "imageId", "name", "flavorId", "hostId",53 "server": ["id", "imageId", "name", "flavorId", "hostId",
54 "status", "progress", "adminPass", "flavorRef",54 "status", "progress", "adminPass", "flavorRef",
55 "imageRef"]}}}55 "imageRef"],
56 "link": ["rel", "type", "href"],
57 },
58 },
59 }
5660
57 def __init__(self):61 def __init__(self):
58 self.compute_api = compute.API()62 self.compute_api = compute.API()
@@ -572,7 +576,7 @@
572 base_url)576 base_url)
573 addresses_builder = nova.api.openstack.views.addresses.ViewBuilderV11()577 addresses_builder = nova.api.openstack.views.addresses.ViewBuilderV11()
574 return nova.api.openstack.views.servers.ViewBuilderV11(578 return nova.api.openstack.views.servers.ViewBuilderV11(
575 addresses_builder, flavor_builder, image_builder)579 addresses_builder, flavor_builder, image_builder, base_url)
576580
577 def _get_addresses_view_builder(self, req):581 def _get_addresses_view_builder(self, req):
578 return nova.api.openstack.views.addresses.ViewBuilderV11(req)582 return nova.api.openstack.views.addresses.ViewBuilderV11(req)
579583
=== modified file 'nova/api/openstack/views/servers.py'
--- nova/api/openstack/views/servers.py 2011-03-24 05:08:17 +0000
+++ nova/api/openstack/views/servers.py 2011-03-25 15:12:57 +0000
@@ -16,6 +16,7 @@
16# under the License.16# under the License.
1717
18import hashlib18import hashlib
19import os
1920
20from nova.compute import power_state21from nova.compute import power_state
21import nova.compute22import nova.compute
@@ -41,9 +42,13 @@
41 def build(self, inst, is_detail):42 def build(self, inst, is_detail):
42 """Return a dict that represenst a server."""43 """Return a dict that represenst a server."""
43 if is_detail:44 if is_detail:
44 return self._build_detail(inst)45 server = self._build_detail(inst)
45 else:46 else:
46 return self._build_simple(inst)47 server = self._build_simple(inst)
48
49 self._build_extra(server, inst)
50
51 return server
4752
48 def _build_simple(self, inst):53 def _build_simple(self, inst):
49 """Return a simple model of a server."""54 """Return a simple model of a server."""
@@ -97,29 +102,67 @@
97 """Return the flavor sub-resource of a server."""102 """Return the flavor sub-resource of a server."""
98 raise NotImplementedError()103 raise NotImplementedError()
99104
105 def _build_extra(self, response, inst):
106 pass
107
100108
101class ViewBuilderV10(ViewBuilder):109class ViewBuilderV10(ViewBuilder):
102 """Model an Openstack API V1.0 server response."""110 """Model an Openstack API V1.0 server response."""
103111
104 def _build_image(self, response, inst):112 def _build_image(self, response, inst):
105 response['imageId'] = inst['image_id']113 if 'image_id' in dict(inst):
114 response['imageId'] = inst['image_id']
106115
107 def _build_flavor(self, response, inst):116 def _build_flavor(self, response, inst):
108 response['flavorId'] = inst['instance_type']117 if 'instance_type' in dict(inst):
118 response['flavorId'] = inst['instance_type']
109119
110120
111class ViewBuilderV11(ViewBuilder):121class ViewBuilderV11(ViewBuilder):
112 """Model an Openstack API V1.0 server response."""122 """Model an Openstack API V1.0 server response."""
113123 def __init__(self, addresses_builder, flavor_builder, image_builder,
114 def __init__(self, addresses_builder, flavor_builder, image_builder):124 base_url):
115 ViewBuilder.__init__(self, addresses_builder)125 ViewBuilder.__init__(self, addresses_builder)
116 self.flavor_builder = flavor_builder126 self.flavor_builder = flavor_builder
117 self.image_builder = image_builder127 self.image_builder = image_builder
128 self.base_url = base_url
118129
119 def _build_image(self, response, inst):130 def _build_image(self, response, inst):
120 image_id = inst["image_id"]131 if "image_id" in dict(inst):
121 response["imageRef"] = self.image_builder.generate_href(image_id)132 image_id = inst.get("image_id")
133 response["imageRef"] = self.image_builder.generate_href(image_id)
122134
123 def _build_flavor(self, response, inst):135 def _build_flavor(self, response, inst):
124 flavor_id = inst["instance_type"]136 if "instance_type" in dict(inst):
125 response["flavorRef"] = self.flavor_builder.generate_href(flavor_id)137 flavor_id = inst["instance_type"]
138 flavor_ref = self.flavor_builder.generate_href(flavor_id)
139 response["flavorRef"] = flavor_ref
140
141 def _build_extra(self, response, inst):
142 self._build_links(response, inst)
143
144 def _build_links(self, response, inst):
145 href = self.generate_href(inst["id"])
146
147 links = [
148 {
149 "rel": "self",
150 "href": href,
151 },
152 {
153 "rel": "bookmark",
154 "type": "application/json",
155 "href": href,
156 },
157 {
158 "rel": "bookmark",
159 "type": "application/xml",
160 "href": href,
161 },
162 ]
163
164 response["server"]["links"] = links
165
166 def generate_href(self, server_id):
167 """Create an url that refers to a specific server id."""
168 return os.path.join(self.base_url, "servers", str(server_id))
126169
=== modified file 'nova/tests/api/openstack/test_servers.py'
--- nova/tests/api/openstack/test_servers.py 2011-03-25 12:51:35 +0000
+++ nova/tests/api/openstack/test_servers.py 2011-03-25 15:12:57 +0000
@@ -164,6 +164,33 @@
164 self.assertEqual(res_dict['server']['id'], 1)164 self.assertEqual(res_dict['server']['id'], 1)
165 self.assertEqual(res_dict['server']['name'], 'server1')165 self.assertEqual(res_dict['server']['name'], 'server1')
166166
167 def test_get_server_by_id_v11(self):
168 req = webob.Request.blank('/v1.1/servers/1')
169 res = req.get_response(fakes.wsgi_app())
170 res_dict = json.loads(res.body)
171 self.assertEqual(res_dict['server']['id'], 1)
172 self.assertEqual(res_dict['server']['name'], 'server1')
173
174 expected_links = [
175 {
176 "rel": "self",
177 "href": "http://localhost/v1.1/servers/1",
178 },
179 {
180 "rel": "bookmark",
181 "type": "application/json",
182 "href": "http://localhost/v1.1/servers/1",
183 },
184 {
185 "rel": "bookmark",
186 "type": "application/xml",
187 "href": "http://localhost/v1.1/servers/1",
188 },
189 ]
190
191 print res_dict['server']
192 self.assertEqual(res_dict['server']['links'], expected_links)
193
167 def test_get_server_by_id_with_addresses(self):194 def test_get_server_by_id_with_addresses(self):
168 private = "192.168.0.3"195 private = "192.168.0.3"
169 public = ["1.2.3.4"]196 public = ["1.2.3.4"]
@@ -186,7 +213,6 @@
186 new_return_server = return_server_with_addresses(private, public)213 new_return_server = return_server_with_addresses(private, public)
187 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)214 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
188 req = webob.Request.blank('/v1.1/servers/1')215 req = webob.Request.blank('/v1.1/servers/1')
189 req.environ['api.version'] = '1.1'
190 res = req.get_response(fakes.wsgi_app())216 res = req.get_response(fakes.wsgi_app())
191 res_dict = json.loads(res.body)217 res_dict = json.loads(res.body)
192 self.assertEqual(res_dict['server']['id'], 1)218 self.assertEqual(res_dict['server']['id'], 1)
@@ -211,6 +237,35 @@
211 self.assertEqual(s.get('imageId', None), None)237 self.assertEqual(s.get('imageId', None), None)
212 i += 1238 i += 1
213239
240 def test_get_server_list_v11(self):
241 req = webob.Request.blank('/v1.1/servers')
242 res = req.get_response(fakes.wsgi_app())
243 res_dict = json.loads(res.body)
244
245 for i, s in enumerate(res_dict['servers']):
246 self.assertEqual(s['id'], i)
247 self.assertEqual(s['name'], 'server%d' % i)
248 self.assertEqual(s.get('imageId', None), None)
249
250 expected_links = [
251 {
252 "rel": "self",
253 "href": "http://localhost/v1.1/servers/%d" % (i,),
254 },
255 {
256 "rel": "bookmark",
257 "type": "application/json",
258 "href": "http://localhost/v1.1/servers/%d" % (i,),
259 },
260 {
261 "rel": "bookmark",
262 "type": "application/xml",
263 "href": "http://localhost/v1.1/servers/%d" % (i,),
264 },
265 ]
266
267 self.assertEqual(s['links'], expected_links)
268
214 def test_get_servers_with_limit(self):269 def test_get_servers_with_limit(self):
215 req = webob.Request.blank('/v1.0/servers?limit=3')270 req = webob.Request.blank('/v1.0/servers?limit=3')
216 res = req.get_response(fakes.wsgi_app())271 res = req.get_response(fakes.wsgi_app())
@@ -458,7 +513,6 @@
458513
459 def test_get_all_server_details_v1_1(self):514 def test_get_all_server_details_v1_1(self):
460 req = webob.Request.blank('/v1.1/servers/detail')515 req = webob.Request.blank('/v1.1/servers/detail')
461 req.environ['api.version'] = '1.1'
462 res = req.get_response(fakes.wsgi_app())516 res = req.get_response(fakes.wsgi_app())
463 res_dict = json.loads(res.body)517 res_dict = json.loads(res.body)
464518