Merge "Handle multiple exceptions raised by jsonpatch"
This commit is contained in:
commit
4f4b0c6c40
|
@ -31,7 +31,7 @@ from ironic.api.controllers.v1 import collection
|
|||
from ironic.api.controllers.v1 import link
|
||||
from ironic.api.controllers.v1 import node
|
||||
from ironic.api.controllers.v1 import types
|
||||
from ironic.api.controllers.v1 import utils
|
||||
from ironic.api.controllers.v1 import utils as api_utils
|
||||
from ironic.common import exception
|
||||
from ironic import objects
|
||||
from ironic.openstack.common import excutils
|
||||
|
@ -130,8 +130,8 @@ class ChassisController(rest.RestController):
|
|||
|
||||
def _get_chassis_collection(self, marker, limit, sort_key, sort_dir,
|
||||
expand=False, resource_url=None):
|
||||
limit = utils.validate_limit(limit)
|
||||
sort_dir = utils.validate_sort_dir(sort_dir)
|
||||
limit = api_utils.validate_limit(limit)
|
||||
sort_dir = api_utils.validate_sort_dir(sort_dir)
|
||||
marker_obj = None
|
||||
if marker:
|
||||
marker_obj = objects.Chassis.get_by_uuid(pecan.request.context,
|
||||
|
@ -213,9 +213,8 @@ class ChassisController(rest.RestController):
|
|||
try:
|
||||
chassis = Chassis(**jsonpatch.apply_patch(rpc_chassis.as_dict(),
|
||||
jsonpatch.JsonPatch(patch)))
|
||||
except jsonpatch.JsonPatchException as e:
|
||||
LOG.exception(e)
|
||||
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
||||
except api_utils.JSONPATCH_EXCEPTIONS as e:
|
||||
raise exception.PatchError(patch=patch, reason=e)
|
||||
|
||||
# Update only the fields that have changed
|
||||
for field in objects.Chassis.fields:
|
||||
|
|
|
@ -588,9 +588,8 @@ class NodesController(rest.RestController):
|
|||
try:
|
||||
node = Node(**jsonpatch.apply_patch(rpc_node.as_dict(),
|
||||
jsonpatch.JsonPatch(patch)))
|
||||
except jsonpatch.JsonPatchException as e:
|
||||
LOG.exception(e)
|
||||
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
||||
except api_utils.JSONPATCH_EXCEPTIONS as e:
|
||||
raise exception.PatchError(patch=patch, reason=e)
|
||||
|
||||
# Update only the fields that have changed
|
||||
for field in objects.Node.fields:
|
||||
|
|
|
@ -276,9 +276,8 @@ class PortsController(rest.RestController):
|
|||
try:
|
||||
port = Port(**jsonpatch.apply_patch(rpc_port.as_dict(),
|
||||
jsonpatch.JsonPatch(patch)))
|
||||
except jsonpatch.JsonPatchException as e:
|
||||
LOG.exception(e)
|
||||
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
||||
except api_utils.JSONPATCH_EXCEPTIONS as e:
|
||||
raise exception.PatchError(patch=patch, reason=e)
|
||||
|
||||
# Update only the fields that have changed
|
||||
for field in objects.Port.fields:
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import jsonpatch
|
||||
import wsme
|
||||
|
||||
from oslo.config import cfg
|
||||
|
@ -23,6 +24,11 @@ from oslo.config import cfg
|
|||
CONF = cfg.CONF
|
||||
|
||||
|
||||
JSONPATCH_EXCEPTIONS = (jsonpatch.JsonPatchException,
|
||||
jsonpatch.JsonPointerException,
|
||||
KeyError)
|
||||
|
||||
|
||||
def validate_limit(limit):
|
||||
if limit and limit < 0:
|
||||
raise wsme.exc.ClientSideError(_("Limit must be positive"))
|
||||
|
|
|
@ -139,6 +139,10 @@ class InvalidStateRequested(Invalid):
|
|||
message = _("Invalid state '%(state)s' requested for node %(node)s.")
|
||||
|
||||
|
||||
class PatchError(Invalid):
|
||||
message = _("Couldn't apply patch '%(patch)s'. Reason: %(reason)s")
|
||||
|
||||
|
||||
class InstanceDeployFailure(IronicException):
|
||||
message = _("Failed to deploy instance: %(reason)s")
|
||||
|
||||
|
|
|
@ -234,6 +234,15 @@ class TestPatch(base.FunctionalTest):
|
|||
self.assertEqual(result['uuid'], cdict['uuid'])
|
||||
self.assertEqual(result['description'], cdict['description'])
|
||||
|
||||
def test_remove_non_existent_property_fail(self):
|
||||
cdict = dbutils.get_test_chassis()
|
||||
response = self.patch_json('/chassis/%s' % cdict['uuid'],
|
||||
[{'path': '/extra/non-existent', 'op': 'remove'}],
|
||||
expect_errors=True)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
|
||||
def test_add_singular(self):
|
||||
cdict = dbutils.get_test_chassis()
|
||||
response = self.patch_json('/chassis/%s' % cdict['uuid'],
|
||||
|
|
|
@ -433,13 +433,12 @@ class TestPatch(base.FunctionalTest):
|
|||
self.mock_update_node.assert_called_once_with(
|
||||
mock.ANY, mock.ANY, 'test-topic')
|
||||
|
||||
def test_remove_fail(self):
|
||||
def test_remove_non_existent_property_fail(self):
|
||||
response = self.patch_json('/nodes/%s' % self.node['uuid'],
|
||||
[{'path': '/extra/non-existent', 'op': 'remove'}],
|
||||
expect_errors=True)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
# FIXME(lucasagomes): It should return 400 instead of 500
|
||||
self.assertEqual(response.status_code, 500)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
|
||||
def test_update_state_in_progress(self):
|
||||
|
|
|
@ -257,6 +257,14 @@ class TestPatch(base.FunctionalTest):
|
|||
self.assertEqual(result['uuid'], pdict['uuid'])
|
||||
self.assertEqual(result['address'], pdict['address'])
|
||||
|
||||
def test_remove_non_existent_property_fail(self):
|
||||
response = self.patch_json('/ports/%s' % self.pdict['uuid'],
|
||||
[{'path': '/extra/non-existent', 'op': 'remove'}],
|
||||
expect_errors=True)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
|
||||
def test_remove_mandatory_field(self):
|
||||
pdict = post_get_test_port(address="AA:BB:CC:DD:EE:FF",
|
||||
uuid=utils.generate_uuid())
|
||||
|
|
Loading…
Reference in New Issue