From 6f287cf3c893e170a92957c6cf640248532d79dd Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Thu, 2 Aug 2012 13:29:04 +0200 Subject: [PATCH] Add infrastructure for building numeric namefield filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, all the CLI helpers in qlang.py and cli.py assume that all namefields are string, which leads to various breakage in case the're actually not. To improve the flexibility of the helpers, we add a bit of infrastructure for accepting so called "numeric" namefields; this is a bit of a hack, as a proper fix would actually add QFT_* support to the helpers, and case for example the regex/globbing on QFT_TEXT, etc. But that's left for (eventual) later improvement. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: RenΓ© Nussbaumer <rn@google.com> --- lib/cli.py | 9 +++++++-- lib/qlang.py | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/cli.py b/lib/cli.py index 885bd7005..f81f1aa29 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -2861,7 +2861,7 @@ def _WarnUnknownFields(fdefs): def GenericList(resource, fields, names, unit, separator, header, cl=None, format_override=None, verbose=False, force_filter=False, - namefield=None, qfilter=None): + namefield=None, qfilter=None, isnumeric=False): """Generic implementation for listing all items of a resource. @param resource: One of L{constants.QR_VIA_LUXI} @@ -2889,12 +2889,17 @@ def GenericList(resource, fields, names, unit, separator, header, cl=None, L{qlang.MakeFilter} for details) @type qfilter: list or None @param qfilter: Query filter (in addition to names) + @param isnumeric: bool + @param isnumeric: Whether the namefield's type is numeric, and therefore + any simple filters built by namefield should use integer values to + reflect that """ if not names: names = None - namefilter = qlang.MakeFilter(names, force_filter, namefield=namefield) + namefilter = qlang.MakeFilter(names, force_filter, namefield=namefield, + isnumeric=isnumeric) if qfilter is None: qfilter = namefilter diff --git a/lib/qlang.py b/lib/qlang.py index 3942b45c6..e52924337 100644 --- a/lib/qlang.py +++ b/lib/qlang.py @@ -290,17 +290,24 @@ def _CheckGlobbing(text): return bool(frozenset(text) & GLOB_DETECTION_CHARS) -def _MakeFilterPart(namefield, text): +def _MakeFilterPart(namefield, text, isnumeric=False): """Generates filter for one argument. """ - if _CheckGlobbing(text): + if isnumeric: + try: + number = int(text) + except (TypeError, ValueError), err: + raise errors.OpPrereqError("Invalid integer passed: %s" % str(err), + errors.ECODE_INVAL) + return [OP_EQUAL, namefield, number] + elif _CheckGlobbing(text): return [OP_REGEXP, namefield, utils.DnsNameGlobPattern(text)] else: return [OP_EQUAL, namefield, text] -def MakeFilter(args, force_filter, namefield=None): +def MakeFilter(args, force_filter, namefield=None, isnumeric=False): """Try to make a filter from arguments to a command. If the name could be a filter it is parsed as such. If it's just a globbing @@ -314,6 +321,9 @@ def MakeFilter(args, force_filter, namefield=None): @type namefield: string @param namefield: Name of field to use for simple filters (use L{None} for a default of "name") + @type isnumeric: bool + @param isnumeric: Whether the namefield type is numeric, as opposed to + the default string type; this influences how the filter is built @rtype: list @return: Query filter @@ -331,7 +341,8 @@ def MakeFilter(args, force_filter, namefield=None): result = ParseFilter(filter_text) elif args: - result = [OP_OR] + map(compat.partial(_MakeFilterPart, namefield), args) + result = [OP_OR] + map(compat.partial(_MakeFilterPart, namefield, + isnumeric=isnumeric), args) else: result = None -- GitLab