Commit a52978c7 authored by Michael Hanselmann's avatar Michael Hanselmann

RAPI: Add resource to recreate instance's disks

This was still missing from RAPI.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 23f0b93e
......@@ -811,6 +811,23 @@ It supports the following commands: ``PUT``.
Takes no parameters.
``/2/instances/[instance_name]/recreate-disks``
+++++++++++++++++++++++++++++++++++++++++++++++++
Recreate disks of an instance. Supports the following commands:
``POST``.
``POST``
~~~~~~~~
Returns a job ID.
Body parameters:
.. opcode_params:: OP_INSTANCE_RECREATE_DISKS
:exclude: instance_name
``/2/instances/[instance_name]/disk/[disk_index]/grow``
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
......
......@@ -1268,7 +1268,7 @@ class OpInstanceDeactivateDisks(OpCode):
class OpInstanceRecreateDisks(OpCode):
"""Deactivate an instance's disks."""
"""Recreate an instance's disks."""
OP_DSC_FIELD = "instance_name"
OP_PARAMS = [
_PInstanceName,
......
......@@ -753,6 +753,31 @@ class GanetiRapiClient(object): # pylint: disable=R0904
("/%s/instances/%s/deactivate-disks" %
(GANETI_RAPI_VERSION, instance)), None, None)
def RecreateInstanceDisks(self, instance, disks=None, nodes=None):
"""Recreate an instance's disks.
@type instance: string
@param instance: Instance name
@type disks: list of int
@param disks: List of disk indexes
@type nodes: list of string
@param nodes: New instance nodes, if relocation is desired
@rtype: string
@return: job id
"""
body = {}
if disks is not None:
body["disks"] = disks
if nodes is not None:
body["nodes"] = nodes
return self._SendRequest(HTTP_POST,
("/%s/instances/%s/recreate-disks" %
(GANETI_RAPI_VERSION, instance)), None, body)
def GrowInstanceDisk(self, instance, disk, amount, wait_for_sync=None):
"""Grows a disk of an instance.
......
......@@ -143,6 +143,8 @@ def GetHandlers(node_name_pattern, instance_name_pattern,
rlib2.R_2_instances_name_activate_disks,
re.compile(r"^/2/instances/(%s)/deactivate-disks$" % instance_name_pattern):
rlib2.R_2_instances_name_deactivate_disks,
re.compile(r"^/2/instances/(%s)/recreate-disks$" % instance_name_pattern):
rlib2.R_2_instances_name_recreate_disks,
re.compile(r"^/2/instances/(%s)/prepare-export$" % instance_name_pattern):
rlib2.R_2_instances_name_prepare_export,
re.compile(r"^/2/instances/(%s)/export$" % instance_name_pattern):
......
......@@ -995,6 +995,21 @@ class R_2_instances_name_deactivate_disks(baserlib.OpcodeResource):
})
class R_2_instances_name_recreate_disks(baserlib.OpcodeResource):
"""/2/instances/[instance_name]/recreate-disks resource.
"""
POST_OPCODE = opcodes.OpInstanceRecreateDisks
def GetPostOpInput(self):
"""Recreate disks for an instance.
"""
return ({}, {
"instance_name": self.items[0],
})
class R_2_instances_name_prepare_export(baserlib.OpcodeResource):
"""/2/instances/[instance_name]/prepare-export resource.
......
......@@ -53,7 +53,6 @@ RAPI_OPCODE_EXCLUDE = frozenset([
opcodes.OpClusterVerifyDisks,
opcodes.OpInstanceChangeGroup,
opcodes.OpInstanceMove,
opcodes.OpInstanceRecreateDisks,
opcodes.OpNodePowercycle,
opcodes.OpNodeQueryvols,
opcodes.OpOobCommand,
......
......@@ -1166,6 +1166,14 @@ class GanetiRapiClientTests(testutils.GanetiTestCase):
self.assertHandler(rlib2.R_2_instances_name_deactivate_disks)
self.assertFalse(self.rapi.GetLastHandler().queryargs)
def testRecreateInstanceDisks(self):
self.rapi.AddResponse("13553")
job_id = self.client.RecreateInstanceDisks("inst23153")
self.assertEqual(job_id, 13553)
self.assertItems(["inst23153"])
self.assertHandler(rlib2.R_2_instances_name_recreate_disks)
self.assertFalse(self.rapi.GetLastHandler().queryargs)
def testGetInstanceConsole(self):
self.rapi.AddResponse("26876")
job_id = self.client.GetInstanceConsole("inst21491")
......
......@@ -446,6 +446,26 @@ class TestInstanceDeactivateDisks(unittest.TestCase):
self.assertRaises(IndexError, cl.GetNextSubmittedJob)
class TestInstanceRecreateDisks(unittest.TestCase):
def test(self):
clfactory = _FakeClientFactory(_FakeClient)
handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
["inst22357"], {}, {}, 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.OpInstanceRecreateDisks))
self.assertEqual(op.instance_name, "inst22357")
self.assertFalse(hasattr(op, "dry_run"))
self.assertFalse(hasattr(op, "force"))
self.assertRaises(IndexError, cl.GetNextSubmittedJob)
class TestInstanceFailover(unittest.TestCase):
def test(self):
clfactory = _FakeClientFactory(_FakeClient)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment