Commit 3882937a authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

RAPI: Allow modifying instance


Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent dd0fa69d
......@@ -671,6 +671,45 @@ Body parameters:
Whether to ensure instance's name is resolvable.
``/2/instances/[instance_name]/modify``
++++++++++++++++++++++++++++++++++++++++
Modifies an instance.
Supports the following commands: ``PUT``.
``PUT``
~~~~~~~
Returns a job ID.
Body parameters:
``osparams`` (dict)
Dictionary with OS parameters.
``hvparams`` (dict)
Hypervisor parameters, hypervisor-dependent.
``beparams`` (dict)
Backend parameters.
``force`` (bool)
Whether to force the operation.
``nics`` (list)
List of NIC changes. Each item is of the form ``(op, settings)``.
``op`` can be ``add`` to add a new NIC with the specified settings,
``remove`` to remove the last NIC or a number to modify the settings
of the NIC with that index.
``disks`` (list)
List of disk changes. See ``nics``.
``disk_template`` (string)
Disk template for instance.
``remote_node`` (string)
Secondary node (used when changing disk template).
``os_name`` (string)
Change instance's OS name. Does not reinstall the instance.
``force_variant`` (bool)
Whether to force an unknown variant.
``/2/instances/[instance_name]/tags``
+++++++++++++++++++++++++++++++++++++
......
......@@ -217,6 +217,8 @@ def GetHandlers(node_name_pattern, instance_name_pattern, job_id_pattern):
rlib2.R_2_instances_name_migrate,
re.compile(r'^/2/instances/(%s)/rename$' % instance_name_pattern):
rlib2.R_2_instances_name_rename,
re.compile(r'^/2/instances/(%s)/modify$' % instance_name_pattern):
rlib2.R_2_instances_name_modify,
"/2/jobs": rlib2.R_2_jobs,
re.compile(r"^/2/jobs/(%s)$" % job_id_pattern):
......
......@@ -1055,6 +1055,56 @@ class R_2_instances_name_rename(baserlib.R_Generic):
return baserlib.SubmitJob([op])
def _ParseModifyInstanceRequest(name, data):
"""Parses a request for modifying an instance.
@rtype: L{opcodes.OpSetInstanceParams}
@return: Instance modify opcode
"""
osparams = baserlib.CheckParameter(data, "osparams", default={})
force = baserlib.CheckParameter(data, "force", default=False)
nics = baserlib.CheckParameter(data, "nics", default=[])
disks = baserlib.CheckParameter(data, "disks", default=[])
disk_template = baserlib.CheckParameter(data, "disk_template", default=None)
remote_node = baserlib.CheckParameter(data, "remote_node", default=None)
os_name = baserlib.CheckParameter(data, "os_name", default=None)
force_variant = baserlib.CheckParameter(data, "force_variant", default=False)
# HV/BE parameters
hvparams = baserlib.CheckParameter(data, "hvparams", default={})
utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES,
allowed_values=[constants.VALUE_DEFAULT])
beparams = baserlib.CheckParameter(data, "beparams", default={})
utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES,
allowed_values=[constants.VALUE_DEFAULT])
return opcodes.OpSetInstanceParams(instance_name=name, hvparams=hvparams,
beparams=beparams, osparams=osparams,
force=force, nics=nics, disks=disks,
disk_template=disk_template,
remote_node=remote_node, os_name=os_name,
force_variant=force_variant)
class R_2_instances_name_modify(baserlib.R_Generic):
"""/2/instances/[instance_name]/modify resource.
"""
def PUT(self):
"""Changes some parameters of an instance.
@return: a job id
"""
baserlib.CheckType(self.request_body, dict, "Body contents")
op = _ParseModifyInstanceRequest(self.items[0], self.request_body)
return baserlib.SubmitJob([op])
class _R_Tags(baserlib.R_Generic):
""" Quasiclass for tagging resources
......
......@@ -295,5 +295,68 @@ class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
self.assert_(op.name_check)
class TestParseModifyInstanceRequest(testutils.GanetiTestCase):
def setUp(self):
testutils.GanetiTestCase.setUp(self)
self.Parse = rlib2._ParseModifyInstanceRequest
def test(self):
name = "instush8gah"
test_disks = [
[],
[(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
]
for osparams in [{}, { "some": "value", "other": "Hello World", }]:
for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
for beparams in [{}, { constants.BE_MEMORY: 128, }]:
for force in [False, True]:
for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
for disks in test_disks:
for disk_template in constants.DISK_TEMPLATES:
data = {
"osparams": osparams,
"hvparams": hvparams,
"beparams": beparams,
"nics": nics,
"disks": disks,
"force": force,
"disk_template": disk_template,
}
op = self.Parse(name, data)
self.assert_(isinstance(op, opcodes.OpSetInstanceParams))
self.assertEqual(op.instance_name, name)
self.assertEqual(op.hvparams, hvparams)
self.assertEqual(op.beparams, beparams)
self.assertEqual(op.osparams, osparams)
self.assertEqual(op.force, force)
self.assertEqual(op.nics, nics)
self.assertEqual(op.disks, disks)
self.assertEqual(op.disk_template, disk_template)
self.assert_(op.remote_node is None)
self.assert_(op.os_name is None)
self.assertFalse(op.force_variant)
def testDefaults(self):
name = "instir8aish31"
op = self.Parse(name, {})
self.assert_(isinstance(op, opcodes.OpSetInstanceParams))
self.assertEqual(op.instance_name, name)
self.assertEqual(op.hvparams, {})
self.assertEqual(op.beparams, {})
self.assertEqual(op.osparams, {})
self.assertFalse(op.force)
self.assertEqual(op.nics, [])
self.assertEqual(op.disks, [])
self.assert_(op.disk_template is None)
self.assert_(op.remote_node is None)
self.assert_(op.os_name is None)
self.assertFalse(op.force_variant)
if __name__ == '__main__':
testutils.GanetiTestProgram()
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