Commit 6f287cf3 authored by Iustin Pop's avatar Iustin Pop
Browse files

Add infrastructure for building numeric namefield filters

Currently, all the CLI helpers in and 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: default avatarIustin Pop <>
Reviewed-by: default avatarRené Nussbaumer <>
parent 09532dcc
......@@ -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,
if qfilter is None:
qfilter = namefilter
......@@ -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:
number = int(text)
except (TypeError, ValueError), err:
raise errors.OpPrereqError("Invalid integer passed: %s" % str(err),
return [OP_EQUAL, namefield, number]
elif _CheckGlobbing(text):
return [OP_REGEXP, namefield, utils.DnsNameGlobPattern(text)]
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)
result = None
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