Group operations: expose add/remove/rename in RAPI
authorAdeodato Simo <dato@google.com>
Mon, 6 Dec 2010 15:23:46 +0000 (15:23 +0000)
committerAdeodato Simo <dato@google.com>
Wed, 8 Dec 2010 12:27:37 +0000 (12:27 +0000)
Signed-off-by: Adeodato Simo <dato@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

doc/rapi.rst
lib/rapi/connector.py
lib/rapi/rlib2.py
test/ganeti.rapi.rlib2_unittest.py

index a10ae5e..67e1e6f 100644 (file)
@@ -337,7 +337,7 @@ features:
 
 The groups resource.
 
-It supports the following commands: ``GET``.
+It supports the following commands: ``GET``, ``POST``.
 
 ``GET``
 ~~~~~~~
@@ -383,12 +383,59 @@ Example::
       }
     ]
 
+``POST``
+~~~~~~~~
+
+Creates a node group.
+
+If the optional bool *dry-run* argument is provided, the job will not be
+actually executed, only the pre-execution checks will be done.
+
+Returns: a job ID that can be used later for polling.
+
+Body parameters:
+
+``name`` (string, required)
+  Node group name.
+
+
 ``/2/groups/[group_name]``
-+++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++
 
 Returns information about a node group.
 
-It supports the following commands: ``GET``.
+It supports the following commands: ``GET``, ``DELETE``.
+
+``GET``
+~~~~~~~
+
+Returns information about a node group, similar to the bulk output from
+the node group list.
+
+``DELETE``
+~~~~~~~~~~
+
+Deletes a node group.
+
+It supports the ``dry-run`` argument.
+
+
+``/2/groups/[group_name]/rename``
++++++++++++++++++++++++++++++++++
+
+Renames a node group.
+
+Supports the following commands: ``PUT``.
+
+``PUT``
+~~~~~~~
+
+Returns a job ID.
+
+Body parameters:
+
+``new_name`` (string, required)
+  New node group name.
 
 
 ``/2/instances``
index f4015ee..9f3a314 100644 (file)
@@ -215,6 +215,8 @@ def GetHandlers(node_name_pattern, instance_name_pattern,
     "/2/groups": rlib2.R_2_groups,
     re.compile(r'^/2/groups/(%s)$' % group_name_pattern):
       rlib2.R_2_groups_name,
+    re.compile(r'^/2/groups/(%s)/rename$' % group_name_pattern):
+      rlib2.R_2_groups_name_rename,
 
     "/2/jobs": rlib2.R_2_jobs,
     re.compile(r"^/2/jobs/(%s)$" % job_id_pattern):
index 39514a0..6c265ec 100644 (file)
@@ -550,6 +550,17 @@ class R_2_groups(baserlib.R_Generic):
       return baserlib.BuildUriList(groupnames, "/2/groups/%s",
                                    uri_fields=("name", "uri"))
 
+  def POST(self):
+    """Create a node group.
+
+    @return: a job id
+
+    """
+    baserlib.CheckType(self.request_body, dict, "Body contents")
+    group_name = baserlib.CheckParameter(self.request_body, "name")
+    op = opcodes.OpAddGroup(group_name=group_name, dry_run=self.dryRun())
+    return baserlib.SubmitJob([op])
+
 
 class R_2_groups_name(baserlib.R_Generic):
   """/2/groups/[group_name] resources.
@@ -568,6 +579,51 @@ class R_2_groups_name(baserlib.R_Generic):
 
     return baserlib.MapFields(G_FIELDS, result[0])
 
+  def DELETE(self):
+    """Delete a node group.
+
+    """
+    op = opcodes.OpRemoveGroup(group_name=self.items[0],
+                               dry_run=bool(self.dryRun()))
+
+    return baserlib.SubmitJob([op])
+
+
+def _ParseRenameGroupRequest(name, data, dry_run):
+  """Parses a request for renaming a node group.
+
+  @type name: string
+  @param name: name of the node group to rename
+  @type data: dict
+  @param data: the body received by the rename request
+  @type dry_run: bool
+  @param dry_run: whether to perform a dry run
+
+  @rtype: L{opcodes.OpRenameGroup}
+  @return: Node group rename opcode
+
+  """
+  old_name = name
+  new_name = baserlib.CheckParameter(data, "new_name")
+
+  return opcodes.OpRenameGroup(old_name=old_name, new_name=new_name,
+                               dry_run=dry_run)
+
+
+class R_2_groups_name_rename(baserlib.R_Generic):
+  """/2/groups/[groupe_name]/rename resource.
+
+  """
+  def PUT(self):
+    """Changes the name of a node group.
+
+    @return: a job id
+
+    """
+    baserlib.CheckType(self.request_body, dict, "Body contents")
+    op = _ParseRenameGroupRequest(self.items[0], self.request_body,
+                                  self.dryRun())
+    return baserlib.SubmitJob([op])
 
 
 def _ParseInstanceCreateRequestVersion1(data, dry_run):
index 977427d..9c08ab2 100755 (executable)
@@ -409,5 +409,38 @@ class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
     self.assertFalse(ops[1].osparams)
 
 
+class TestParseRenameGroupRequest(testutils.GanetiTestCase):
+  def setUp(self):
+    testutils.GanetiTestCase.setUp(self)
+
+    self.Parse = rlib2._ParseRenameGroupRequest
+
+  def test(self):
+    name = "instij0eeph7"
+    data = {
+      "new_name": "ua0aiyoo",
+      }
+
+    op = self.Parse(name, data, False)
+
+    self.assert_(isinstance(op, opcodes.OpRenameGroup))
+    self.assertEqual(op.old_name, name)
+    self.assertEqual(op.new_name, "ua0aiyoo")
+    self.assertFalse(op.dry_run)
+
+  def testDryRun(self):
+    name = "instij0eeph7"
+    data = {
+      "new_name": "ua0aiyoo",
+      }
+
+    op = self.Parse(name, data, True)
+
+    self.assert_(isinstance(op, opcodes.OpRenameGroup))
+    self.assertEqual(op.old_name, name)
+    self.assertEqual(op.new_name, "ua0aiyoo")
+    self.assert_(op.dry_run)
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()