mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-24 16:10:02 -06:00
ipalib: introduce API schema plugins
Add a set of plugins for API schema introspection. This includes: * a set of commands for command introspection (`command_find`, `command_show`, `command_defaults`), * a set of commands for command param introspection (`param_find`, `param_show`), * a set of commands for command output introspection (`output_find`, `output_show`), * a set of commands for help topic introspection (`topic_find`, `topic_show`), * a command to get the full API schema in one call (`schema`). https://fedorahosted.org/freeipa/ticket/4739 Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
parent
3cf5f83d92
commit
f35beca68c
95
API.txt
95
API.txt
@ -757,6 +757,33 @@ option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: command_defaults
|
||||
args: 1,3,1
|
||||
arg: Str('name')
|
||||
option: Any('kw?')
|
||||
option: Str('params*')
|
||||
option: Str('version?')
|
||||
output: Output('result')
|
||||
command: command_find
|
||||
args: 1,4,4
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('pkey_only?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Output('count', type=[<type 'int'>])
|
||||
output: ListOfEntries('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('truncated', type=[<type 'bool'>])
|
||||
command: command_show
|
||||
args: 1,3,3
|
||||
arg: Str('name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: compat_is_enabled
|
||||
args: 0,1,1
|
||||
option: Str('version?')
|
||||
@ -3076,6 +3103,50 @@ option: Password('second_code', confirm=False)
|
||||
option: Str('user')
|
||||
option: Str('version?')
|
||||
output: Output('result')
|
||||
command: output_find
|
||||
args: 2,4,4
|
||||
arg: Str('commandname', cli_name='command')
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('pkey_only?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Output('count', type=[<type 'int'>])
|
||||
output: ListOfEntries('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('truncated', type=[<type 'bool'>])
|
||||
command: output_show
|
||||
args: 2,3,3
|
||||
arg: Str('commandname', cli_name='command')
|
||||
arg: Str('name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: param_find
|
||||
args: 2,4,4
|
||||
arg: Str('commandname', cli_name='command')
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('pkey_only?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Output('count', type=[<type 'int'>])
|
||||
output: ListOfEntries('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('truncated', type=[<type 'bool'>])
|
||||
command: param_show
|
||||
args: 2,3,3
|
||||
arg: Str('commandname', cli_name='command')
|
||||
arg: Str('name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: passwd
|
||||
args: 3,2,3
|
||||
arg: Str('principal', autofill=True, cli_name='user')
|
||||
@ -3656,6 +3727,10 @@ option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: schema
|
||||
args: 0,1,1
|
||||
option: Str('version?')
|
||||
output: Output('result')
|
||||
command: selfservice_add
|
||||
args: 1,5,3
|
||||
arg: Str('aciname', cli_name='name')
|
||||
@ -4870,6 +4945,26 @@ option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: topic_find
|
||||
args: 1,4,4
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('pkey_only?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Output('count', type=[<type 'int'>])
|
||||
output: ListOfEntries('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('truncated', type=[<type 'bool'>])
|
||||
command: topic_show
|
||||
args: 1,3,3
|
||||
arg: Str('name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: topologysegment_add
|
||||
args: 2,13,3
|
||||
arg: Str('topologysuffixcn', cli_name='topologysuffix')
|
||||
|
4
VERSION
4
VERSION
@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=172
|
||||
# Last change: ipalib: replace DeprecatedParam with `deprecated` Param argument
|
||||
IPA_API_VERSION_MINOR=173
|
||||
# Last change: ipalib: introduce API schema plugins
|
||||
|
660
ipalib/plugins/schema.py
Normal file
660
ipalib/plugins/schema.py
Normal file
@ -0,0 +1,660 @@
|
||||
#
|
||||
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import importlib
|
||||
import itertools
|
||||
import sys
|
||||
|
||||
import six
|
||||
|
||||
from ipalib import errors
|
||||
from ipalib.crud import PKQuery, Retrieve, Search
|
||||
from ipalib.frontend import Command, Method, Object
|
||||
from ipalib.output import Entry, ListOfEntries, ListOfPrimaryKeys, PrimaryKey
|
||||
from ipalib.parameters import Any, Bool, Flag, Int, Str
|
||||
from ipalib.plugable import Registry
|
||||
from ipalib.text import _
|
||||
from ipapython.version import API_VERSION
|
||||
|
||||
__doc__ = _("""
|
||||
API Schema
|
||||
""") + _("""
|
||||
Provides API introspection capabilities.
|
||||
""") + _("""
|
||||
EXAMPLES:
|
||||
""") + _("""
|
||||
Show user-find details:
|
||||
ipa command-show user-find
|
||||
""") + _("""
|
||||
Find user-find parameters:
|
||||
ipa param-find user-find
|
||||
""")
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
register = Registry()
|
||||
|
||||
|
||||
class BaseMetaObject(Object):
|
||||
takes_params = (
|
||||
Str(
|
||||
'name',
|
||||
label=_("Name"),
|
||||
primary_key=True,
|
||||
normalizer=lambda name: name.replace(u'-', u'_'),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'doc?',
|
||||
label=_("Documentation"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
)
|
||||
|
||||
def _get_obj(self, obj, **kwargs):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _retrieve(self, *args, **kwargs):
|
||||
raise NotImplementedError()
|
||||
|
||||
def retrieve(self, *args, **kwargs):
|
||||
obj = self._retrieve(*args, **kwargs)
|
||||
obj = self._get_obj(obj, **kwargs)
|
||||
return obj
|
||||
|
||||
def _search(self, *args, **kwargs):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _split_search_args(self, criteria=None):
|
||||
return [], criteria
|
||||
|
||||
def search(self, *args, **kwargs):
|
||||
args, criteria = self._split_search_args(*args)
|
||||
|
||||
result = self._search(*args, **kwargs)
|
||||
result = (self._get_obj(r, **kwargs) for r in result)
|
||||
|
||||
if criteria:
|
||||
criteria = criteria.lower()
|
||||
result = (r for r in result
|
||||
if (criteria in r['name'].lower() or
|
||||
criteria in r.get('doc', u'').lower()))
|
||||
|
||||
if not kwargs.get('all', False) and kwargs.get('pkey_only', False):
|
||||
result = ({'name': r['name']} for r in result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class BaseMetaRetrieve(Retrieve):
|
||||
def execute(self, *args, **options):
|
||||
obj = self.obj.retrieve(*args, **options)
|
||||
return dict(result=obj, value=args[-1])
|
||||
|
||||
|
||||
class BaseMetaSearch(Search):
|
||||
def get_options(self):
|
||||
for option in super(BaseMetaSearch, self).get_options():
|
||||
yield option
|
||||
|
||||
yield Flag(
|
||||
'pkey_only?',
|
||||
label=_("Primary key only"),
|
||||
doc=_("Results should contain primary key attribute only "
|
||||
"(\"%s\")") % 'name',
|
||||
)
|
||||
|
||||
def execute(self, criteria=None, **options):
|
||||
result = list(self.obj.search(criteria, **options))
|
||||
return dict(result=result, count=len(result), truncated=False)
|
||||
|
||||
|
||||
class MetaObject(BaseMetaObject):
|
||||
takes_params = BaseMetaObject.takes_params + (
|
||||
Str(
|
||||
'topic_topic?',
|
||||
label=_("Help topic"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class MetaRetrieve(BaseMetaRetrieve):
|
||||
pass
|
||||
|
||||
|
||||
class MetaSearch(BaseMetaSearch):
|
||||
pass
|
||||
|
||||
|
||||
@register()
|
||||
class command(MetaObject):
|
||||
takes_params = BaseMetaObject.takes_params + (
|
||||
Str(
|
||||
'args_param*',
|
||||
label=_("Arguments"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'options_param*',
|
||||
label=_("Options"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'output_params_param*',
|
||||
label=_("Output parameters"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'no_cli?',
|
||||
label=_("Exclude from CLI"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
)
|
||||
|
||||
def _get_obj(self, command, **kwargs):
|
||||
obj = dict()
|
||||
obj['name'] = unicode(command.name)
|
||||
|
||||
if command.doc:
|
||||
obj['doc'] = unicode(command.doc)
|
||||
|
||||
if command.topic:
|
||||
try:
|
||||
topic = self.api.Object.topic.retrieve(unicode(command.topic))
|
||||
except errors.NotFound:
|
||||
pass
|
||||
else:
|
||||
obj['topic_topic'] = topic['name']
|
||||
|
||||
if command.NO_CLI:
|
||||
obj['no_cli'] = True
|
||||
|
||||
if len(command.args):
|
||||
obj['args_param'] = tuple(unicode(n) for n in command.args)
|
||||
|
||||
if len(command.options):
|
||||
obj['options_param'] = tuple(
|
||||
unicode(n) for n in command.options if n != 'version')
|
||||
|
||||
if len(command.output_params):
|
||||
obj['output_params_param'] = tuple(
|
||||
unicode(n) for n in command.output_params
|
||||
if n not in command.params)
|
||||
|
||||
return obj
|
||||
|
||||
def _retrieve(self, name, **kwargs):
|
||||
try:
|
||||
return self.api.Command[name]
|
||||
except KeyError:
|
||||
raise errors.NotFound(
|
||||
reason=_("%(pkey)s: %(oname)s not found") % {
|
||||
'pkey': name, 'oname': self.name,
|
||||
}
|
||||
)
|
||||
|
||||
def _search(self, **kwargs):
|
||||
return self.api.Command()
|
||||
|
||||
|
||||
@register()
|
||||
class command_show(MetaRetrieve):
|
||||
__doc__ = _("Display information about a command.")
|
||||
|
||||
|
||||
@register()
|
||||
class command_find(MetaSearch):
|
||||
__doc__ = _("Search for commands.")
|
||||
|
||||
|
||||
@register()
|
||||
class command_defaults(PKQuery):
|
||||
NO_CLI = True
|
||||
|
||||
takes_options = (
|
||||
Str('params*'),
|
||||
Any('kw?'),
|
||||
)
|
||||
|
||||
def execute(self, name, **options):
|
||||
command = self.api.Command[name]
|
||||
|
||||
params = options.get('params', [])
|
||||
|
||||
kw = options.get('kw', {})
|
||||
if not isinstance(kw, dict):
|
||||
raise errors.ConversionError(name=name,
|
||||
error=_("must be a dictionary"))
|
||||
|
||||
result = command.get_default(**kw)
|
||||
result = {n: v for n, v in result.items() if n in params}
|
||||
|
||||
return dict(result=result)
|
||||
|
||||
|
||||
@register()
|
||||
class topic_(MetaObject):
|
||||
name = 'topic'
|
||||
|
||||
def __init__(self, api):
|
||||
super(topic_, self).__init__(api)
|
||||
self.__topics = None
|
||||
|
||||
def __get_topics(self):
|
||||
if self.__topics is None:
|
||||
topics = {}
|
||||
object.__setattr__(self, '_topic___topics', topics)
|
||||
|
||||
for command in self.api.Command():
|
||||
topic_name = command.topic
|
||||
|
||||
while topic_name is not None and topic_name not in topics:
|
||||
topic = topics[topic_name] = {'name': topic_name}
|
||||
|
||||
for package in self.api.packages:
|
||||
module_name = '.'.join((package.__name__, topic_name))
|
||||
try:
|
||||
module = sys.modules[module_name]
|
||||
except KeyError:
|
||||
try:
|
||||
module = importlib.import_module(module_name)
|
||||
except ImportError:
|
||||
continue
|
||||
|
||||
if module.__doc__ is not None:
|
||||
topic['doc'] = unicode(module.__doc__).strip()
|
||||
|
||||
try:
|
||||
topic_name = module.topic
|
||||
except AttributeError:
|
||||
topic_name = None
|
||||
else:
|
||||
topic['topic_topic'] = topic_name
|
||||
|
||||
return self.__topics
|
||||
|
||||
def _get_obj(self, topic, **kwargs):
|
||||
return topic
|
||||
|
||||
def _retrieve(self, name, **kwargs):
|
||||
try:
|
||||
return self.__get_topics()[name]
|
||||
except KeyError:
|
||||
raise errors.NotFound(
|
||||
reason=_("%(pkey)s: %(oname)s not found") % {
|
||||
'pkey': name, 'oname': self.name,
|
||||
}
|
||||
)
|
||||
|
||||
def _search(self, **kwargs):
|
||||
return self.__get_topics().values()
|
||||
|
||||
|
||||
@register()
|
||||
class topic_show(MetaRetrieve):
|
||||
__doc__ = _("Display information about a help topic.")
|
||||
|
||||
|
||||
@register()
|
||||
class topic_find(MetaSearch):
|
||||
__doc__ = _("Search for help topics.")
|
||||
|
||||
|
||||
class BaseParam(BaseMetaObject):
|
||||
takes_params = BaseMetaObject.takes_params + (
|
||||
Str(
|
||||
'type?',
|
||||
label=_("Type"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'required?',
|
||||
label=_("Required"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'multivalue?',
|
||||
label=_("Multi-value"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
)
|
||||
|
||||
def _split_search_args(self, commandname, criteria=None):
|
||||
return [commandname], criteria
|
||||
|
||||
|
||||
class BaseParamMethod(Method):
|
||||
def get_args(self):
|
||||
parent = self.api.Object.command
|
||||
parent_key = parent.primary_key
|
||||
yield parent_key.clone_rename(
|
||||
parent.name + parent_key.name,
|
||||
cli_name=parent.name,
|
||||
label=parent_key.label,
|
||||
required=True,
|
||||
query=True,
|
||||
)
|
||||
|
||||
for arg in super(BaseParamMethod, self).get_args():
|
||||
yield arg
|
||||
|
||||
|
||||
class BaseParamRetrieve(BaseParamMethod, BaseMetaRetrieve):
|
||||
pass
|
||||
|
||||
|
||||
class BaseParamSearch(BaseParamMethod, BaseMetaSearch):
|
||||
pass
|
||||
|
||||
|
||||
@register()
|
||||
class param(BaseParam):
|
||||
takes_params = BaseParam.takes_params + (
|
||||
Bool(
|
||||
'alwaysask?',
|
||||
label=_("Always ask"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'autofill?',
|
||||
label=_("Autofill"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'cli_metavar?',
|
||||
label=_("CLI metavar"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'cli_name?',
|
||||
label=_("CLI name"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'confirm',
|
||||
label=_("Confirm (password)"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'default*',
|
||||
label=_("Default"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'default_from_param*',
|
||||
label=_("Default from"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'deprecated_cli_aliases*',
|
||||
label=_("Deprecated CLI aliases"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'exclude*',
|
||||
label=_("Exclude from"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'hint?',
|
||||
label=_("Hint"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'include*',
|
||||
label=_("Include in"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'label?',
|
||||
label=_("Label"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'no_convert?',
|
||||
label=_("Convert on server"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Str(
|
||||
'option_group?',
|
||||
label=_("Option group"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Int(
|
||||
'sortorder?',
|
||||
label=_("Sort order"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'dnsrecord_extra?',
|
||||
label=_("Extra field (DNS record)"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'dnsrecord_part?',
|
||||
label=_("Part (DNS record)"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'no_option?',
|
||||
label=_("No option"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'suppress_empty?',
|
||||
label=_("Suppress empty"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
Bool(
|
||||
'sensitive?',
|
||||
label=_("Sensitive"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
)
|
||||
|
||||
def _get_obj(self, param, **kwargs):
|
||||
obj = dict()
|
||||
obj['name'] = unicode(param.name)
|
||||
|
||||
if param.type is unicode:
|
||||
obj['type'] = u'str'
|
||||
elif param.type is bytes:
|
||||
obj['type'] = u'bytes'
|
||||
elif param.type is not None:
|
||||
obj['type'] = unicode(param.type.__name__)
|
||||
|
||||
if not param.required:
|
||||
obj['required'] = False
|
||||
if param.multivalue:
|
||||
obj['multivalue'] = True
|
||||
if param.password:
|
||||
obj['sensitive'] = True
|
||||
|
||||
for key, value in param._Param__clonekw.items():
|
||||
if key in ('alwaysask',
|
||||
'autofill',
|
||||
'confirm',
|
||||
'sortorder'):
|
||||
obj[key] = value
|
||||
elif key in ('cli_metavar',
|
||||
'cli_name',
|
||||
'doc',
|
||||
'hint',
|
||||
'label',
|
||||
'option_group'):
|
||||
obj[key] = unicode(value)
|
||||
elif key == 'default':
|
||||
if param.multivalue:
|
||||
obj[key] = [unicode(v) for v in value]
|
||||
else:
|
||||
obj[key] = [unicode(value)]
|
||||
elif key == 'default_from':
|
||||
obj['default_from_param'] = list(unicode(k)
|
||||
for k in value.keys)
|
||||
elif key in ('deprecated_cli_aliases',
|
||||
'exclude',
|
||||
'include'):
|
||||
obj[key] = list(unicode(v) for v in value)
|
||||
elif key in ('exponential',
|
||||
'normalizer',
|
||||
'only_absolute',
|
||||
'precision'):
|
||||
obj['no_convert'] = True
|
||||
|
||||
for flag in (param.flags or []):
|
||||
if flag in ('dnsrecord_extra',
|
||||
'dnsrecord_part',
|
||||
'no_option',
|
||||
'suppress_empty'):
|
||||
obj[flag] = True
|
||||
|
||||
return obj
|
||||
|
||||
def _retrieve(self, commandname, name, **kwargs):
|
||||
command = self.api.Command[commandname]
|
||||
|
||||
if name != 'version':
|
||||
try:
|
||||
return command.params[name]
|
||||
except KeyError:
|
||||
try:
|
||||
return command.output_params[name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
raise errors.NotFound(
|
||||
reason=_("%(pkey)s: %(oname)s not found") % {
|
||||
'pkey': name, 'oname': self.name,
|
||||
}
|
||||
)
|
||||
|
||||
def _search(self, commandname, **kwargs):
|
||||
command = self.api.Command[commandname]
|
||||
|
||||
result = itertools.chain(
|
||||
(p for p in command.params() if p.name != 'version'),
|
||||
(p for p in command.output_params()
|
||||
if p.name not in command.params))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@register()
|
||||
class param_show(BaseParamRetrieve):
|
||||
__doc__ = _("Display information about a command parameter.")
|
||||
|
||||
|
||||
@register()
|
||||
class param_find(BaseParamSearch):
|
||||
__doc__ = _("Search command parameters.")
|
||||
|
||||
|
||||
@register()
|
||||
class output(BaseParam):
|
||||
takes_params = BaseParam.takes_params + (
|
||||
Bool(
|
||||
'no_display?',
|
||||
label=_("Do not display"),
|
||||
flags={'no_search'},
|
||||
),
|
||||
)
|
||||
|
||||
def _get_obj(self, command_output, **kwargs):
|
||||
command, output = command_output
|
||||
required = True
|
||||
multivalue = False
|
||||
|
||||
if isinstance(output, (Entry, ListOfEntries)):
|
||||
type_type = dict
|
||||
multivalue = isinstance(output, ListOfEntries)
|
||||
elif isinstance(output, (PrimaryKey, ListOfPrimaryKeys)):
|
||||
if getattr(command, 'obj', None) and command.obj.primary_key:
|
||||
type_type = command.obj.primary_key.type
|
||||
else:
|
||||
type_type = type(None)
|
||||
multivalue = isinstance(output, ListOfPrimaryKeys)
|
||||
elif isinstance(output.type, tuple):
|
||||
if tuple in output.type or list in output.type:
|
||||
type_type = None
|
||||
multivalue = True
|
||||
else:
|
||||
type_type = output.type[0]
|
||||
required = type(None) not in output.type
|
||||
else:
|
||||
type_type = output.type
|
||||
|
||||
obj = dict()
|
||||
obj['name'] = unicode(output.name)
|
||||
|
||||
if type_type is unicode:
|
||||
obj['type'] = u'str'
|
||||
elif type_type is bytes:
|
||||
obj['type'] = u'bytes'
|
||||
elif type_type is not None:
|
||||
obj['type'] = unicode(type_type.__name__)
|
||||
|
||||
if not required:
|
||||
obj['required'] = False
|
||||
|
||||
if multivalue:
|
||||
obj['multivalue'] = True
|
||||
|
||||
if 'doc' in output.__dict__:
|
||||
obj['doc'] = unicode(output.doc)
|
||||
|
||||
if 'flags' in output.__dict__:
|
||||
if 'no_display' in output.flags:
|
||||
obj['no_display'] = True
|
||||
|
||||
return obj
|
||||
|
||||
def _retrieve(self, commandname, name, **kwargs):
|
||||
command = self.api.Command[commandname]
|
||||
try:
|
||||
return (command, command.output[name])
|
||||
except KeyError:
|
||||
raise errors.NotFound(
|
||||
reason=_("%(pkey)s: %(oname)s not found") % {
|
||||
'pkey': name, 'oname': self.name,
|
||||
}
|
||||
)
|
||||
|
||||
def _search(self, commandname, **kwargs):
|
||||
command = self.api.Command[commandname]
|
||||
return ((command, output) for output in command.output())
|
||||
|
||||
|
||||
@register()
|
||||
class output_show(BaseParamRetrieve):
|
||||
__doc__ = _("Display information about a command output.")
|
||||
|
||||
|
||||
@register()
|
||||
class output_find(BaseParamSearch):
|
||||
__doc__ = _("Search for command outputs.")
|
||||
|
||||
|
||||
@register()
|
||||
class schema(Command):
|
||||
NO_CLI = True
|
||||
|
||||
def execute(self, *args, **kwargs):
|
||||
commands = list(self.api.Object.command.search(**kwargs))
|
||||
for command in commands:
|
||||
name = command['name']
|
||||
command['params'] = list(
|
||||
self.api.Object.param.search(name, **kwargs))
|
||||
command['output'] = list(
|
||||
self.api.Object.output.search(name, **kwargs))
|
||||
|
||||
topics = list(self.api.Object.topic.search(**kwargs))
|
||||
|
||||
schema = dict()
|
||||
schema['version'] = API_VERSION
|
||||
schema['commands'] = commands
|
||||
schema['topics'] = topics
|
||||
|
||||
return dict(result=schema)
|
Loading…
Reference in New Issue
Block a user