From d56e7dc73fe625590a3b9c8d0389fa99f5638749 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Fri, 30 Jul 2010 19:12:32 +0200
Subject: [PATCH] Allow renaming instances via RAPI

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 doc/rapi.rst                       | 22 ++++++++++++++++
 lib/rapi/connector.py              |  2 ++
 lib/rapi/rlib2.py                  | 32 +++++++++++++++++++++++
 test/ganeti.rapi.rlib2_unittest.py | 41 ++++++++++++++++++++++++++++++
 4 files changed, 97 insertions(+)

diff --git a/doc/rapi.rst b/doc/rapi.rst
index d47ae4470..6d4b1a70d 100644
--- a/doc/rapi.rst
+++ b/doc/rapi.rst
@@ -649,6 +649,28 @@ Body parameters:
   Whether a previously failed migration should be cleaned up.
 
 
+``/2/instances/[instance_name]/rename``
+++++++++++++++++++++++++++++++++++++++++
+
+Renames an instance.
+
+Supports the following commands: ``PUT``.
+
+``PUT``
+~~~~~~~
+
+Returns a job ID.
+
+Body parameters:
+
+``new_name`` (string, required)
+  New instance name.
+``ip_check`` (bool)
+  Whether to ensure instance's IP address is inactive.
+``name_check`` (bool)
+  Whether to ensure instance's name is resolvable.
+
+
 ``/2/instances/[instance_name]/tags``
 +++++++++++++++++++++++++++++++++++++
 
diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py
index d0b18eba3..b865e7415 100644
--- a/lib/rapi/connector.py
+++ b/lib/rapi/connector.py
@@ -215,6 +215,8 @@ def GetHandlers(node_name_pattern, instance_name_pattern, job_id_pattern):
       rlib2.R_2_instances_name_export,
     re.compile(r'^/2/instances/(%s)/migrate$' % instance_name_pattern):
       rlib2.R_2_instances_name_migrate,
+    re.compile(r'^/2/instances/(%s)/rename$' % instance_name_pattern):
+      rlib2.R_2_instances_name_rename,
 
     "/2/jobs": rlib2.R_2_jobs,
     re.compile(r"^/2/jobs/(%s)$" % job_id_pattern):
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index 18d8d1c89..cacf7d825 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -1023,6 +1023,38 @@ class R_2_instances_name_migrate(baserlib.R_Generic):
     return baserlib.SubmitJob([op])
 
 
+def _ParseRenameInstanceRequest(name, data):
+  """Parses a request for renaming an instance.
+
+  @rtype: L{opcodes.OpRenameInstance}
+  @return: Instance rename opcode
+
+  """
+  new_name = baserlib.CheckParameter(data, "new_name")
+  ip_check = baserlib.CheckParameter(data, "ip_check", default=True)
+  name_check = baserlib.CheckParameter(data, "name_check", default=True)
+
+  return opcodes.OpRenameInstance(instance_name=name, new_name=new_name,
+                                  name_check=name_check, ip_check=ip_check)
+
+
+class R_2_instances_name_rename(baserlib.R_Generic):
+  """/2/instances/[instance_name]/rename resource.
+
+  """
+  def PUT(self):
+    """Changes the name of an instance.
+
+    @return: a job id
+
+    """
+    baserlib.CheckType(self.request_body, dict, "Body contents")
+
+    op = _ParseRenameInstanceRequest(self.items[0], self.request_body)
+
+    return baserlib.SubmitJob([op])
+
+
 class _R_Tags(baserlib.R_Generic):
   """ Quasiclass for tagging resources
 
diff --git a/test/ganeti.rapi.rlib2_unittest.py b/test/ganeti.rapi.rlib2_unittest.py
index f9cd70120..632001df8 100755
--- a/test/ganeti.rapi.rlib2_unittest.py
+++ b/test/ganeti.rapi.rlib2_unittest.py
@@ -254,5 +254,46 @@ class TestParseMigrateInstanceRequest(testutils.GanetiTestCase):
     self.assertFalse(op.cleanup)
 
 
+class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
+  def setUp(self):
+    testutils.GanetiTestCase.setUp(self)
+
+    self.Parse = rlib2._ParseRenameInstanceRequest
+
+  def test(self):
+    name = "instij0eeph7"
+
+    for new_name in ["ua0aiyoo", "fai3ongi"]:
+      for ip_check in [False, True]:
+        for name_check in [False, True]:
+          data = {
+            "new_name": new_name,
+            "ip_check": ip_check,
+            "name_check": name_check,
+            }
+
+          op = self.Parse(name, data)
+          self.assert_(isinstance(op, opcodes.OpRenameInstance))
+          self.assertEqual(op.instance_name, name)
+          self.assertEqual(op.new_name, new_name)
+          self.assertEqual(op.ip_check, ip_check)
+          self.assertEqual(op.name_check, name_check)
+
+  def testDefaults(self):
+    name = "instahchie3t"
+
+    for new_name in ["thag9mek", "quees7oh"]:
+      data = {
+        "new_name": new_name,
+        }
+
+      op = self.Parse(name, data)
+      self.assert_(isinstance(op, opcodes.OpRenameInstance))
+      self.assertEqual(op.instance_name, name)
+      self.assertEqual(op.new_name, new_name)
+      self.assert_(op.ip_check)
+      self.assert_(op.name_check)
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()
-- 
GitLab