diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py index 48c697fc9531c977ac9255c522bdfa28c6bf6ae7..4f3bfb16a4d57b386aa89a7f06478b4c223868b9 100644 --- a/lib/rapi/rlib2.py +++ b/lib/rapi/rlib2.py @@ -922,44 +922,35 @@ class R_2_instances_name_reinstall(baserlib.ResourceBase): return self.SubmitJob(ops) -def _ParseInstanceReplaceDisksRequest(name, data): - """Parses a request for an instance export. - - @rtype: L{opcodes.OpInstanceReplaceDisks} - @return: Instance export opcode - - """ - override = { - "instance_name": name, - } - - # Parse disks - try: - raw_disks = data["disks"] - except KeyError: - pass - else: - if not ht.TListOf(ht.TInt)(raw_disks): # pylint: disable-msg=E1102 - # Backwards compatibility for strings of the format "1, 2, 3" - try: - data["disks"] = [int(part) for part in raw_disks.split(",")] - except (TypeError, ValueError), err: - raise http.HttpBadRequest("Invalid disk index passed: %s" % str(err)) - - return baserlib.FillOpcode(opcodes.OpInstanceReplaceDisks, data, override) - - -class R_2_instances_name_replace_disks(baserlib.ResourceBase): +class R_2_instances_name_replace_disks(baserlib.OpcodeResource): """/2/instances/[instance_name]/replace-disks resource. """ - def POST(self): + POST_OPCODE = opcodes.OpInstanceReplaceDisks + + def GetPostOpInput(self): """Replaces disks on an instance. """ - op = _ParseInstanceReplaceDisksRequest(self.items[0], self.request_body) + data = self.request_body.copy() + static = { + "instance_name": self.items[0], + } - return self.SubmitJob([op]) + # Parse disks + try: + raw_disks = data["disks"] + except KeyError: + pass + else: + if not ht.TListOf(ht.TInt)(raw_disks): # pylint: disable-msg=E1102 + # Backwards compatibility for strings of the format "1, 2, 3" + try: + data["disks"] = [int(part) for part in raw_disks.split(",")] + except (TypeError, ValueError), err: + raise http.HttpBadRequest("Invalid disk index passed: %s" % err) + + return (data, static) class R_2_instances_name_activate_disks(baserlib.ResourceBase): diff --git a/test/ganeti.rapi.rlib2_unittest.py b/test/ganeti.rapi.rlib2_unittest.py index 74b578025f050848ce063099bec0791de757e90e..fd61d16156858b50e377a78502766956a618c527 100755 --- a/test/ganeti.rapi.rlib2_unittest.py +++ b/test/ganeti.rapi.rlib2_unittest.py @@ -864,11 +864,10 @@ class TestGroupRename(unittest.TestCase): self.assertRaises(IndexError, cl.GetNextSubmittedJob) -class TestParseInstanceReplaceDisksRequest(unittest.TestCase): - def setUp(self): - self.Parse = rlib2._ParseInstanceReplaceDisksRequest - +class TestInstanceReplaceDisks(unittest.TestCase): def test(self): + clfactory = _FakeClientFactory(_FakeClient) + name = "inst22568" for disks in [range(1, 4), "1,2,3", "1, 2, 3"]: @@ -878,29 +877,59 @@ class TestParseInstanceReplaceDisksRequest(unittest.TestCase): "iallocator": "myalloc", } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks)) + handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks, + [name], {}, data, clfactory) + job_id = handler.POST() + + cl = clfactory.GetNextClient() + self.assertRaises(IndexError, clfactory.GetNextClient) + + (exp_job_id, (op, )) = cl.GetNextSubmittedJob() + self.assertEqual(job_id, exp_job_id) + + self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks)) + self.assertEqual(op.instance_name, name) self.assertEqual(op.mode, constants.REPLACE_DISK_SEC) self.assertEqual(op.disks, [1, 2, 3]) self.assertEqual(op.iallocator, "myalloc") + self.assertRaises(IndexError, cl.GetNextSubmittedJob) def testDefaults(self): + clfactory = _FakeClientFactory(_FakeClient) + name = "inst11413" data = { "mode": constants.REPLACE_DISK_AUTO, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks)) + handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks, + [name], {}, data, clfactory) + job_id = handler.POST() + + cl = clfactory.GetNextClient() + self.assertRaises(IndexError, clfactory.GetNextClient) + + (exp_job_id, (op, )) = cl.GetNextSubmittedJob() + self.assertEqual(job_id, exp_job_id) + + self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks)) + self.assertEqual(op.instance_name, name) self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO) self.assertFalse(hasattr(op, "iallocator")) self.assertFalse(hasattr(op, "disks")) + self.assertRaises(IndexError, cl.GetNextSubmittedJob) def testWrong(self): - self.assertRaises(http.HttpBadRequest, self.Parse, "inst", - { "mode": constants.REPLACE_DISK_AUTO, - "disks": "hello world", - }) + clfactory = _FakeClientFactory(_FakeClient) + + data = { + "mode": constants.REPLACE_DISK_AUTO, + "disks": "hello world", + } + + handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks, + ["foo"], {}, data, clfactory) + self.assertRaises(http.HttpBadRequest, handler.POST) class TestGroupModify(unittest.TestCase):