Commit c1912a48 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

gnt-* list-fields: Show friendly field type

For people writing query filters (documented in ganeti(7)) knowing a field's
type can be useful.

$ gnt-instance list-fields name be/memory
Name      Type         Title        Description
name      Text         Instance     Instance name
be/memory Storage size ConfigMaxMem The "maxmem" backend parameter
Signed-off-by: default avatarMichael Hanselmann <>
Reviewed-by: default avatarIustin Pop <>
parent 5ff543c3
......@@ -315,6 +315,17 @@ TISPECS_CLUSTER_TYPES = {
constants.ISPECS_STD: constants.VTYPE_INT,
#: User-friendly names for query2 field types
constants.QFT_UNKNOWN: "Unknown",
constants.QFT_TEXT: "Text",
constants.QFT_BOOL: "Boolean",
constants.QFT_NUMBER: "Number",
constants.QFT_UNIT: "Storage size",
constants.QFT_TIMESTAMP: "Timestamp",
constants.QFT_OTHER: "Custom",
class _Argument:
def __init__(self, min=0, max=None): # pylint: disable=W0622
......@@ -3064,6 +3075,21 @@ def GenericList(resource, fields, names, unit, separator, header, cl=None,
return constants.EXIT_SUCCESS
def _FieldDescValues(fdef):
"""Helper function for L{GenericListFields} to get query field description.
@type fdef: L{objects.QueryFieldDefinition}
@rtype: list
return [,
_QFT_NAMES.get(fdef.kind, fdef.kind),
def GenericListFields(resource, fields, separator, header, cl=None):
"""Generic implementation for listing fields for a resource.
......@@ -3088,11 +3114,12 @@ def GenericListFields(resource, fields, separator, header, cl=None):
columns = [
TableColumn("Name", str, False),
TableColumn("Type", str, False),
TableColumn("Title", str, False),
TableColumn("Description", str, False),
rows = [[, fdef.title, fdef.doc] for fdef in response.fields]
rows = map(_FieldDescValues, response.fields)
for line in FormatTable(rows, columns, header, separator):
......@@ -1010,5 +1010,39 @@ class TestParseArgs(unittest.TestCase):
["test", "list"], cmd, aliases, set())
class TestQftNames(unittest.TestCase):
def testComplete(self):
self.assertEqual(frozenset(cli._QFT_NAMES), constants.QFT_ALL)
def testUnique(self):
lcnames = map(lambda s: s.lower(), cli._QFT_NAMES.values())
def testUppercase(self):
for name in cli._QFT_NAMES.values():
self.assertEqual(name[0], name[0].upper())
class TestFieldDescValues(unittest.TestCase):
def testKnownKind(self):
fdef = objects.QueryFieldDefinition(name="aname",
doc="aaa doc aaa")
["aname", "Text", "Atitle", "aaa doc aaa"])
def testUnknownKind(self):
kind = "#foo#"
self.assertFalse(kind in constants.QFT_ALL)
self.assertFalse(kind in cli._QFT_NAMES)
fdef = objects.QueryFieldDefinition(name="zname", title="Ztitle",
kind=kind, doc="zzz doc zzz")
["zname", kind, "Ztitle", "zzz doc zzz"])
if __name__ == "__main__":
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment