diff --git a/doc/rapi.rst b/doc/rapi.rst index 5a00dddcb114c66ad3c2db3d0b2fc562209f3bb7..238b849a8cd5ab459c59a8258998824254d5375a 100644 --- a/doc/rapi.rst +++ b/doc/rapi.rst @@ -1326,6 +1326,28 @@ be a job id. It supports the bool ``force`` argument. + +``/2/nodes/[node_name]/modify`` ++++++++++++++++++++++++++++++++++ + +Modifies the parameters of a node. Supports the following commands: +``POST``. + +``POST`` +~~~~~~~ + +Returns a job ID. + +Body parameters: + +.. opcode_params:: OP_NODE_SET_PARAMS + :exclude: node_name + +Job result: + +.. opcode_result:: OP_NODE_SET_PARAMS + + ``/2/nodes/[node_name]/storage`` ++++++++++++++++++++++++++++++++ diff --git a/lib/rapi/client.py b/lib/rapi/client.py index dac670b1b187818531d51bfdd720d3fe2c16fe22..2453eb6125324f8588ce333056e9f0a5d8cde633 100644 --- a/lib/rapi/client.py +++ b/lib/rapi/client.py @@ -1449,6 +1449,21 @@ class GanetiRapiClient(object): # pylint: disable=R0904 ("/%s/nodes/%s/role" % (GANETI_RAPI_VERSION, node)), query, role) + def ModifyNode(self, group, **kwargs): + """Modifies a node. + + More details for parameters can be found in the RAPI documentation. + + @type group: string + @param group: Node name + @rtype: string + @return: job id + + """ + return self._SendRequest(HTTP_POST, + ("/%s/nodes/%s/modify" % + (GANETI_RAPI_VERSION, group)), None, kwargs) + def GetNodeStorageUnits(self, node, storage_type, output_fields): """Gets the storage units for a node. diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py index 499e2e69fe10a064c2ec3b7bf88a518fb1976f94..a0ddcaf2c194408022567df109bc572be3641b8e 100644 --- a/lib/rapi/connector.py +++ b/lib/rapi/connector.py @@ -177,6 +177,8 @@ def GetHandlers(node_name_pattern, instance_name_pattern, rlib2.R_2_nodes_name_evacuate, re.compile(r"^/2/nodes/(%s)/migrate$" % node_name_pattern): rlib2.R_2_nodes_name_migrate, + re.compile(r"^/2/nodes/(%s)/modify$" % node_name_pattern): + rlib2.R_2_nodes_name_modify, re.compile(r"^/2/nodes/(%s)/storage$" % node_name_pattern): rlib2.R_2_nodes_name_storage, re.compile(r"^/2/nodes/(%s)/storage/modify$" % node_name_pattern): diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py index 0a958da114beb3e2ee8f5d8ede3fc822d62b942a..e905ec7d09fd2f72dc4113081a581f97fe7fce51 100644 --- a/lib/rapi/rlib2.py +++ b/lib/rapi/rlib2.py @@ -497,6 +497,25 @@ class R_2_nodes_name_migrate(baserlib.R_Generic): return baserlib.SubmitJob([op]) +class R_2_nodes_name_modify(baserlib.R_Generic): + """/2/nodes/[node_name]/modify resource. + + """ + def POST(self): + """Changes parameters of a node. + + @return: a job id + + """ + baserlib.CheckType(self.request_body, dict, "Body contents") + + op = baserlib.FillOpcode(opcodes.OpNodeSetParams, self.request_body, { + "instance_name": self.items[0], + }) + + return baserlib.SubmitJob([op]) + + class R_2_nodes_name_storage(baserlib.R_Generic): """/2/nodes/[node_name]/storage resource. diff --git a/test/ganeti.rapi.client_unittest.py b/test/ganeti.rapi.client_unittest.py index d7af45ad3ca6ec6295727ed670fe94e42331c6ce..dc972d2875cb5c7440de133a5ca633574ad3fd05 100755 --- a/test/ganeti.rapi.client_unittest.py +++ b/test/ganeti.rapi.client_unittest.py @@ -973,6 +973,14 @@ class GanetiRapiClientTests(testutils.GanetiTestCase): self.assertQuery("force", ["1"]) self.assertEqual("\"master-candidate\"", self.rapi.GetLastRequestData()) + def testModifyNode(self): + self.rapi.AddResponse("3783") + job_id = self.client.ModifyNode("node16979.example.com", drained=True) + self.assertEqual(job_id, 3783) + self.assertHandler(rlib2.R_2_nodes_name_modify) + self.assertItems(["node16979.example.com"]) + self.assertEqual(self.rapi.CountPending(), 0) + def testGetNodeStorageUnits(self): self.rapi.AddResponse("42") self.assertEqual(42,