# 02110-1301, USA.
-"""Module for query operations"""
+"""Module for query operations
+
+How it works:
+
+ - Add field definitions
+ - See how L{NODE_FIELDS} is built
+ - Each field gets:
+ - Query field definition (L{objects.QueryFieldDefinition}, use
+ L{_MakeField} for creating), containing:
+ - Name, must be lowercase and match L{FIELD_NAME_RE}
+ - Title for tables, must not contain whitespace and match
+ L{TITLE_RE}
+ - Value data type, e.g. L{constants.QFT_NUMBER}
+ - Data request type, see e.g. C{NQ_*}
+ - A retrieval function, see L{Query.__init__} for description
+ - Pass list of fields through L{_PrepareFieldList} for preparation and
+ checks
+ - Instantiate L{Query} with prepared field list definition and selected fields
+ - Call L{Query.RequestedData} to determine what data to collect/compute
+ - Call L{Query.Query} or L{Query.OldStyleQuery} with collected data and use
+ result
+ - Data container must support iteration using C{__iter__}
+ - Items are passed to retrieval functions and can have any format
+ - Call L{Query.GetFields} to get list of definitions for selected fields
+
+@attention: Retrieval functions must be idempotent. They can be called multiple
+ times, in any order and any number of times. This is important to keep in
+ mind for implementing filters in the future.
+
+"""
import logging
import operator
from ganeti import ht
+# Constants for requesting data from the caller/data provider. Each property
+# collected/computed separately by the data provider should have its own to
+# only collect the requested data and not more.
+
(NQ_CONFIG,
NQ_INST,
NQ_LIVE,
@type fields: list of tuples; (L{objects.QueryFieldDefinition}, data kind,
retrieval function)
- @param fields: List of fields
+ @param fields: List of fields, see L{Query.__init__} for a better description
@rtype: dict
@return: Field dictionary for L{Query}
"""
def __init__(self, nodes, live_data, master_name, node_to_primary,
- node_to_secondary, groups, oob_support):
+ node_to_secondary, groups, oob_support, cluster):
"""Initializes this class.
"""
self.node_to_secondary = node_to_secondary
self.groups = groups
self.oob_support = oob_support
+ self.cluster = cluster
# Used for individual rows
self.curlive_data = None
}
-def _GetNodeGroup(ctx, node):
+def _GetGroup(cb):
+ """Build function for calling another function with an node group.
+
+ @param cb: The callback to be called with the nodegroup
+
+ """
+ def fn(ctx, node):
+ """Get group data for a node.
+
+ @type ctx: L{NodeQueryData}
+ @type inst: L{objects.Node}
+ @param inst: Node object
+
+ """
+ ng = ctx.groups.get(node.group, None)
+ if ng is None:
+ # Nodes always have a group, or the configuration is corrupt
+ return (constants.QRFS_UNAVAIL, None)
+
+ return cb(ctx, node, ng)
+
+ return fn
+
+
+def _GetNodeGroup(ctx, node, ng): # pylint: disable-msg=W0613
"""Returns the name of a node's group.
@type ctx: L{NodeQueryData}
@type node: L{objects.Node}
@param node: Node object
+ @type ng: L{objects.NodeGroup}
+ @param ng: The node group this node belongs to
"""
- ng = ctx.groups.get(node.group, None)
- if ng is None:
- # Nodes always have a group, or the configuration is corrupt
- return (constants.QRFS_UNAVAIL, None)
-
return (constants.QRFS_NORMAL, ng.name)
return (constants.QRFS_UNAVAIL, None)
+def _GetNdParams(ctx, node, ng):
+ """Returns the ndparams for this node.
+
+ @type ctx: L{NodeQueryData}
+ @type node: L{objects.Node}
+ @param node: Node object
+ @type ng: L{objects.NodeGroup}
+ @param ng: The node group this node belongs to
+
+ """
+ return (constants.QRFS_NORMAL, ctx.cluster.SimpleFillND(ng.FillND(node)))
+
+
def _GetLiveNodeField(field, kind, ctx, node):
"""Gets the value of a "live" field from L{NodeQueryData}.
(_MakeField("role", "Role", constants.QFT_TEXT), NQ_CONFIG,
lambda ctx, node: (constants.QRFS_NORMAL,
_GetNodeRole(node, ctx.master_name))),
- (_MakeField("group", "Group", constants.QFT_TEXT), NQ_GROUP, _GetNodeGroup),
+ (_MakeField("group", "Group", constants.QFT_TEXT), NQ_GROUP,
+ _GetGroup(_GetNodeGroup)),
(_MakeField("group.uuid", "GroupUUID", constants.QFT_TEXT),
NQ_CONFIG, lambda ctx, node: (constants.QRFS_NORMAL, node.group)),
(_MakeField("powered", "Powered", constants.QFT_BOOL), NQ_OOB,
_GetNodePower),
+ (_MakeField("ndparams", "NodeParameters", constants.QFT_OTHER), NQ_GROUP,
+ _GetGroup(_GetNdParams)),
+ (_MakeField("custom_ndparams", "CustomNodeParameters", constants.QFT_OTHER),
+ NQ_GROUP, lambda ctx, node: (constants.QRFS_NORMAL, node.ndparams)),
]
def _GetLength(getter):
"name": ("Group", constants.QFT_TEXT),
"serial_no": ("SerialNo", constants.QFT_NUMBER),
"uuid": ("UUID", constants.QFT_TEXT),
+ "ndparams": ("NDParams", constants.QFT_OTHER),
}