Makefile: Fix list of directories
[ganeti-local] / lib / query.py
index 7efdaa4..dc07159 100644 (file)
@@ -137,7 +137,12 @@ _FS_UNAVAIL = object()
 _FS_OFFLINE = object()
 
 #: List of all special status
-_FS_ALL = frozenset([_FS_UNKNOWN, _FS_NODATA, _FS_UNAVAIL, _FS_OFFLINE])
+_FS_ALL = compat.UniqueFrozenset([
+  _FS_UNKNOWN,
+  _FS_NODATA,
+  _FS_UNAVAIL,
+  _FS_OFFLINE,
+  ])
 
 #: VType to QFT mapping
 _VTToQFT = {
@@ -1229,8 +1234,24 @@ def _GetLiveNodeField(field, kind, ctx, node):
   if not ctx.curlive_data:
     return _FS_NODATA
 
+  return _GetStatsField(field, kind, ctx.curlive_data)
+
+
+def _GetStatsField(field, kind, data):
+  """Gets a value from live statistics.
+
+  If the value is not found, L{_FS_UNAVAIL} is returned. If the field kind is
+  numeric a conversion to integer is attempted. If that fails, L{_FS_UNAVAIL}
+  is returned.
+
+  @param field: Live field name
+  @param kind: Data kind, one of L{constants.QFT_ALL}
+  @type data: dict
+  @param data: Statistics
+
+  """
   try:
-    value = ctx.curlive_data[field]
+    value = data[field]
   except KeyError:
     return _FS_UNAVAIL
 
@@ -1244,7 +1265,7 @@ def _GetLiveNodeField(field, kind, ctx, node):
     return int(value)
   except (ValueError, TypeError):
     logging.exception("Failed to convert node field '%s' (value %r) to int",
-                      value, field)
+                      field, value)
     return _FS_UNAVAIL
 
 
@@ -2213,6 +2234,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.
 
@@ -2474,25 +2525,25 @@ class NetworkQueryData:
 
 
 _NETWORK_SIMPLE_FIELDS = {
-  "name": ("Network", QFT_TEXT, 0, "The network"),
-  "network": ("Subnet", QFT_TEXT, 0, "The subnet"),
-  "gateway": ("Gateway", QFT_OTHER, 0, "The gateway"),
-  "network6": ("IPv6Subnet", QFT_OTHER, 0, "The ipv6 subnet"),
-  "gateway6": ("IPv6Gateway", QFT_OTHER, 0, "The ipv6 gateway"),
-  "mac_prefix": ("MacPrefix", QFT_OTHER, 0, "The mac prefix"),
-  "network_type": ("NetworkType", QFT_OTHER, 0, "The network type"),
+  "name": ("Network", QFT_TEXT, 0, "Name"),
+  "network": ("Subnet", QFT_TEXT, 0, "IPv4 subnet"),
+  "gateway": ("Gateway", QFT_OTHER, 0, "IPv4 gateway"),
+  "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"),
   }
 
 
 _NETWORK_STATS_FIELDS = {
-  "free_count": ("FreeCount", QFT_NUMBER, 0, "How many addresses are free"),
-  "reserved_count": ("ReservedCount", QFT_NUMBER, 0,
-                     "How many addresses are reserved"),
-  "map": ("Map", QFT_TEXT, 0, "The actual mapping"),
-  "external_reservations": ("ExternalReservations", QFT_TEXT, 0,
-                            "The external reservations"),
+  "free_count": ("FreeCount", QFT_NUMBER, 0, "Number of available addresses"),
+  "reserved_count":
+    ("ReservedCount", QFT_NUMBER, 0, "Number of reserved addresses"),
+  "map": ("Map", QFT_TEXT, 0, "Actual mapping"),
+  "external_reservations":
+    ("ExternalReservations", QFT_TEXT, 0, "External reservations"),
   }
 
 
@@ -2504,24 +2555,7 @@ def _GetNetworkStatsField(field, kind, ctx, _):
   @type ctx: L{NetworkQueryData}
 
   """
-
-  try:
-    value = ctx.curstats[field]
-  except KeyError:
-    return _FS_UNAVAIL
-
-  if kind == QFT_TEXT:
-    return value
-
-  assert kind in (QFT_NUMBER, QFT_UNIT)
-
-  # Try to convert into number
-  try:
-    return int(value)
-  except (ValueError, TypeError):
-    logging.exception("Failed to convert network field '%s' (value %r) to int",
-                      field, value)
-    return _FS_UNAVAIL
+  return _GetStatsField(field, kind, ctx.curstats)
 
 
 def _BuildNetworkFields():
@@ -2552,8 +2586,9 @@ def _BuildNetworkFields():
   fields.extend([
     (_MakeField("group_cnt", "NodeGroups", QFT_NUMBER, "Number of nodegroups"),
      NETQ_GROUP, 0, _GetLength(network_to_groups)),
-    (_MakeField("group_list", "GroupList", QFT_OTHER, "List of nodegroups"),
-     NETQ_GROUP, 0, _GetSortedList(network_to_groups)),
+    (_MakeField("group_list", "GroupList", QFT_OTHER,
+     "List of nodegroups (group name, NIC mode, NIC link)"),
+     NETQ_GROUP, 0, lambda ctx, network: network_to_groups(ctx)[network.uuid]),
     ])
 
   # Add fields for instances
@@ -2590,6 +2625,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()
 
@@ -2607,6 +2645,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,