Revision 0dbc732c
b/lib/rapi/rlib2.py | ||
---|---|---|
922 | 922 |
return self.SubmitJob(ops) |
923 | 923 |
|
924 | 924 |
|
925 |
def _ParseInstanceReplaceDisksRequest(name, data): |
|
926 |
"""Parses a request for an instance export. |
|
927 |
|
|
928 |
@rtype: L{opcodes.OpInstanceReplaceDisks} |
|
929 |
@return: Instance export opcode |
|
930 |
|
|
931 |
""" |
|
932 |
override = { |
|
933 |
"instance_name": name, |
|
934 |
} |
|
935 |
|
|
936 |
# Parse disks |
|
937 |
try: |
|
938 |
raw_disks = data["disks"] |
|
939 |
except KeyError: |
|
940 |
pass |
|
941 |
else: |
|
942 |
if not ht.TListOf(ht.TInt)(raw_disks): # pylint: disable-msg=E1102 |
|
943 |
# Backwards compatibility for strings of the format "1, 2, 3" |
|
944 |
try: |
|
945 |
data["disks"] = [int(part) for part in raw_disks.split(",")] |
|
946 |
except (TypeError, ValueError), err: |
|
947 |
raise http.HttpBadRequest("Invalid disk index passed: %s" % str(err)) |
|
948 |
|
|
949 |
return baserlib.FillOpcode(opcodes.OpInstanceReplaceDisks, data, override) |
|
950 |
|
|
951 |
|
|
952 |
class R_2_instances_name_replace_disks(baserlib.ResourceBase): |
|
925 |
class R_2_instances_name_replace_disks(baserlib.OpcodeResource): |
|
953 | 926 |
"""/2/instances/[instance_name]/replace-disks resource. |
954 | 927 |
|
955 | 928 |
""" |
956 |
def POST(self): |
|
929 |
POST_OPCODE = opcodes.OpInstanceReplaceDisks |
|
930 |
|
|
931 |
def GetPostOpInput(self): |
|
957 | 932 |
"""Replaces disks on an instance. |
958 | 933 |
|
959 | 934 |
""" |
960 |
op = _ParseInstanceReplaceDisksRequest(self.items[0], self.request_body) |
|
935 |
data = self.request_body.copy() |
|
936 |
static = { |
|
937 |
"instance_name": self.items[0], |
|
938 |
} |
|
961 | 939 |
|
962 |
return self.SubmitJob([op]) |
|
940 |
# Parse disks |
|
941 |
try: |
|
942 |
raw_disks = data["disks"] |
|
943 |
except KeyError: |
|
944 |
pass |
|
945 |
else: |
|
946 |
if not ht.TListOf(ht.TInt)(raw_disks): # pylint: disable-msg=E1102 |
|
947 |
# Backwards compatibility for strings of the format "1, 2, 3" |
|
948 |
try: |
|
949 |
data["disks"] = [int(part) for part in raw_disks.split(",")] |
|
950 |
except (TypeError, ValueError), err: |
|
951 |
raise http.HttpBadRequest("Invalid disk index passed: %s" % err) |
|
952 |
|
|
953 |
return (data, static) |
|
963 | 954 |
|
964 | 955 |
|
965 | 956 |
class R_2_instances_name_activate_disks(baserlib.ResourceBase): |
b/test/ganeti.rapi.rlib2_unittest.py | ||
---|---|---|
864 | 864 |
self.assertRaises(IndexError, cl.GetNextSubmittedJob) |
865 | 865 |
|
866 | 866 |
|
867 |
class TestParseInstanceReplaceDisksRequest(unittest.TestCase): |
|
868 |
def setUp(self): |
|
869 |
self.Parse = rlib2._ParseInstanceReplaceDisksRequest |
|
870 |
|
|
867 |
class TestInstanceReplaceDisks(unittest.TestCase): |
|
871 | 868 |
def test(self): |
869 |
clfactory = _FakeClientFactory(_FakeClient) |
|
870 |
|
|
872 | 871 |
name = "inst22568" |
873 | 872 |
|
874 | 873 |
for disks in [range(1, 4), "1,2,3", "1, 2, 3"]: |
... | ... | |
878 | 877 |
"iallocator": "myalloc", |
879 | 878 |
} |
880 | 879 |
|
881 |
op = self.Parse(name, data) |
|
882 |
self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks)) |
|
880 |
handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks, |
|
881 |
[name], {}, data, clfactory) |
|
882 |
job_id = handler.POST() |
|
883 |
|
|
884 |
cl = clfactory.GetNextClient() |
|
885 |
self.assertRaises(IndexError, clfactory.GetNextClient) |
|
886 |
|
|
887 |
(exp_job_id, (op, )) = cl.GetNextSubmittedJob() |
|
888 |
self.assertEqual(job_id, exp_job_id) |
|
889 |
|
|
890 |
self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks)) |
|
891 |
self.assertEqual(op.instance_name, name) |
|
883 | 892 |
self.assertEqual(op.mode, constants.REPLACE_DISK_SEC) |
884 | 893 |
self.assertEqual(op.disks, [1, 2, 3]) |
885 | 894 |
self.assertEqual(op.iallocator, "myalloc") |
895 |
self.assertRaises(IndexError, cl.GetNextSubmittedJob) |
|
886 | 896 |
|
887 | 897 |
def testDefaults(self): |
898 |
clfactory = _FakeClientFactory(_FakeClient) |
|
899 |
|
|
888 | 900 |
name = "inst11413" |
889 | 901 |
data = { |
890 | 902 |
"mode": constants.REPLACE_DISK_AUTO, |
891 | 903 |
} |
892 | 904 |
|
893 |
op = self.Parse(name, data) |
|
894 |
self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks)) |
|
905 |
handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks, |
|
906 |
[name], {}, data, clfactory) |
|
907 |
job_id = handler.POST() |
|
908 |
|
|
909 |
cl = clfactory.GetNextClient() |
|
910 |
self.assertRaises(IndexError, clfactory.GetNextClient) |
|
911 |
|
|
912 |
(exp_job_id, (op, )) = cl.GetNextSubmittedJob() |
|
913 |
self.assertEqual(job_id, exp_job_id) |
|
914 |
|
|
915 |
self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks)) |
|
916 |
self.assertEqual(op.instance_name, name) |
|
895 | 917 |
self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO) |
896 | 918 |
self.assertFalse(hasattr(op, "iallocator")) |
897 | 919 |
self.assertFalse(hasattr(op, "disks")) |
920 |
self.assertRaises(IndexError, cl.GetNextSubmittedJob) |
|
898 | 921 |
|
899 | 922 |
def testWrong(self): |
900 |
self.assertRaises(http.HttpBadRequest, self.Parse, "inst", |
|
901 |
{ "mode": constants.REPLACE_DISK_AUTO, |
|
902 |
"disks": "hello world", |
|
903 |
}) |
|
923 |
clfactory = _FakeClientFactory(_FakeClient) |
|
924 |
|
|
925 |
data = { |
|
926 |
"mode": constants.REPLACE_DISK_AUTO, |
|
927 |
"disks": "hello world", |
|
928 |
} |
|
929 |
|
|
930 |
handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks, |
|
931 |
["foo"], {}, data, clfactory) |
|
932 |
self.assertRaises(http.HttpBadRequest, handler.POST) |
|
904 | 933 |
|
905 | 934 |
|
906 | 935 |
class TestGroupModify(unittest.TestCase): |
Also available in: Unified diff