Make LUInstanceSetParams handle pnode parameter
[ganeti-local] / lib / query.py
index c7f8fa9..ff801ce 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2010, 2011, 2012 Google Inc.
+# Copyright (C) 2010, 2011, 2012, 2013 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -90,7 +90,8 @@ from ganeti.constants import (QFT_UNKNOWN, QFT_TEXT, QFT_BOOL, QFT_NUMBER,
  IQ_LIVE,
  IQ_DISKUSAGE,
  IQ_CONSOLE,
- IQ_NODES) = range(100, 105)
+ IQ_NODES,
+ IQ_NETWORKS) = range(100, 106)
 
 (LQ_MODE,
  LQ_OWNER,
@@ -976,6 +977,23 @@ def _GetItemAttr(attr):
   return lambda _, item: getter(item)
 
 
+def _GetItemMaybeAttr(attr):
+  """Returns a field function to return a not-None attribute of the item.
+
+  If the value is None, then C{_FS_UNAVAIL} will be returned instead.
+
+  @param attr: Attribute name
+
+  """
+  def _helper(_, obj):
+    val = getattr(obj, attr)
+    if val is None:
+      return _FS_UNAVAIL
+    else:
+      return val
+  return _helper
+
+
 def _GetNDParam(name):
   """Return a field function to return an ND parameter out of the context.
 
@@ -1344,7 +1362,7 @@ def _BuildNodeFields():
     return lambda ctx, node: len(getter(ctx)[node.name])
 
   def _GetList(getter):
-    return lambda ctx, node: list(getter(ctx)[node.name])
+    return lambda ctx, node: utils.NiceSort(list(getter(ctx)[node.name]))
 
   # Add fields operating on instance lists
   for prefix, titleprefix, docword, getter in \
@@ -1383,7 +1401,7 @@ class InstanceQueryData:
 
   """
   def __init__(self, instances, cluster, disk_usage, offline_nodes, bad_nodes,
-               live_data, wrongnode_inst, console, nodes, groups):
+               live_data, wrongnode_inst, console, nodes, groups, networks):
     """Initializes this class.
 
     @param instances: List of instance objects
@@ -1402,6 +1420,8 @@ class InstanceQueryData:
     @param console: Per-instance console information
     @type nodes: dict; node name as key
     @param nodes: Node objects
+    @type networks: dict; net_uuid as key
+    @param networks: Network objects
 
     """
     assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
@@ -1419,6 +1439,7 @@ class InstanceQueryData:
     self.console = console
     self.nodes = nodes
     self.groups = groups
+    self.networks = networks
 
     # Used for individual rows
     self.inst_hvparams = None
@@ -1569,6 +1590,20 @@ def _GetInstNic(index, cb):
   return fn
 
 
+def _GetInstNicNetworkName(ctx, _, nic): # pylint: disable=W0613
+  """Get a NIC's Network.
+
+  @type ctx: L{InstanceQueryData}
+  @type nic: L{objects.NIC}
+  @param nic: NIC object
+
+  """
+  if nic.network is None:
+    return _FS_UNAVAIL
+  else:
+    return ctx.networks[nic.network].name
+
+
 def _GetInstNicNetwork(ctx, _, nic): # pylint: disable=W0613
   """Get a NIC's Network.
 
@@ -1615,6 +1650,27 @@ def _GetInstNicBridge(ctx, index, _):
     return _FS_UNAVAIL
 
 
+def _GetInstAllNicNetworkNames(ctx, inst):
+  """Get all network names for an instance.
+
+  @type ctx: L{InstanceQueryData}
+  @type inst: L{objects.Instance}
+  @param inst: Instance object
+
+  """
+  result = []
+
+  for nic in inst.nics:
+    name = None
+    if nic.network:
+      name = ctx.networks[nic.network].name
+    result.append(name)
+
+  assert len(result) == len(inst.nics)
+
+  return result
+
+
 def _GetInstAllNicBridges(ctx, inst):
   """Get all network bridges for an instance.
 
@@ -1697,6 +1753,9 @@ def _GetInstanceNetworkFields():
     (_MakeField("nic.networks", "NIC_networks", QFT_OTHER,
                 "List containing each interface's network"), IQ_CONFIG, 0,
      lambda ctx, inst: [nic.network for nic in inst.nics]),
+    (_MakeField("nic.networks.names", "NIC_networks_names", QFT_OTHER,
+                "List containing each interface's network"),
+     IQ_NETWORKS, 0, _GetInstAllNicNetworkNames)
     ]
 
   # NICs by number
@@ -1721,6 +1780,9 @@ def _GetInstanceNetworkFields():
       (_MakeField("nic.network/%s" % i, "NicNetwork/%s" % i, QFT_TEXT,
                   "Network of %s network interface" % numtext),
        IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicNetwork)),
+      (_MakeField("nic.network.name/%s" % i, "NicNetworkName/%s" % i, QFT_TEXT,
+                  "Network name of %s network interface" % numtext),
+       IQ_NETWORKS, 0, _GetInstNic(i, _GetInstNicNetworkName)),
       ])
 
   aliases = [
@@ -2234,6 +2296,36 @@ def _BuildOsFields():
   return _PrepareFieldList(fields, [])
 
 
+class ExtStorageInfo(objects.ConfigObject):
+  __slots__ = [
+    "name",
+    "node_status",
+    "nodegroup_status",
+    "parameters",
+    ]
+
+
+def _BuildExtStorageFields():
+  """Builds list of fields for extstorage provider queries.
+
+  """
+  fields = [
+    (_MakeField("name", "Name", QFT_TEXT, "ExtStorage provider name"),
+     None, 0, _GetItemAttr("name")),
+    (_MakeField("node_status", "NodeStatus", QFT_OTHER,
+                "Status from node"),
+     None, 0, _GetItemAttr("node_status")),
+    (_MakeField("nodegroup_status", "NodegroupStatus", QFT_OTHER,
+                "Overall Nodegroup status"),
+     None, 0, _GetItemAttr("nodegroup_status")),
+    (_MakeField("parameters", "Parameters", QFT_OTHER,
+                "ExtStorage provider parameters"),
+     None, 0, _GetItemAttr("parameters")),
+    ]
+
+  return _PrepareFieldList(fields, [])
+
+
 def _JobUnavailInner(fn, ctx, (job_id, job)): # pylint: disable=W0613
   """Return L{_FS_UNAVAIL} if job is None.
 
@@ -2353,7 +2445,7 @@ def _GetExportName(_, (node_name, expname)): # pylint: disable=W0613
 
   """
   if expname is None:
-    return _FS_UNAVAIL
+    return _FS_NODATA
   else:
     return expname
 
@@ -2501,7 +2593,6 @@ _NETWORK_SIMPLE_FIELDS = {
   "network6": ("IPv6Subnet", QFT_OTHER, 0, "IPv6 subnet"),
   "gateway6": ("IPv6Gateway", QFT_OTHER, 0, "IPv6 gateway"),
   "mac_prefix": ("MacPrefix", QFT_OTHER, 0, "MAC address prefix"),
-  "network_type": ("NetworkType", QFT_OTHER, 0, "Network type"),
   "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Network"),
   "uuid": ("UUID", QFT_TEXT, 0, "Network UUID"),
   }
@@ -2540,7 +2631,7 @@ def _BuildNetworkFields():
   # Add simple fields
   fields.extend([
     (_MakeField(name, title, kind, doc),
-     NETQ_CONFIG, 0, _GetItemAttr(name))
+     NETQ_CONFIG, 0, _GetItemMaybeAttr(name))
      for (name, (title, kind, _, doc)) in _NETWORK_SIMPLE_FIELDS.items()])
 
   def _GetLength(getter):
@@ -2595,6 +2686,9 @@ GROUP_FIELDS = _BuildGroupFields()
 #: Fields available for operating system queries
 OS_FIELDS = _BuildOsFields()
 
+#: Fields available for extstorage provider queries
+EXTSTORAGE_FIELDS = _BuildExtStorageFields()
+
 #: Fields available for job queries
 JOB_FIELDS = _BuildJobFields()
 
@@ -2612,6 +2706,7 @@ ALL_FIELDS = {
   constants.QR_LOCK: LOCK_FIELDS,
   constants.QR_GROUP: GROUP_FIELDS,
   constants.QR_OS: OS_FIELDS,
+  constants.QR_EXTSTORAGE: EXTSTORAGE_FIELDS,
   constants.QR_JOB: JOB_FIELDS,
   constants.QR_EXPORT: EXPORT_FIELDS,
   constants.QR_NETWORK: NETWORK_FIELDS,