From c1912a48875ae86b13286827e4df885911e5c1d0 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Fri, 21 Dec 2012 14:44:52 +0100 Subject: [PATCH] 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: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/cli.py | 29 ++++++++++++++++++++++++++++- test/ganeti.cli_unittest.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/cli.py b/lib/cli.py index 0162bddd1..9a258f453 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -315,6 +315,17 @@ TISPECS_CLUSTER_TYPES = { constants.ISPECS_STD: constants.VTYPE_INT, } +#: User-friendly names for query2 field types +_QFT_NAMES = { + 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 [ + fdef.name, + _QFT_NAMES.get(fdef.kind, fdef.kind), + fdef.title, + fdef.doc, + ] + + 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.name, fdef.title, fdef.doc] for fdef in response.fields] + rows = map(_FieldDescValues, response.fields) for line in FormatTable(rows, columns, header, separator): ToStdout(line) diff --git a/test/ganeti.cli_unittest.py b/test/ganeti.cli_unittest.py index 5cb486953..3ebde5fe0 100755 --- a/test/ganeti.cli_unittest.py +++ b/test/ganeti.cli_unittest.py @@ -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()) + self.assertFalse(utils.FindDuplicates(lcnames)) + + 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", + title="Atitle", + kind=constants.QFT_TEXT, + doc="aaa doc aaa") + self.assertEqual(cli._FieldDescValues(fdef), + ["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") + self.assertEqual(cli._FieldDescValues(fdef), + ["zname", kind, "Ztitle", "zzz doc zzz"]) + + if __name__ == "__main__": testutils.GanetiTestProgram() -- GitLab