Merge lp:~rackspace-titan/nova/osapi_fault_wrap_webob_exc into lp:~hudson-openstack/nova/trunk
- osapi_fault_wrap_webob_exc
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Brian Waldon | ||||||||
Approved revision: | 1295 | ||||||||
Merged at revision: | 1301 | ||||||||
Proposed branch: | lp:~rackspace-titan/nova/osapi_fault_wrap_webob_exc | ||||||||
Merge into: | lp:~hudson-openstack/nova/trunk | ||||||||
Diff against target: |
763 lines (+90/-102) 15 files modified
nova/api/openstack/accounts.py (+3/-3) nova/api/openstack/backup_schedules.py (+4/-5) nova/api/openstack/common.py (+12/-7) nova/api/openstack/consoles.py (+3/-4) nova/api/openstack/create_instance_helper.py (+3/-4) nova/api/openstack/image_metadata.py (+2/-3) nova/api/openstack/images.py (+1/-2) nova/api/openstack/ips.py (+5/-6) nova/api/openstack/server_metadata.py (+0/-1) nova/api/openstack/servers.py (+42/-50) nova/api/openstack/shared_ip_groups.py (+6/-7) nova/api/openstack/users.py (+1/-2) nova/api/openstack/wsgi.py (+5/-1) nova/api/openstack/zones.py (+2/-6) nova/tests/api/openstack/test_servers.py (+1/-1) |
||||||||
To merge this branch: | bzr merge lp:~rackspace-titan/nova/osapi_fault_wrap_webob_exc | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brian Waldon (community) | Approve | ||
Devin Carlen (community) | Approve | ||
Alex Meade (community) | Approve | ||
Review via email: mp+68698@code.launchpad.net |
Commit message
Description of the change
Perform fault wrapping in the openstack WSGI controller. This allows us to just raise webob Exceptions in OS API controllers with the appropriate explanations set. This resolves some inconsistencies with exception raising and returning that would cause HTML output to occur when faults weren't being handled correctly.
Dan Prince (dan-prince) wrote : | # |
Alex Meade (alex-meade) wrote : | # |
This is some great OSAPI cleanup, assuming you test it well, I approve
Devin Carlen (devcamcar) wrote : | # |
lgtm, nice cleanup.
Brian Waldon (bcwaldon) wrote : | # |
Great work, Dan. Two things:
1) One pep8 violation:
nova/api/
msg = _('offset param must be an integer')
2) Since you'll already be in common.py, can you fix the i18n on line 112 (on the MP)? The '% marker' should be outside of the _()
- 1294. By Dan Prince
-
Merge w/ trunk.
- 1295. By Dan Prince
-
pep8 and stuff.
Dan Prince (dan-prince) wrote : | # |
> Great work, Dan. Two things:
>
> 1) One pep8 violation:
>
> nova/api/
> msg = _('offset param must be an integer')
>
>
> 2) Since you'll already be in common.py, can you fix the i18n on line 112 (on
> the MP)? The '% marker' should be outside of the _()
Fixed. Should be all set.
Brian Waldon (bcwaldon) wrote : | # |
Thank you, Dan Prince.
Preview Diff
1 | === modified file 'nova/api/openstack/accounts.py' |
2 | --- nova/api/openstack/accounts.py 2011-07-06 20:28:10 +0000 |
3 | +++ nova/api/openstack/accounts.py 2011-07-21 18:52:39 +0000 |
4 | @@ -47,10 +47,10 @@ |
5 | raise exception.AdminRequired() |
6 | |
7 | def index(self, req): |
8 | - raise faults.Fault(webob.exc.HTTPNotImplemented()) |
9 | + raise webob.exc.HTTPNotImplemented() |
10 | |
11 | def detail(self, req): |
12 | - raise faults.Fault(webob.exc.HTTPNotImplemented()) |
13 | + raise webob.exc.HTTPNotImplemented() |
14 | |
15 | def show(self, req, id): |
16 | """Return data about the given account id""" |
17 | @@ -65,7 +65,7 @@ |
18 | def create(self, req, body): |
19 | """We use update with create-or-update semantics |
20 | because the id comes from an external source""" |
21 | - raise faults.Fault(webob.exc.HTTPNotImplemented()) |
22 | + raise webob.exc.HTTPNotImplemented() |
23 | |
24 | def update(self, req, id, body): |
25 | """This is really create or update.""" |
26 | |
27 | === modified file 'nova/api/openstack/backup_schedules.py' |
28 | --- nova/api/openstack/backup_schedules.py 2011-07-06 20:28:10 +0000 |
29 | +++ nova/api/openstack/backup_schedules.py 2011-07-21 18:52:39 +0000 |
30 | @@ -19,7 +19,6 @@ |
31 | |
32 | from webob import exc |
33 | |
34 | -from nova.api.openstack import faults |
35 | from nova.api.openstack import wsgi |
36 | |
37 | |
38 | @@ -36,20 +35,20 @@ |
39 | |
40 | def index(self, req, server_id, **kwargs): |
41 | """ Returns the list of backup schedules for a given instance """ |
42 | - return faults.Fault(exc.HTTPNotImplemented()) |
43 | + raise exc.HTTPNotImplemented() |
44 | |
45 | def show(self, req, server_id, id, **kwargs): |
46 | """ Returns a single backup schedule for a given instance """ |
47 | - return faults.Fault(exc.HTTPNotImplemented()) |
48 | + raise exc.HTTPNotImplemented() |
49 | |
50 | def create(self, req, server_id, **kwargs): |
51 | """ No actual update method required, since the existing API allows |
52 | both create and update through a POST """ |
53 | - return faults.Fault(exc.HTTPNotImplemented()) |
54 | + raise exc.HTTPNotImplemented() |
55 | |
56 | def delete(self, req, server_id, id, **kwargs): |
57 | """ Deletes an existing backup schedule """ |
58 | - return faults.Fault(exc.HTTPNotImplemented()) |
59 | + raise exc.HTTPNotImplemented() |
60 | |
61 | |
62 | def create_resource(): |
63 | |
64 | === modified file 'nova/api/openstack/common.py' |
65 | --- nova/api/openstack/common.py 2011-07-15 03:09:28 +0000 |
66 | +++ nova/api/openstack/common.py 2011-07-21 18:52:39 +0000 |
67 | @@ -53,10 +53,10 @@ |
68 | params[param] = int(request.GET[param]) |
69 | except ValueError: |
70 | msg = _('%s param must be an integer') % param |
71 | - raise webob.exc.HTTPBadRequest(msg) |
72 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
73 | if params[param] < 0: |
74 | msg = _('%s param must be positive') % param |
75 | - raise webob.exc.HTTPBadRequest(msg) |
76 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
77 | |
78 | return params |
79 | |
80 | @@ -77,18 +77,22 @@ |
81 | try: |
82 | offset = int(request.GET.get('offset', 0)) |
83 | except ValueError: |
84 | - raise webob.exc.HTTPBadRequest(_('offset param must be an integer')) |
85 | + msg = _('offset param must be an integer') |
86 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
87 | |
88 | try: |
89 | limit = int(request.GET.get('limit', max_limit)) |
90 | except ValueError: |
91 | - raise webob.exc.HTTPBadRequest(_('limit param must be an integer')) |
92 | + msg = _('limit param must be an integer') |
93 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
94 | |
95 | if limit < 0: |
96 | - raise webob.exc.HTTPBadRequest(_('limit param must be positive')) |
97 | + msg = _('limit param must be positive') |
98 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
99 | |
100 | if offset < 0: |
101 | - raise webob.exc.HTTPBadRequest(_('offset param must be positive')) |
102 | + msg = _('offset param must be positive') |
103 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
104 | |
105 | limit = min(max_limit, limit or max_limit) |
106 | range_end = offset + limit |
107 | @@ -111,7 +115,8 @@ |
108 | start_index = i + 1 |
109 | break |
110 | if start_index < 0: |
111 | - raise webob.exc.HTTPBadRequest(_('marker [%s] not found' % marker)) |
112 | + msg = _('marker [%s] not found') % marker |
113 | + raise webob.exc.HTTPBadRequest(explanation=msg) |
114 | range_end = start_index + limit |
115 | return items[start_index:range_end] |
116 | |
117 | |
118 | === modified file 'nova/api/openstack/consoles.py' |
119 | --- nova/api/openstack/consoles.py 2011-07-20 17:52:22 +0000 |
120 | +++ nova/api/openstack/consoles.py 2011-07-21 18:52:39 +0000 |
121 | @@ -20,7 +20,6 @@ |
122 | |
123 | from nova import console |
124 | from nova import exception |
125 | -from nova.api.openstack import faults |
126 | from nova.api.openstack import wsgi |
127 | |
128 | |
129 | @@ -72,12 +71,12 @@ |
130 | int(server_id), |
131 | int(id)) |
132 | except exception.NotFound: |
133 | - return faults.Fault(exc.HTTPNotFound()) |
134 | + raise exc.HTTPNotFound() |
135 | return _translate_detail_keys(console) |
136 | |
137 | def update(self, req, server_id, id): |
138 | """You can't update a console""" |
139 | - raise faults.Fault(exc.HTTPNotImplemented()) |
140 | + raise exc.HTTPNotImplemented() |
141 | |
142 | def delete(self, req, server_id, id): |
143 | """Deletes a console""" |
144 | @@ -86,7 +85,7 @@ |
145 | int(server_id), |
146 | int(id)) |
147 | except exception.NotFound: |
148 | - return faults.Fault(exc.HTTPNotFound()) |
149 | + raise exc.HTTPNotFound() |
150 | return webob.Response(status_int=202) |
151 | |
152 | |
153 | |
154 | === modified file 'nova/api/openstack/create_instance_helper.py' |
155 | --- nova/api/openstack/create_instance_helper.py 2011-07-06 20:28:10 +0000 |
156 | +++ nova/api/openstack/create_instance_helper.py 2011-07-21 18:52:39 +0000 |
157 | @@ -28,7 +28,6 @@ |
158 | from nova import utils |
159 | |
160 | from nova.compute import instance_types |
161 | -from nova.api.openstack import faults |
162 | from nova.api.openstack import wsgi |
163 | from nova.auth import manager as auth_manager |
164 | |
165 | @@ -70,7 +69,7 @@ |
166 | return type from this method is left to the caller. |
167 | """ |
168 | if not body: |
169 | - raise faults.Fault(exc.HTTPUnprocessableEntity()) |
170 | + raise exc.HTTPUnprocessableEntity() |
171 | |
172 | context = req.environ['nova.context'] |
173 | |
174 | @@ -94,7 +93,7 @@ |
175 | except Exception, e: |
176 | msg = _("Cannot find requested image %(image_href)s: %(e)s" % |
177 | locals()) |
178 | - raise faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
179 | + raise exc.HTTPBadRequest(explanation=msg) |
180 | |
181 | personality = body['server'].get('personality') |
182 | |
183 | @@ -153,7 +152,7 @@ |
184 | self._handle_quota_error(error) |
185 | except exception.ImageNotFound as error: |
186 | msg = _("Can not find requested image") |
187 | - raise faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
188 | + raise exc.HTTPBadRequest(explanation=msg) |
189 | |
190 | # Let the caller deal with unhandled exceptions. |
191 | |
192 | |
193 | === modified file 'nova/api/openstack/image_metadata.py' |
194 | --- nova/api/openstack/image_metadata.py 2011-07-06 20:28:10 +0000 |
195 | +++ nova/api/openstack/image_metadata.py 2011-07-21 18:52:39 +0000 |
196 | @@ -22,7 +22,6 @@ |
197 | from nova import image |
198 | from nova import quota |
199 | from nova import utils |
200 | -from nova.api.openstack import faults |
201 | from nova.api.openstack import wsgi |
202 | |
203 | |
204 | @@ -62,7 +61,7 @@ |
205 | if id in metadata: |
206 | return {'meta': {id: metadata[id]}} |
207 | else: |
208 | - return faults.Fault(exc.HTTPNotFound()) |
209 | + raise exc.HTTPNotFound() |
210 | |
211 | def create(self, req, image_id, body): |
212 | context = req.environ['nova.context'] |
213 | @@ -105,7 +104,7 @@ |
214 | img = self.image_service.show(context, image_id) |
215 | metadata = self._get_metadata(context, image_id) |
216 | if not id in metadata: |
217 | - return faults.Fault(exc.HTTPNotFound()) |
218 | + raise exc.HTTPNotFound() |
219 | metadata.pop(id) |
220 | img['properties'] = metadata |
221 | self.image_service.update(context, image_id, img, None) |
222 | |
223 | === modified file 'nova/api/openstack/images.py' |
224 | --- nova/api/openstack/images.py 2011-07-14 13:29:27 +0000 |
225 | +++ nova/api/openstack/images.py 2011-07-21 18:52:39 +0000 |
226 | @@ -25,7 +25,6 @@ |
227 | import nova.image |
228 | from nova import log |
229 | from nova.api.openstack import common |
230 | -from nova.api.openstack import faults |
231 | from nova.api.openstack import image_metadata |
232 | from nova.api.openstack import servers |
233 | from nova.api.openstack.views import images as images_view |
234 | @@ -85,7 +84,7 @@ |
235 | image = self._image_service.show(context, id) |
236 | except (exception.NotFound, exception.InvalidImageRef): |
237 | explanation = _("Image not found.") |
238 | - raise faults.Fault(webob.exc.HTTPNotFound(explanation=explanation)) |
239 | + raise webob.exc.HTTPNotFound(explanation=explanation) |
240 | |
241 | return dict(image=self.get_builder(req).build(image, detail=True)) |
242 | |
243 | |
244 | === modified file 'nova/api/openstack/ips.py' |
245 | --- nova/api/openstack/ips.py 2011-07-14 17:25:05 +0000 |
246 | +++ nova/api/openstack/ips.py 2011-07-21 18:52:39 +0000 |
247 | @@ -20,7 +20,6 @@ |
248 | from webob import exc |
249 | |
250 | import nova |
251 | -from nova.api.openstack import faults |
252 | import nova.api.openstack.views.addresses |
253 | from nova.api.openstack import wsgi |
254 | from nova import db |
255 | @@ -37,14 +36,14 @@ |
256 | instance = self.compute_api.get( |
257 | req.environ['nova.context'], server_id) |
258 | except nova.exception.NotFound: |
259 | - return faults.Fault(exc.HTTPNotFound()) |
260 | + raise exc.HTTPNotFound() |
261 | return instance |
262 | |
263 | def create(self, req, server_id, body): |
264 | - return faults.Fault(exc.HTTPNotImplemented()) |
265 | + raise exc.HTTPNotImplemented() |
266 | |
267 | def delete(self, req, server_id, id): |
268 | - return faults.Fault(exc.HTTPNotImplemented()) |
269 | + raise exc.HTTPNotImplemented() |
270 | |
271 | |
272 | class ControllerV10(Controller): |
273 | @@ -63,7 +62,7 @@ |
274 | view = builder.build_public_parts(instance) |
275 | else: |
276 | msg = _("Only private and public networks available") |
277 | - return faults.Fault(exc.HTTPNotFound(explanation=msg)) |
278 | + raise exc.HTTPNotFound(explanation=msg) |
279 | |
280 | return {id: view} |
281 | |
282 | @@ -86,7 +85,7 @@ |
283 | |
284 | if network is None: |
285 | msg = _("Instance is not a member of specified network") |
286 | - return faults.Fault(exc.HTTPNotFound(explanation=msg)) |
287 | + raise exc.HTTPNotFound(explanation=msg) |
288 | |
289 | return network |
290 | |
291 | |
292 | === modified file 'nova/api/openstack/server_metadata.py' |
293 | --- nova/api/openstack/server_metadata.py 2011-07-06 20:28:10 +0000 |
294 | +++ nova/api/openstack/server_metadata.py 2011-07-21 18:52:39 +0000 |
295 | @@ -18,7 +18,6 @@ |
296 | from webob import exc |
297 | |
298 | from nova import compute |
299 | -from nova.api.openstack import faults |
300 | from nova.api.openstack import wsgi |
301 | from nova import exception |
302 | from nova import quota |
303 | |
304 | === modified file 'nova/api/openstack/servers.py' |
305 | --- nova/api/openstack/servers.py 2011-07-20 17:52:22 +0000 |
306 | +++ nova/api/openstack/servers.py 2011-07-21 18:52:39 +0000 |
307 | @@ -27,7 +27,6 @@ |
308 | from nova import utils |
309 | from nova.api.openstack import common |
310 | from nova.api.openstack import create_instance_helper as helper |
311 | -from nova.api.openstack import faults |
312 | import nova.api.openstack.views.addresses |
313 | import nova.api.openstack.views.flavors |
314 | import nova.api.openstack.views.images |
315 | @@ -102,17 +101,14 @@ |
316 | req.environ['nova.context'], id) |
317 | return self._build_view(req, instance, is_detail=True) |
318 | except exception.NotFound: |
319 | - return faults.Fault(exc.HTTPNotFound()) |
320 | + raise exc.HTTPNotFound() |
321 | |
322 | def create(self, req, body): |
323 | """ Creates a new server for a given user """ |
324 | extra_values = None |
325 | result = None |
326 | - try: |
327 | - extra_values, instances = self.helper.create_instance( |
328 | - req, body, self.compute_api.create) |
329 | - except faults.Fault, f: |
330 | - return f |
331 | + extra_values, instances = self.helper.create_instance( |
332 | + req, body, self.compute_api.create) |
333 | |
334 | # We can only return 1 instance via the API, if we happen to |
335 | # build more than one... instances is a list, so we'll just |
336 | @@ -132,7 +128,7 @@ |
337 | raise exc.HTTPUnprocessableEntity() |
338 | |
339 | if not body: |
340 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
341 | + raise exc.HTTPUnprocessableEntity() |
342 | |
343 | ctxt = req.environ['nova.context'] |
344 | update_dict = {} |
345 | @@ -147,7 +143,7 @@ |
346 | try: |
347 | self.compute_api.update(ctxt, id, **update_dict) |
348 | except exception.NotFound: |
349 | - return faults.Fault(exc.HTTPNotFound()) |
350 | + raise exc.HTTPNotFound() |
351 | |
352 | return exc.HTTPNoContent() |
353 | |
354 | @@ -171,7 +167,7 @@ |
355 | for key in actions.keys(): |
356 | if key in body: |
357 | return actions[key](body, req, id) |
358 | - return faults.Fault(exc.HTTPNotImplemented()) |
359 | + raise exc.HTTPNotImplemented() |
360 | |
361 | def _action_change_password(self, input_dict, req, id): |
362 | return exc.HTTPNotImplemented() |
363 | @@ -181,7 +177,7 @@ |
364 | self.compute_api.confirm_resize(req.environ['nova.context'], id) |
365 | except Exception, e: |
366 | LOG.exception(_("Error in confirm-resize %s"), e) |
367 | - return faults.Fault(exc.HTTPBadRequest()) |
368 | + raise exc.HTTPBadRequest() |
369 | return exc.HTTPNoContent() |
370 | |
371 | def _action_revert_resize(self, input_dict, req, id): |
372 | @@ -189,7 +185,7 @@ |
373 | self.compute_api.revert_resize(req.environ['nova.context'], id) |
374 | except Exception, e: |
375 | LOG.exception(_("Error in revert-resize %s"), e) |
376 | - return faults.Fault(exc.HTTPBadRequest()) |
377 | + raise exc.HTTPBadRequest() |
378 | return webob.Response(status_int=202) |
379 | |
380 | def _action_resize(self, input_dict, req, id): |
381 | @@ -200,14 +196,14 @@ |
382 | reboot_type = input_dict['reboot']['type'] |
383 | else: |
384 | LOG.exception(_("Missing argument 'type' for reboot")) |
385 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
386 | + raise exc.HTTPUnprocessableEntity() |
387 | try: |
388 | # TODO(gundlach): pass reboot_type, support soft reboot in |
389 | # virt driver |
390 | self.compute_api.reboot(req.environ['nova.context'], id) |
391 | except Exception, e: |
392 | LOG.exception(_("Error in reboot %s"), e) |
393 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
394 | + raise exc.HTTPUnprocessableEntity() |
395 | return webob.Response(status_int=202) |
396 | |
397 | def _action_migrate(self, input_dict, req, id): |
398 | @@ -215,7 +211,7 @@ |
399 | self.compute_api.resize(req.environ['nova.context'], id) |
400 | except Exception, e: |
401 | LOG.exception(_("Error in migrate %s"), e) |
402 | - return faults.Fault(exc.HTTPBadRequest()) |
403 | + raise exc.HTTPBadRequest() |
404 | return webob.Response(status_int=202) |
405 | |
406 | @scheduler_api.redirect_handler |
407 | @@ -231,7 +227,7 @@ |
408 | except: |
409 | readable = traceback.format_exc() |
410 | LOG.exception(_("Compute.api::lock %s"), readable) |
411 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
412 | + raise exc.HTTPUnprocessableEntity() |
413 | return webob.Response(status_int=202) |
414 | |
415 | @scheduler_api.redirect_handler |
416 | @@ -247,7 +243,7 @@ |
417 | except: |
418 | readable = traceback.format_exc() |
419 | LOG.exception(_("Compute.api::unlock %s"), readable) |
420 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
421 | + raise exc.HTTPUnprocessableEntity() |
422 | return webob.Response(status_int=202) |
423 | |
424 | @scheduler_api.redirect_handler |
425 | @@ -262,7 +258,7 @@ |
426 | except: |
427 | readable = traceback.format_exc() |
428 | LOG.exception(_("Compute.api::get_lock %s"), readable) |
429 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
430 | + raise exc.HTTPUnprocessableEntity() |
431 | return webob.Response(status_int=202) |
432 | |
433 | @scheduler_api.redirect_handler |
434 | @@ -277,7 +273,7 @@ |
435 | except: |
436 | readable = traceback.format_exc() |
437 | LOG.exception(_("Compute.api::reset_network %s"), readable) |
438 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
439 | + raise exc.HTTPUnprocessableEntity() |
440 | return webob.Response(status_int=202) |
441 | |
442 | @scheduler_api.redirect_handler |
443 | @@ -292,7 +288,7 @@ |
444 | except: |
445 | readable = traceback.format_exc() |
446 | LOG.exception(_("Compute.api::inject_network_info %s"), readable) |
447 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
448 | + raise exc.HTTPUnprocessableEntity() |
449 | return webob.Response(status_int=202) |
450 | |
451 | @scheduler_api.redirect_handler |
452 | @@ -304,7 +300,7 @@ |
453 | except: |
454 | readable = traceback.format_exc() |
455 | LOG.exception(_("Compute.api::pause %s"), readable) |
456 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
457 | + raise exc.HTTPUnprocessableEntity() |
458 | return webob.Response(status_int=202) |
459 | |
460 | @scheduler_api.redirect_handler |
461 | @@ -316,7 +312,7 @@ |
462 | except: |
463 | readable = traceback.format_exc() |
464 | LOG.exception(_("Compute.api::unpause %s"), readable) |
465 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
466 | + raise exc.HTTPUnprocessableEntity() |
467 | return webob.Response(status_int=202) |
468 | |
469 | @scheduler_api.redirect_handler |
470 | @@ -328,7 +324,7 @@ |
471 | except: |
472 | readable = traceback.format_exc() |
473 | LOG.exception(_("compute.api::suspend %s"), readable) |
474 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
475 | + raise exc.HTTPUnprocessableEntity() |
476 | return webob.Response(status_int=202) |
477 | |
478 | @scheduler_api.redirect_handler |
479 | @@ -340,7 +336,7 @@ |
480 | except: |
481 | readable = traceback.format_exc() |
482 | LOG.exception(_("compute.api::resume %s"), readable) |
483 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
484 | + raise exc.HTTPUnprocessableEntity() |
485 | return webob.Response(status_int=202) |
486 | |
487 | @scheduler_api.redirect_handler |
488 | @@ -352,7 +348,7 @@ |
489 | except: |
490 | readable = traceback.format_exc() |
491 | LOG.exception(_("compute.api::rescue %s"), readable) |
492 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
493 | + raise exc.HTTPUnprocessableEntity() |
494 | return webob.Response(status_int=202) |
495 | |
496 | @scheduler_api.redirect_handler |
497 | @@ -364,7 +360,7 @@ |
498 | except: |
499 | readable = traceback.format_exc() |
500 | LOG.exception(_("compute.api::unrescue %s"), readable) |
501 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
502 | + raise exc.HTTPUnprocessableEntity() |
503 | return webob.Response(status_int=202) |
504 | |
505 | @scheduler_api.redirect_handler |
506 | @@ -374,7 +370,7 @@ |
507 | self.compute_api.get_ajax_console(req.environ['nova.context'], |
508 | int(id)) |
509 | except exception.NotFound: |
510 | - return faults.Fault(exc.HTTPNotFound()) |
511 | + raise exc.HTTPNotFound() |
512 | return webob.Response(status_int=202) |
513 | |
514 | @scheduler_api.redirect_handler |
515 | @@ -384,7 +380,7 @@ |
516 | self.compute_api.get_vnc_console(req.environ['nova.context'], |
517 | int(id)) |
518 | except exception.NotFound: |
519 | - return faults.Fault(exc.HTTPNotFound()) |
520 | + raise exc.HTTPNotFound() |
521 | return webob.Response(status_int=202) |
522 | |
523 | @scheduler_api.redirect_handler |
524 | @@ -416,7 +412,7 @@ |
525 | try: |
526 | self.compute_api.delete(req.environ['nova.context'], id) |
527 | except exception.NotFound: |
528 | - return faults.Fault(exc.HTTPNotFound()) |
529 | + raise exc.HTTPNotFound() |
530 | return webob.Response(status_int=202) |
531 | |
532 | def _image_ref_from_req_data(self, data): |
533 | @@ -440,17 +436,13 @@ |
534 | |
535 | def _action_resize(self, input_dict, req, id): |
536 | """ Resizes a given instance to the flavor size requested """ |
537 | - try: |
538 | - if 'resize' in input_dict and 'flavorId' in input_dict['resize']: |
539 | - flavor_id = input_dict['resize']['flavorId'] |
540 | - self.compute_api.resize(req.environ['nova.context'], id, |
541 | - flavor_id) |
542 | - else: |
543 | - LOG.exception(_("Missing 'flavorId' argument for resize")) |
544 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
545 | - except Exception, e: |
546 | - LOG.exception(_("Error in resize %s"), e) |
547 | - return faults.Fault(exc.HTTPBadRequest()) |
548 | + if 'resize' in input_dict and 'flavorId' in input_dict['resize']: |
549 | + flavor_id = input_dict['resize']['flavorId'] |
550 | + self.compute_api.resize(req.environ['nova.context'], id, |
551 | + flavor_id) |
552 | + else: |
553 | + LOG.exception(_("Missing 'flavorId' argument for resize")) |
554 | + raise exc.HTTPUnprocessableEntity() |
555 | return webob.Response(status_int=202) |
556 | |
557 | def _action_rebuild(self, info, request, instance_id): |
558 | @@ -462,14 +454,14 @@ |
559 | except (KeyError, TypeError): |
560 | msg = _("Could not parse imageId from request.") |
561 | LOG.debug(msg) |
562 | - return faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
563 | + raise exc.HTTPBadRequest(explanation=msg) |
564 | |
565 | try: |
566 | self.compute_api.rebuild(context, instance_id, image_id) |
567 | except exception.BuildInProgress: |
568 | msg = _("Instance %d is currently being rebuilt.") % instance_id |
569 | LOG.debug(msg) |
570 | - return faults.Fault(exc.HTTPConflict(explanation=msg)) |
571 | + raise exc.HTTPConflict(explanation=msg) |
572 | |
573 | return webob.Response(status_int=202) |
574 | |
575 | @@ -486,7 +478,7 @@ |
576 | try: |
577 | self.compute_api.delete(req.environ['nova.context'], id) |
578 | except exception.NotFound: |
579 | - return faults.Fault(exc.HTTPNotFound()) |
580 | + raise exc.HTTPNotFound() |
581 | |
582 | def _image_ref_from_req_data(self, data): |
583 | return data['server']['imageRef'] |
584 | @@ -530,7 +522,7 @@ |
585 | except AttributeError as ex: |
586 | msg = _("Unable to parse metadata key/value pairs.") |
587 | LOG.debug(msg) |
588 | - raise faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
589 | + raise exc.HTTPBadRequest(explanation=msg) |
590 | |
591 | def _decode_personalities(self, personalities): |
592 | """Decode the Base64-encoded personalities.""" |
593 | @@ -541,14 +533,14 @@ |
594 | except (KeyError, TypeError): |
595 | msg = _("Unable to parse personality path/contents.") |
596 | LOG.info(msg) |
597 | - raise faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
598 | + raise exc.HTTPBadRequest(explanation=msg) |
599 | |
600 | try: |
601 | personality["contents"] = base64.b64decode(contents) |
602 | except TypeError: |
603 | msg = _("Personality content could not be Base64 decoded.") |
604 | LOG.info(msg) |
605 | - raise faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
606 | + raise exc.HTTPBadRequest(explanation=msg) |
607 | |
608 | def _action_resize(self, input_dict, req, id): |
609 | """ Resizes a given instance to the flavor size requested """ |
610 | @@ -560,10 +552,10 @@ |
611 | flavor_id) |
612 | else: |
613 | LOG.exception(_("Missing 'flavorRef' argument for resize")) |
614 | - return faults.Fault(exc.HTTPUnprocessableEntity()) |
615 | + raise exc.HTTPUnprocessableEntity() |
616 | except Exception, e: |
617 | LOG.exception(_("Error in resize %s"), e) |
618 | - return faults.Fault(exc.HTTPBadRequest()) |
619 | + raise exc.HTTPBadRequest() |
620 | return webob.Response(status_int=202) |
621 | |
622 | def _action_rebuild(self, info, request, instance_id): |
623 | @@ -575,7 +567,7 @@ |
624 | except (KeyError, TypeError): |
625 | msg = _("Could not parse imageRef from request.") |
626 | LOG.debug(msg) |
627 | - return faults.Fault(exc.HTTPBadRequest(explanation=msg)) |
628 | + raise exc.HTTPBadRequest(explanation=msg) |
629 | |
630 | personalities = info["rebuild"].get("personality", []) |
631 | metadata = info["rebuild"].get("metadata") |
632 | @@ -591,7 +583,7 @@ |
633 | except exception.BuildInProgress: |
634 | msg = _("Instance %d is currently being rebuilt.") % instance_id |
635 | LOG.debug(msg) |
636 | - return faults.Fault(exc.HTTPConflict(explanation=msg)) |
637 | + raise exc.HTTPConflict(explanation=msg) |
638 | |
639 | return webob.Response(status_int=202) |
640 | |
641 | |
642 | === modified file 'nova/api/openstack/shared_ip_groups.py' |
643 | --- nova/api/openstack/shared_ip_groups.py 2011-07-06 20:28:10 +0000 |
644 | +++ nova/api/openstack/shared_ip_groups.py 2011-07-21 18:52:39 +0000 |
645 | @@ -17,7 +17,6 @@ |
646 | |
647 | from webob import exc |
648 | |
649 | -from nova.api.openstack import faults |
650 | from nova.api.openstack import wsgi |
651 | |
652 | |
653 | @@ -26,27 +25,27 @@ |
654 | |
655 | def index(self, req, **kwargs): |
656 | """ Returns a list of Shared IP Groups for the user """ |
657 | - raise faults.Fault(exc.HTTPNotImplemented()) |
658 | + raise exc.HTTPNotImplemented() |
659 | |
660 | def show(self, req, id, **kwargs): |
661 | """ Shows in-depth information on a specific Shared IP Group """ |
662 | - raise faults.Fault(exc.HTTPNotImplemented()) |
663 | + raise exc.HTTPNotImplemented() |
664 | |
665 | def update(self, req, id, **kwargs): |
666 | """ You can't update a Shared IP Group """ |
667 | - raise faults.Fault(exc.HTTPNotImplemented()) |
668 | + raise exc.HTTPNotImplemented() |
669 | |
670 | def delete(self, req, id, **kwargs): |
671 | """ Deletes a Shared IP Group """ |
672 | - raise faults.Fault(exc.HTTPNotImplemented()) |
673 | + raise exc.HTTPNotImplemented() |
674 | |
675 | def detail(self, req, **kwargs): |
676 | """ Returns a complete list of Shared IP Groups """ |
677 | - raise faults.Fault(exc.HTTPNotImplemented()) |
678 | + raise exc.HTTPNotImplemented() |
679 | |
680 | def create(self, req, **kwargs): |
681 | """ Creates a new Shared IP group """ |
682 | - raise faults.Fault(exc.HTTPNotImplemented()) |
683 | + raise exc.HTTPNotImplemented() |
684 | |
685 | |
686 | def create_resource(): |
687 | |
688 | === modified file 'nova/api/openstack/users.py' |
689 | --- nova/api/openstack/users.py 2011-07-06 20:28:10 +0000 |
690 | +++ nova/api/openstack/users.py 2011-07-21 18:52:39 +0000 |
691 | @@ -19,7 +19,6 @@ |
692 | from nova import flags |
693 | from nova import log as logging |
694 | from nova.api.openstack import common |
695 | -from nova.api.openstack import faults |
696 | from nova.api.openstack import wsgi |
697 | from nova.auth import manager |
698 | |
699 | @@ -69,7 +68,7 @@ |
700 | user = None |
701 | |
702 | if user is None: |
703 | - raise faults.Fault(exc.HTTPNotFound()) |
704 | + raise exc.HTTPNotFound() |
705 | |
706 | return dict(user=_translate_keys(user)) |
707 | |
708 | |
709 | === modified file 'nova/api/openstack/wsgi.py' |
710 | --- nova/api/openstack/wsgi.py 2011-07-20 17:12:18 +0000 |
711 | +++ nova/api/openstack/wsgi.py 2011-07-21 18:52:39 +0000 |
712 | @@ -448,7 +448,11 @@ |
713 | msg = _("Malformed request body") |
714 | return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg)) |
715 | |
716 | - action_result = self.dispatch(request, action, args) |
717 | + try: |
718 | + action_result = self.dispatch(request, action, args) |
719 | + except webob.exc.HTTPException as ex: |
720 | + LOG.info(_("HTTP exception thrown: %s"), unicode(ex)) |
721 | + action_result = faults.Fault(ex) |
722 | |
723 | #TODO(bcwaldon): find a more elegant way to pass through non-dict types |
724 | if type(action_result) is dict or action_result is None: |
725 | |
726 | === modified file 'nova/api/openstack/zones.py' |
727 | --- nova/api/openstack/zones.py 2011-07-06 20:28:10 +0000 |
728 | +++ nova/api/openstack/zones.py 2011-07-21 18:52:39 +0000 |
729 | @@ -27,7 +27,6 @@ |
730 | |
731 | from nova.api.openstack import create_instance_helper as helper |
732 | from nova.api.openstack import common |
733 | -from nova.api.openstack import faults |
734 | from nova.api.openstack import wsgi |
735 | |
736 | |
737 | @@ -127,11 +126,8 @@ |
738 | Returns a reservation ID (a UUID). |
739 | """ |
740 | result = None |
741 | - try: |
742 | - extra_values, result = self.helper.create_instance(req, body, |
743 | - self.compute_api.create_all_at_once) |
744 | - except faults.Fault, f: |
745 | - return f |
746 | + extra_values, result = self.helper.create_instance(req, body, |
747 | + self.compute_api.create_all_at_once) |
748 | |
749 | reservation_id = result |
750 | return {'reservation_id': reservation_id} |
751 | |
752 | === modified file 'nova/tests/api/openstack/test_servers.py' |
753 | --- nova/tests/api/openstack/test_servers.py 2011-07-19 13:36:37 +0000 |
754 | +++ nova/tests/api/openstack/test_servers.py 2011-07-21 18:52:39 +0000 |
755 | @@ -1758,7 +1758,7 @@ |
756 | self.stubs.Set(nova.compute.api.API, 'resize', resize_mock) |
757 | |
758 | res = req.get_response(fakes.wsgi_app()) |
759 | - self.assertEqual(res.status_int, 400) |
760 | + self.assertEqual(res.status_int, 500) |
761 | |
762 | def test_resized_server_has_correct_status(self): |
763 | req = self.webreq('/1', 'GET') |
This branch resolves some issues I was having where faults would return content like this (for a JSON request):
<html> <head> <title>422 Unprocessable Entity</title> </head> <body> <h1>422 Unprocessable Entity</h1> Unable to process the contained instructions<br /><br /> </body> </html>
---
In this branch we basically treat 400 and 500 faults as exceptions and handle them in nova.api. openstack. wsgi. This branch doesn't touch the extensions and auth middlewares which still return fault.Faults directly where the rest of the OSAPI just raises webob Exceptions.
I'm open to suggestions. This HTML output really bugs me...