From e055a2ab54a41998d41192afb462837ba5eb27b9 Mon Sep 17 00:00:00 2001
From: Dimitris Aragiorgis <dimara@grnet.gr>
Date: Thu, 29 Nov 2012 13:49:38 +0200
Subject: [PATCH] Introduce ht.TMaybeValueNone and ht.TValueNone

TValueNone checks if a value is "none" and TMaybeValueNone is a wrapper
of TOr(TValueNone, x). This is used by OpNetworkSetParam in order to
reset a network value (e.g. mac_prefix, gateway, etc.)

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/ht.py                  | 15 +++++++++++++++
 lib/opcodes.py             | 17 +++++++----------
 test/ganeti.ht_unittest.py | 12 ++++++++++++
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/lib/ht.py b/lib/ht.py
index 85d3b82d8..eba209ac3 100644
--- a/lib/ht.py
+++ b/lib/ht.py
@@ -187,6 +187,14 @@ def TNone(val):
   return val is None
 
 
+@WithDesc("ValueNone")
+def TValueNone(val):
+  """Checks if the given value is L{constants.VALUE_NONE}.
+
+  """
+  return val == constants.VALUE_NONE
+
+
 @WithDesc("Boolean")
 def TBool(val):
   """Checks if the given value is a boolean.
@@ -319,6 +327,13 @@ def TMaybe(test):
   return TOr(TNone, test)
 
 
+def TMaybeValueNone(test):
+  """Used for unsetting values.
+
+  """
+  return TMaybe(TOr(TValueNone, test))
+
+
 # Type aliases
 
 #: a non-empty string
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 959d56b0e..0721eab60 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -348,10 +348,6 @@ _PStorageType = ("storage_type", ht.NoDefault, _CheckStorageType,
 
 _CheckNetworkType = ht.TElemOf(constants.NETWORK_VALID_TYPES)
 
-#: Network type parameter
-_PNetworkType = ("network_type", None, ht.TMaybe(_CheckNetworkType),
-                 "Network type")
-
 
 @ht.WithDesc("IPv4 network")
 def _CheckCIDRNetNotation(value):
@@ -2024,7 +2020,7 @@ class OpNetworkAdd(OpCode):
   OP_DSC_FIELD = "network_name"
   OP_PARAMS = [
     _PNetworkName,
-    _PNetworkType,
+    ("network_type", None, ht.TMaybe(_CheckNetworkType), "Network type"),
     ("network", ht.NoDefault, _TIpNetwork4, "IPv4 subnet"),
     ("gateway", None, ht.TMaybe(_TIpAddress4), "IPv4 gateway"),
     ("network6", None, ht.TMaybe(_TIpNetwork6), "IPv6 subnet"),
@@ -2056,11 +2052,12 @@ class OpNetworkSetParams(OpCode):
   OP_DSC_FIELD = "network_name"
   OP_PARAMS = [
     _PNetworkName,
-    _PNetworkType,
-    ("gateway", None, ht.TMaybe(_TIpAddress4), "IPv4 gateway"),
-    ("network6", None, ht.TMaybe(_TIpNetwork6), "IPv6 subnet"),
-    ("gateway6", None, ht.TMaybe(_TIpAddress6), "IPv6 gateway"),
-    ("mac_prefix", None, ht.TMaybeString,
+    ("network_type", None, ht.TMaybeValueNone(_CheckNetworkType),
+     "Network type"),
+    ("gateway", None, ht.TMaybeValueNone(_TIpAddress4), "IPv4 gateway"),
+    ("network6", None, ht.TMaybeValueNone(_TIpNetwork6), "IPv6 subnet"),
+    ("gateway6", None, ht.TMaybeValueNone(_TIpAddress6), "IPv6 gateway"),
+    ("mac_prefix", None, ht.TMaybeValueNone(ht.TString),
      "MAC address prefix that overrides cluster one"),
     ("add_reserved_ips", None, _TMaybeAddr4List,
      "Which external IP addresses to reserve"),
diff --git a/test/ganeti.ht_unittest.py b/test/ganeti.ht_unittest.py
index 8e7b910f1..e99a81029 100755
--- a/test/ganeti.ht_unittest.py
+++ b/test/ganeti.ht_unittest.py
@@ -23,6 +23,7 @@
 
 import unittest
 
+from ganeti import constants
 from ganeti import ht
 
 import testutils
@@ -282,6 +283,17 @@ class TestTypeChecks(unittest.TestCase):
 
     self.assertFalse(fn(None))
 
+  def testMaybeValueNone(self):
+    fn = ht.TMaybeValueNone(ht.TInt)
+
+    self.assertTrue(fn(None))
+    self.assertTrue(fn(0))
+    self.assertTrue(fn(constants.VALUE_NONE))
+
+    self.assertFalse(fn(""))
+    self.assertFalse(fn([]))
+    self.assertFalse(fn(constants.VALUE_DEFAULT))
+
 
 if __name__ == "__main__":
   testutils.GanetiTestProgram()
-- 
GitLab