From 51cc8637ba2efba7c4dad59a6850b6374258e5df Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Fri, 9 Sep 2011 10:46:51 +0200
Subject: [PATCH] rlib2: Convert /2/nodes/[node_name]/role to OpcodeResource
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Also fix a typo in a constant name.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: RenΓ© Nussbaumer <rn@google.com>
---
 lib/rapi/rlib2.py                  | 34 +++++++++++------------
 test/ganeti.rapi.rlib2_unittest.py | 44 ++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 17 deletions(-)

diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index fdb15c541..44cbc85cd 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -108,14 +108,14 @@ J_FIELDS = J_FIELDS_BULK + [
   ]
 
 _NR_DRAINED = "drained"
-_NR_MASTER_CANDIATE = "master-candidate"
+_NR_MASTER_CANDIDATE = "master-candidate"
 _NR_MASTER = "master"
 _NR_OFFLINE = "offline"
 _NR_REGULAR = "regular"
 
 _NR_MAP = {
   constants.NR_MASTER: _NR_MASTER,
-  constants.NR_MCANDIDATE: _NR_MASTER_CANDIATE,
+  constants.NR_MCANDIDATE: _NR_MASTER_CANDIDATE,
   constants.NR_DRAINED: _NR_DRAINED,
   constants.NR_OFFLINE: _NR_OFFLINE,
   constants.NR_REGULAR: _NR_REGULAR,
@@ -383,10 +383,12 @@ class R_2_nodes_name(baserlib.ResourceBase):
     return baserlib.MapFields(N_FIELDS, result[0])
 
 
-class R_2_nodes_name_role(baserlib.ResourceBase):
-  """ /2/nodes/[node_name]/role resource.
+class R_2_nodes_name_role(baserlib.OpcodeResource):
+  """/2/nodes/[node_name]/role resource.
 
   """
+  PUT_OPCODE = opcodes.OpNodeSetParams
+
   def GET(self):
     """Returns the current node role.
 
@@ -400,16 +402,12 @@ class R_2_nodes_name_role(baserlib.ResourceBase):
 
     return _NR_MAP[result[0][0]]
 
-  def PUT(self):
+  def GetPutOpInput(self):
     """Sets the node role.
 
-    @return: a job id
-
     """
-    if not isinstance(self.request_body, basestring):
-      raise http.HttpBadRequest("Invalid body contents, not a string")
+    baserlib.CheckType(self.request_body, basestring, "Body contents")
 
-    node_name = self.items[0]
     role = self.request_body
 
     if role == _NR_REGULAR:
@@ -417,7 +415,7 @@ class R_2_nodes_name_role(baserlib.ResourceBase):
       offline = False
       drained = False
 
-    elif role == _NR_MASTER_CANDIATE:
+    elif role == _NR_MASTER_CANDIDATE:
       candidate = True
       offline = drained = None
 
@@ -432,13 +430,15 @@ class R_2_nodes_name_role(baserlib.ResourceBase):
     else:
       raise http.HttpBadRequest("Can't set '%s' role" % role)
 
-    op = opcodes.OpNodeSetParams(node_name=node_name,
-                                 master_candidate=candidate,
-                                 offline=offline,
-                                 drained=drained,
-                                 force=bool(self.useForce()))
+    assert len(self.items) == 1
 
-    return self.SubmitJob([op])
+    return ({}, {
+      "node_name": self.items[0],
+      "master_candidate": candidate,
+      "offline": offline,
+      "drained": drained,
+      "force": self.useForce(),
+      })
 
 
 class R_2_nodes_name_evacuate(baserlib.OpcodeResource):
diff --git a/test/ganeti.rapi.rlib2_unittest.py b/test/ganeti.rapi.rlib2_unittest.py
index 3bb154fe2..997676337 100755
--- a/test/ganeti.rapi.rlib2_unittest.py
+++ b/test/ganeti.rapi.rlib2_unittest.py
@@ -1283,5 +1283,49 @@ class TestGroupAdd(unittest.TestCase):
     self.assertTrue(op.dry_run)
 
 
+class TestNodeRole(unittest.TestCase):
+  def test(self):
+    clfactory = _FakeClientFactory(_FakeClient)
+
+    for role in rlib2._NR_MAP.values():
+      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
+                               ["node-z"], {}, role, clfactory)
+      if role == rlib2._NR_MASTER:
+        self.assertRaises(http.HttpBadRequest, handler.PUT)
+      else:
+        job_id = handler.PUT()
+
+        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.OpNodeSetParams))
+        self.assertEqual(op.node_name, "node-z")
+        self.assertFalse(op.force)
+        self.assertFalse(hasattr(op, "dry_run"))
+
+        if role == rlib2._NR_REGULAR:
+          self.assertFalse(op.drained)
+          self.assertFalse(op.offline)
+          self.assertFalse(op.master_candidate)
+        elif role == rlib2._NR_MASTER_CANDIDATE:
+          self.assertFalse(op.drained)
+          self.assertFalse(op.offline)
+          self.assertTrue(op.master_candidate)
+        elif role == rlib2._NR_DRAINED:
+          self.assertTrue(op.drained)
+          self.assertFalse(op.offline)
+          self.assertFalse(op.master_candidate)
+        elif role == rlib2._NR_OFFLINE:
+          self.assertFalse(op.drained)
+          self.assertTrue(op.offline)
+          self.assertFalse(op.master_candidate)
+        else:
+          self.fail("Unknown role '%s'" % role)
+
+      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()
-- 
GitLab