From 4f7e5a1da4f7b02efb9d21b87f7095751cbff2f9 Mon Sep 17 00:00:00 2001
From: Bernardo Dal Seno <bdalseno@google.com>
Date: Wed, 27 Feb 2013 18:50:17 +0100
Subject: [PATCH] Fix upgrade of policy in objects.Cluster

Unknown elements were silently removed on startup. This means that a
software upgrade could result in lost configuration information if
cfgupgrade wasn't run promptly.

Added unit test for Cluster.UpgradeConfig() to cover this case.

Signed-off-by: Bernardo Dal Seno <bdalseno@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 lib/objects.py                     | 6 ++++++
 test/py/ganeti.objects_unittest.py | 7 +++++++
 2 files changed, 13 insertions(+)

diff --git a/lib/objects.py b/lib/objects.py
index 60c7aac04..6bae3a5d4 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -1616,6 +1616,12 @@ class Cluster(TaggableObject):
       # we can either make sure to upgrade the ipolicy always, or only
       # do it in some corner cases (e.g. missing keys); note that this
       # will break any removal of keys from the ipolicy dict
+      wrongkeys = frozenset(self.ipolicy.keys()) - constants.IPOLICY_ALL_KEYS
+      if wrongkeys:
+        # These keys would be silently removed by FillIPolicy()
+        msg = ("Cluster instance policy contains spourious keys: %s" %
+               utils.CommaJoin(wrongkeys))
+        raise errors.ConfigurationError(msg)
       self.ipolicy = FillIPolicy(constants.IPOLICY_DEFAULTS, self.ipolicy)
 
   @property
diff --git a/test/py/ganeti.objects_unittest.py b/test/py/ganeti.objects_unittest.py
index 9c4595d02..6f73e303d 100755
--- a/test/py/ganeti.objects_unittest.py
+++ b/test/py/ganeti.objects_unittest.py
@@ -215,6 +215,13 @@ class TestClusterObject(unittest.TestCase):
     self.fake_cl.enabled_hypervisors = sorted(constants.HYPER_TYPES)
     self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_CHROOT)
 
+  def testUpgradeConfig(self):
+    # FIXME: This test is incomplete
+    cluster = objects.Cluster()
+    cluster.UpgradeConfig()
+    cluster = objects.Cluster(ipolicy={"unknown_key": None})
+    self.assertRaises(errors.ConfigurationError, cluster.UpgradeConfig)
+
 
 class TestOS(unittest.TestCase):
   ALL_DATA = [
-- 
GitLab