mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-11 00:31:56 -06:00
cli: simplify parsing of arbitrary types
Add the 'constructor' type to IPAOption to allow parsing arbitrary types. When using this type, supply the 'constructor' attribute with the constructor of the type. The checker for the 'constructor' type attempts to construct the data, returning if successful else raising OptionValueError. The 'knob' interface remains unchanged but now accepts arbitrary constructors. This feature subsumes the '_option_callback' mechanism, which has been refactored away. This feature also subsumes the "dn" type in IPAOption, but this refactor is deferred. Part of: https://pagure.io/freeipa/issue/6858 Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
parent
7902fc9a06
commit
c5afee964e
@ -79,16 +79,28 @@ def check_dn_option(option, opt, value):
|
||||
except Exception as e:
|
||||
raise OptionValueError("option %s: invalid DN: %s" % (opt, e))
|
||||
|
||||
|
||||
def check_constructor(option, opt, value):
|
||||
con = option.constructor
|
||||
assert con is not None, "Oops! Developer forgot to set 'constructor' kwarg"
|
||||
try:
|
||||
return con(value)
|
||||
except Exception as e:
|
||||
raise OptionValueError("option {} invalid: {}".format(opt, e))
|
||||
|
||||
|
||||
class IPAOption(Option):
|
||||
"""
|
||||
optparse.Option subclass with support of options labeled as
|
||||
security-sensitive such as passwords.
|
||||
"""
|
||||
ATTRS = Option.ATTRS + ["sensitive"]
|
||||
TYPES = Option.TYPES + ("ip", "dn")
|
||||
ATTRS = Option.ATTRS + ["sensitive", "constructor"]
|
||||
TYPES = Option.TYPES + ("ip", "dn", "constructor")
|
||||
TYPE_CHECKER = copy(Option.TYPE_CHECKER)
|
||||
TYPE_CHECKER["ip"] = check_ip_option
|
||||
TYPE_CHECKER["dn"] = check_dn_option
|
||||
TYPE_CHECKER["constructor"] = check_constructor
|
||||
|
||||
|
||||
class IPAOptionParser(OptionParser):
|
||||
"""
|
||||
|
@ -8,7 +8,6 @@ Command line support.
|
||||
|
||||
import collections
|
||||
import enum
|
||||
import functools
|
||||
import logging
|
||||
import optparse # pylint: disable=deprecated-module
|
||||
import signal
|
||||
@ -105,17 +104,6 @@ def uninstall_tool(configurable_class, command_name, log_file_name,
|
||||
)
|
||||
|
||||
|
||||
def _option_callback(action, option, opt_str, value, parser, opt_type):
|
||||
try:
|
||||
value = opt_type(value)
|
||||
except ValueError as e:
|
||||
raise optparse.OptionValueError(
|
||||
"option {0}: {1}".format(opt_str, e))
|
||||
|
||||
option.take_action(
|
||||
action, option.dest, opt_str, value, parser.values, parser)
|
||||
|
||||
|
||||
class ConfigureTool(admintool.AdminTool):
|
||||
configurable_class = None
|
||||
debug_option = False
|
||||
@ -186,24 +174,16 @@ class ConfigureTool(admintool.AdminTool):
|
||||
kwargs['metavar'] = "{{{0}}}".format(
|
||||
",".join(kwargs['choices']))
|
||||
else:
|
||||
kwargs['nargs'] = 1
|
||||
kwargs['callback_args'] = (knob_scalar_type,)
|
||||
kwargs['type'] = 'constructor'
|
||||
kwargs['constructor'] = knob_scalar_type
|
||||
kwargs['dest'] = name
|
||||
if issubclass(knob_type, list):
|
||||
if 'type' not in kwargs:
|
||||
kwargs['action'] = 'callback'
|
||||
kwargs['callback'] = (
|
||||
functools.partial(_option_callback, 'append'))
|
||||
elif kwargs['type'] is None:
|
||||
if kwargs['type'] is None:
|
||||
kwargs['action'] = 'append_const'
|
||||
else:
|
||||
kwargs['action'] = 'append'
|
||||
else:
|
||||
if 'type' not in kwargs:
|
||||
kwargs['action'] = 'callback'
|
||||
kwargs['callback'] = (
|
||||
functools.partial(_option_callback, 'store'))
|
||||
elif kwargs['type'] is None:
|
||||
if kwargs['type'] is None:
|
||||
kwargs['action'] = 'store_const'
|
||||
else:
|
||||
kwargs['action'] = 'store'
|
||||
|
Loading…
Reference in New Issue
Block a user