summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2012-06-21 08:20:26 -0400
committerMartin Kosek <mkosek@redhat.com>2013-02-21 16:26:09 +0100
commit7336a176b43989b9d459a2536af88f89e849213f (patch)
tree46c2ab141dc545e8f0c148871508fe7c952d22e5
parent246bc3f3eaccf2a84310df84dc85fe455c24ac65 (diff)
downloadfreeipa.git-7336a176b43989b9d459a2536af88f89e849213f.tar.gz
freeipa.git-7336a176b43989b9d459a2536af88f89e849213f.tar.xz
freeipa.git-7336a176b43989b9d459a2536af88f89e849213f.zip
Add the version option to all Commands
Several Commands were missing the 'version' option. Add it to those that were missing it. Do not remove the version option before calling commands. This means methods such as execute(), forward(), run() receive it. Several of these needed `**options` added to their signatures. Commands in the Cert plugin passed any unknown options to the underlying functions, these are changed to pass what's needed explicitly. Some commands in DNS and Batch plugins now pass version to commands they call. When the option is not given, fill it in automatically. (In a subsequent commit, a warning will be added in this case). Note that the public API did not change: all RPC calls already accepted a version option. There's no need for an API version bump (even though API.txt changes substantially). Design page: http://freeipa.org/page/V3/Messages Tickets: https://fedorahosted.org/freeipa/ticket/2732 https://fedorahosted.org/freeipa/ticket/3294
-rw-r--r--API.txt204
-rw-r--r--doc/examples/examples.py2
-rw-r--r--ipalib/__init__.py51
-rw-r--r--ipalib/cli.py4
-rw-r--r--ipalib/frontend.py18
-rw-r--r--ipalib/plugins/aci.py2
-rw-r--r--ipalib/plugins/automount.py2
-rw-r--r--ipalib/plugins/batch.py1
-rw-r--r--ipalib/plugins/cert.py12
-rw-r--r--ipalib/plugins/dns.py4
-rw-r--r--ipalib/plugins/hbacrule.py4
-rw-r--r--ipalib/plugins/internal.py2
-rw-r--r--ipalib/plugins/passwd.py2
-rw-r--r--ipalib/plugins/ping.py2
-rw-r--r--ipalib/plugins/selinuxusermap.py4
-rw-r--r--ipalib/plugins/sudorule.py4
-rw-r--r--tests/test_ipalib/test_backend.py16
-rw-r--r--tests/test_ipalib/test_crud.py4
-rw-r--r--tests/test_ipalib/test_frontend.py58
-rw-r--r--tests/test_xmlrpc/test_cert_plugin.py (renamed from tests/test_xmlrpc/test_cert.py)0
20 files changed, 243 insertions, 153 deletions
diff --git a/API.txt b/API.txt
index 9437cd4b..a5eaaa83 100644
--- a/API.txt
+++ b/API.txt
@@ -20,9 +20,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: aci_del
-args: 1,1,3
+args: 1,2,3
arg: Str('aciname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: StrEnum('aciprefix', cli_name='prefix', values=(u'permission', u'delegation', u'selfservice', u'none'))
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -160,9 +161,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: automember_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', cli_name='automember_rule')
option: StrEnum('type', values=(u'group', u'hostgroup'))
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -234,12 +236,13 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: automountkey_del
-args: 2,3,3
+args: 2,4,3
arg: Str('automountlocationcn', cli_name='automountlocation', query=True, required=True)
arg: IA5Str('automountmapautomountmapname', cli_name='automountmap', query=True, required=True)
option: IA5Str('automountinformation?', cli_name='info')
option: IA5Str('automountkey', cli_name='key')
option: Flag('continue', autofill=True, cli_name='continue', default=False, exclude='webui', multivalue=False, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -302,9 +305,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: automountlocation_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='location', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -323,10 +327,11 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('truncated', <type 'bool'>, None)
command: automountlocation_import
-args: 2,1,1
+args: 2,2,1
arg: Str('cn', attribute=True, cli_name='location', multivalue=False, primary_key=True, query=True, required=True)
arg: Str('masterfile')
option: Flag('continue?', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: automountlocation_show
args: 1,4,3
@@ -339,8 +344,9 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: automountlocation_tofiles
-args: 1,0,1
+args: 1,1,1
arg: Str('cn', attribute=True, cli_name='location', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: automountmap_add
args: 2,6,3
@@ -371,10 +377,11 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: automountmap_del
-args: 2,1,3
+args: 2,2,3
arg: Str('automountlocationcn', cli_name='automountlocation', query=True, required=True)
arg: IA5Str('automountmapname', attribute=True, cli_name='map', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -421,8 +428,9 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: batch
-args: 1,0,2
+args: 1,1,2
arg: Any('methods*')
+option: Str('version?', exclude='webui')
output: Output('count', <type 'int'>, None)
output: Output('results', (<type 'list'>, <type 'tuple'>), None)
command: cert_find
@@ -449,29 +457,34 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('truncated', <type 'bool'>, None)
command: cert_remove_hold
-args: 1,0,1
+args: 1,1,1
arg: Str('serial_number')
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: cert_request
-args: 1,3,1
+args: 1,4,1
arg: File('csr', cli_name='csr_file')
option: Flag('add', autofill=True, default=False)
option: Str('principal')
option: Str('request_type', autofill=True, default=u'pkcs10')
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
command: cert_revoke
-args: 1,1,1
+args: 1,2,1
arg: Str('serial_number')
option: Int('revocation_reason', autofill=True, default=0, maxvalue=10, minvalue=0)
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: cert_show
-args: 1,1,1
+args: 1,2,1
arg: Str('serial_number')
option: Str('out?', exclude='webui')
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: cert_status
-args: 1,0,1
+args: 1,1,1
arg: Str('request_id')
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: config_mod
args: 0,24,3
@@ -525,9 +538,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: cosentry_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='cn', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -586,8 +600,9 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: delegation_del
-args: 1,0,3
+args: 1,1,3
arg: Str('aciname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -630,13 +645,15 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dns_is_enabled
-args: 0,0,3
+args: 0,1,3
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dns_resolve
-args: 1,0,3
+args: 1,1,3
arg: Str('hostname')
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -837,10 +854,11 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dnsrecord_delentry
-args: 2,1,3
+args: 2,2,3
arg: Str('dnszoneidnsname', cli_name='dnszone', query=True, required=True)
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1062,27 +1080,31 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dnszone_add_permission
-args: 1,0,3
+args: 1,1,3
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dnszone_del
-args: 1,1,3
+args: 1,2,3
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dnszone_disable
-args: 1,0,3
+args: 1,1,3
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dnszone_enable
-args: 1,0,3
+args: 1,1,3
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1151,8 +1173,9 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: dnszone_remove_permission
-args: 1,0,3
+args: 1,1,3
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1198,11 +1221,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('truncated', <type 'bool'>, None)
command: entitle_import
-args: 1,3,1
+args: 1,4,1
arg: File('usercertificate*', cli_name='certificate_file')
option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
option: Str('uuid?', autofill=True, default=u'IMPORTED')
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
command: entitle_register
args: 1,7,3
@@ -1218,7 +1242,8 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: entitle_status
-args: 0,0,1
+args: 0,1,1
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
command: entitle_sync
args: 0,4,3
@@ -1230,10 +1255,11 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: env
-args: 1,2,4
+args: 1,3,4
arg: Str('variables*')
option: Flag('all', autofill=True, cli_name='all', default=True, exclude='webui')
option: Flag('server?', autofill=True, default=False)
+option: Str('version?', exclude='webui')
output: Output('count', <type 'int'>, None)
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
@@ -1266,15 +1292,17 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: group_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='group_name', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: group_detach
-args: 1,0,3
+args: 1,1,3
arg: Str('cn', attribute=True, cli_name='group_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1413,21 +1441,24 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: hbacrule_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: hbacrule_disable
-args: 1,0,3
+args: 1,1,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: hbacrule_enable
-args: 1,0,3
+args: 1,1,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1541,9 +1572,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: hbacsvc_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='service', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1609,9 +1641,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: hbacsvcgroup_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1665,7 +1698,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: hbactest
-args: 0,9,6
+args: 0,10,6
option: Flag('disabled?', autofill=True, cli_name='disabled', default=False)
option: Flag('enabled?', autofill=True, cli_name='enabled', default=False)
option: Flag('nodetail?', autofill=True, cli_name='nodetail', default=False)
@@ -1675,6 +1708,7 @@ option: Int('sizelimit?', autofill=False, minvalue=0)
option: Str('sourcehost?', cli_name='srchost')
option: Str('targethost', cli_name='host')
option: Str('user', cli_name='user', primary_key=True)
+option: Str('version?', exclude='webui')
output: Output('error', (<type 'list'>, <type 'tuple'>, <type 'NoneType'>), None)
output: Output('matched', (<type 'list'>, <type 'tuple'>, <type 'NoneType'>), None)
output: Output('notmatched', (<type 'list'>, <type 'tuple'>, <type 'NoneType'>), None)
@@ -1716,15 +1750,17 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: host_del
-args: 1,1,3
+args: 1,2,3
arg: Str('fqdn', attribute=True, cli_name='hostname', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('updatedns?', autofill=True, default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: host_disable
-args: 1,0,3
+args: 1,1,3
arg: Str('fqdn', attribute=True, cli_name='hostname', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1836,9 +1872,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: hostgroup_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='hostgroup_name', multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*$', primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1905,7 +1942,8 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: i18n_messages
-args: 0,0,1
+args: 0,1,1
+option: Str('version?', exclude='webui')
output: Output('messages', <type 'dict'>, None)
command: idrange_add
args: 1,12,3
@@ -1926,9 +1964,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: idrange_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -1983,12 +2022,13 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: json_metadata
-args: 2,3,3
+args: 2,4,3
arg: Str('objname?')
arg: Str('methodname?')
option: Str('command?')
option: Str('method?')
option: Str('object?')
+option: Str('version?', exclude='webui')
output: Output('commands', <type 'dict'>, None)
output: Output('methods', <type 'dict'>, None)
output: Output('objects', <type 'dict'>, None)
@@ -2027,7 +2067,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: migrate_ds
-args: 2,16,4
+args: 2,17,4
arg: Str('ldapuri', cli_name='ldap_uri')
arg: Password('bindpw', cli_name='password', confirm=False)
option: DNParam('basedn?', cli_name='base_dn')
@@ -2046,6 +2086,7 @@ option: DNParam('usercontainer', autofill=True, cli_name='user_container', defau
option: Str('userignoreattribute*', autofill=True, cli_name='user_ignore_attribute', csv=True, default=())
option: Str('userignoreobjectclass*', autofill=True, cli_name='user_ignore_objectclass', csv=True, default=())
option: Str('userobjectclass+', autofill=True, cli_name='user_objectclass', csv=True, default=(u'person',))
+option: Str('version?', exclude='webui')
output: Output('compat', <type 'bool'>, None)
output: Output('enabled', <type 'bool'>, None)
output: Output('failed', <type 'dict'>, None)
@@ -2081,9 +2122,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: netgroup_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*$', primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2164,10 +2206,11 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: passwd
-args: 3,0,3
+args: 3,1,3
arg: Str('principal', autofill=True, cli_name='user', primary_key=True)
arg: Password('password')
arg: Password('current_password', autofill=True, confirm=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2210,10 +2253,11 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: permission_del
-args: 1,2,3
+args: 1,3,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, pattern='^[-_ a-zA-Z0-9]+$', primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
option: Flag('force', autofill=True, default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2280,16 +2324,19 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: ping
-args: 0,0,1
+args: 0,1,1
+option: Str('version?', exclude='webui')
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
command: pkinit_anonymous
-args: 1,0,1
+args: 1,1,1
arg: Str('action')
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: plugins
-args: 0,2,3
+args: 0,3,3
option: Flag('all', autofill=True, cli_name='all', default=True, exclude='webui')
option: Flag('server?', autofill=True, default=False)
+option: Str('version?', exclude='webui')
output: Output('count', <type 'int'>, None)
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
@@ -2326,9 +2373,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: privilege_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2413,9 +2461,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: pwpolicy_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='group', multivalue=True, primary_key=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2536,9 +2585,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: role_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2617,8 +2667,9 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: selfservice_del
-args: 1,0,3
+args: 1,1,3
arg: Str('aciname', attribute=True, cli_name='name', multivalue=False, pattern='^[-_ a-zA-Z0-9]+$', primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2696,21 +2747,24 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: selinuxusermap_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: selinuxusermap_disable
-args: 1,0,3
+args: 1,1,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: selinuxusermap_enable
-args: 1,0,3
+args: 1,1,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2810,15 +2864,17 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: service_del
-args: 1,1,3
+args: 1,2,3
arg: Str('krbprincipalname', attribute=True, cli_name='principal', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: service_disable
-args: 1,0,3
+args: 1,1,3
arg: Str('krbprincipalname', attribute=True, cli_name='principal', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2888,9 +2944,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: sudocmd_del
-args: 1,1,3
+args: 1,2,3
arg: Str('sudocmd', attribute=True, cli_name='command', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -2956,9 +3013,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: sudocmdgroup_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='sudocmdgroup_name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -3068,9 +3126,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: sudorule_add_option
-args: 1,1,1
+args: 1,2,1
arg: Str('cn', attribute=True, cli_name='sudorule_name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('ipasudoopt', cli_name='sudooption')
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: sudorule_add_runasgroup
args: 1,4,3
@@ -3105,19 +3164,22 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: sudorule_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='sudorule_name', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: sudorule_disable
-args: 1,0,1
+args: 1,1,1
arg: Str('cn', attribute=True, cli_name='sudorule_name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: sudorule_enable
-args: 1,0,1
+args: 1,1,1
arg: Str('cn', attribute=True, cli_name='sudorule_name', multivalue=False, primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: sudorule_find
args: 1,19,4
@@ -3204,9 +3266,10 @@ output: Output('completed', <type 'int'>, None)
output: Output('failed', <type 'dict'>, None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
command: sudorule_remove_option
-args: 1,1,1
+args: 1,2,1
arg: Str('cn', attribute=True, cli_name='sudorule_name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('ipasudoopt', cli_name='sudooption')
+option: Str('version?', exclude='webui')
output: Output('result', None, None)
command: sudorule_remove_runasgroup
args: 1,4,3
@@ -3269,9 +3332,10 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: trust_del
-args: 1,1,3
+args: 1,2,3
arg: Str('cn', attribute=True, cli_name='realm', multivalue=True, primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -3383,21 +3447,24 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: user_del
-args: 1,1,3
+args: 1,2,3
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: user_disable
-args: 1,0,3
+args: 1,1,3
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
command: user_enable
-args: 1,0,3
+args: 1,1,3
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
@@ -3514,8 +3581,9 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('truncated', <type 'bool'>, None)
command: user_unlock
-args: 1,0,3
+args: 1,1,3
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
+option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Output('value', <type 'unicode'>, None)
diff --git a/doc/examples/examples.py b/doc/examples/examples.py
index a969c898..4ac415f1 100644
--- a/doc/examples/examples.py
+++ b/doc/examples/examples.py
@@ -97,7 +97,7 @@ class exhelloworld(Command):
# This is where the command functionality should go.
# It is always executed on the server-side, so don't rely
# on client-side stuff in here!
- def execute(self, name):
+ def execute(self, name, **options):
return dict(summary='Hello world, %s!' % name)
# register the command, uncomment this line if you want to try it out
diff --git a/ipalib/__init__.py b/ipalib/__init__.py
index 8bf37f04..aab74008 100644
--- a/ipalib/__init__.py
+++ b/ipalib/__init__.py
@@ -134,7 +134,7 @@ implement a ``run()`` method, like this:
>>> class my_command(Command):
... """My example plugin with run()."""
...
-... def run(self):
+... def run(self, **options):
... return dict(result='My run() method was called!')
...
>>> api = create_api()
@@ -174,17 +174,22 @@ For example, say you have a command plugin like this:
>>> class my_command(Command):
... """Forwarding vs. execution."""
...
-... def forward(self):
+... def forward(self, **options):
... return dict(
... result='forward(): in_server=%r' % self.env.in_server
... )
...
-... def execute(self):
+... def execute(self, **options):
... return dict(
... result='execute(): in_server=%r' % self.env.in_server
... )
...
+The ``options`` will contain a dict of command options. One option is added
+automatically: ``version``. It contains the API version of the client.
+In order to maintain forward compatibility, you should always specify the
+API version current at the time you're writing your client.
+
If ``my_command`` is loaded in a *client* context, ``forward()`` will be
called:
@@ -192,7 +197,7 @@ called:
>>> api.env.in_server = False # run() will dispatch to forward()
>>> api.register(my_command)
>>> api.finalize()
->>> api.Command.my_command() # Call your command plugin
+>>> api.Command.my_command(version=u'2.47') # Call your command plugin
{'result': 'forward(): in_server=False'}
On the other hand, if ``my_command`` is loaded in a *server* context,
@@ -202,7 +207,7 @@ On the other hand, if ``my_command`` is loaded in a *server* context,
>>> api.env.in_server = True # run() will dispatch to execute()
>>> api.register(my_command)
>>> api.finalize()
->>> api.Command.my_command() # Call your command plugin
+>>> api.Command.my_command(version=u'2.47') # Call your command plugin
{'result': 'execute(): in_server=True'}
Normally there should be no reason to override `frontend.Command.forward()`,
@@ -314,7 +319,7 @@ Second, we have our frontend plugin, the command:
>>> class my_command(Command):
... """My example command plugin."""
...
-... def execute(self):
+... def execute(self, **options):
... """Implemented against Backend.my_backend"""
... return dict(result=self.Backend.my_backend.do_stuff())
...
@@ -324,7 +329,7 @@ Lastly, we call ``api.finalize()`` and see what happens when we call
``my_command()``:
>>> api.finalize()
->>> api.Command.my_command()
+>>> api.Command.my_command(version=u'2.47')
{'result': 'my_backend.do_stuff() indeed did do stuff!'}
When not in a server context, ``my_command.execute()`` never gets called, so
@@ -337,11 +342,11 @@ example:
>>> class my_command(Command):
... """My example command plugin."""
...
-... def execute(self):
+... def execute(self, **options):
... """Same as above."""
... return dict(result=self.Backend.my_backend.do_stuff())
...
-... def forward(self):
+... def forward(self, **options):
... return dict(result='Just my_command.forward() getting called here.')
...
>>> api.register(my_command)
@@ -371,7 +376,7 @@ several other commands in a single operation. For example:
>>> class meta_command(Command):
... """My meta-command plugin."""
...
-... def execute(self):
+... def execute(self, **options):
... """Calls command_1(), command_2()"""
... msg = '%s; %s.' % (
... self.Command.command_1()['result'],
@@ -379,18 +384,18 @@ several other commands in a single operation. For example:
... )
... return dict(result=msg)
>>> class command_1(Command):
-... def execute(self):
+... def execute(self, **options):
... return dict(result='command_1.execute() called')
...
>>> class command_2(Command):
-... def execute(self):
+... def execute(self, **options):
... return dict(result='command_2.execute() called')
...
>>> api.register(meta_command)
>>> api.register(command_1)
>>> api.register(command_2)
>>> api.finalize()
->>> api.Command.meta_command()
+>>> api.Command.meta_command(version=u'2.47')
{'result': 'command_1.execute() called; command_2.execute() called.'}
Because this is quite useful, we are going to revise our golden rule somewhat:
@@ -425,9 +430,9 @@ For example:
>>> api.env.in_server = True
>>> api.register(nudge)
>>> api.finalize()
->>> api.Command.nudge(u'Jason')
+>>> api.Command.nudge(u'Jason', version=u'2.47')
{'result': u'Jason, go write more documentation!'}
->>> api.Command.nudge(u'Jason', stuff=u'unit tests')
+>>> api.Command.nudge(u'Jason', stuff=u'unit tests', version=u'2.47')
{'result': u'Jason, go write more unit tests!'}
The ``args`` and ``options`` attributes are `plugable.NameSpace` instances
@@ -438,25 +443,27 @@ containing a command's arguments and options, respectively, as you can see:
>>> api.Command.nudge.args.programmer
Str('programmer')
>>> list(api.Command.nudge.options) # Iterates through option names
-['stuff']
+['stuff', 'version']
>>> api.Command.nudge.options.stuff
Str('stuff', default=u'documentation')
>>> api.Command.nudge.options.stuff.default
u'documentation'
+The 'version' option is added to commands automatically.
+
The arguments and options must not contain colliding names. They are both
merged together into the ``params`` attribute, another `plugable.NameSpace`
instance, as you can see:
>>> api.Command.nudge.params
-NameSpace(<2 members>, sort=False)
+NameSpace(<3 members>, sort=False)
>>> list(api.Command.nudge.params) # Iterates through the param names
-['programmer', 'stuff']
+['programmer', 'stuff', 'version']
When calling a command, its positional arguments can also be provided as
keyword arguments, and in any order. For example:
->>> api.Command.nudge(stuff=u'lines of code', programmer=u'Jason')
+>>> api.Command.nudge(stuff=u'lines of code', programmer=u'Jason', version=u'2.47')
{'result': u'Jason, go write more lines of code!'}
When a command plugin is called, the values supplied for its parameters are
@@ -669,7 +676,7 @@ For example:
...
... takes_args = 'color'
...
-... def execute(self, color):
+... def execute(self, color, **options):
... """Uses self.log.error()"""
... if color not in ('red', 'blue', 'green'):
... self.log.error("I don't have %s paint!", color) # Log error
@@ -746,14 +753,14 @@ For example:
>>> class motd(Command):
... """Print message of the day."""
...
-... def execute(self):
+... def execute(self, **options):
... return dict(result=self.env.message)
...
>>> api = create_api()
>>> api.bootstrap(in_server=True, message='Hello, world!')
>>> api.register(motd)
>>> api.finalize()
->>> api.Command.motd()
+>>> api.Command.motd(version=u'2.47')
{'result': u'Hello, world!'}
Also see the `plugable.API.bootstrap_with_global_options()` method.
diff --git a/ipalib/cli.py b/ipalib/cli.py
index 3d59e4a0..f1d2f874 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -755,7 +755,7 @@ class help(frontend.Local):
super(help, self)._on_finalize()
- def run(self, key, outfile=None):
+ def run(self, key, outfile=None, **options):
if outfile is None:
outfile = sys.stdout
writer = self._writer(outfile)
@@ -872,7 +872,7 @@ class console(frontend.Command):
has_output = tuple()
- def run(self):
+ def run(self, **options):
code.interact(
'(Custom IPA interactive Python console)',
local=dict(api=self.api)
diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index 52ddf28c..c27ff138 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -526,7 +526,6 @@ class Command(HasParam):
yield (name, options.pop(name))
# If any options remain, they are either internal or unknown
unused_keys = set(options).difference(self.internal_options)
- unused_keys.discard('version')
if unused_keys:
raise OptionError(_('Unknown option: %(option)s'),
option=unused_keys.pop())
@@ -743,7 +742,8 @@ class Command(HasParam):
if self.api.env.in_server:
if 'version' in options:
self.verify_client_version(options['version'])
- del options['version']
+ else:
+ options['version'] = API_VERSION
return self.execute(*args, **options)
return self.forward(*args, **options)
@@ -897,12 +897,12 @@ class Command(HasParam):
exclude='webui',
flags=['no_output'],
)
- yield Str('version?',
- doc=_('Client version. Used to determine if server will accept request.'),
- exclude='webui',
- flags=['no_option', 'no_output'],
- )
- return
+ break
+ yield Str('version?',
+ doc=_('Client version. Used to determine if server will accept request.'),
+ exclude='webui',
+ flags=['no_option', 'no_output'],
+ )
def validate_output(self, output):
"""
@@ -1282,7 +1282,7 @@ class Method(Attribute, Command):
>>> from ipalib import create_api
>>> api = create_api()
>>> class user_add(Method):
- ... def run(self):
+ ... def run(self, **options):
... return dict(result='Added the user!')
...
>>> class user(Object):
diff --git a/ipalib/plugins/aci.py b/ipalib/plugins/aci.py
index 7c4e8a54..a97bb48b 100644
--- a/ipalib/plugins/aci.py
+++ b/ipalib/plugins/aci.py
@@ -566,7 +566,7 @@ class aci_del(crud.Delete):
takes_options = (_prefix_option,)
- def execute(self, aciname, aciprefix):
+ def execute(self, aciname, aciprefix, **options):
"""
Execute the aci-delete operation.
diff --git a/ipalib/plugins/automount.py b/ipalib/plugins/automount.py
index 19b60905..fcda0a10 100644
--- a/ipalib/plugins/automount.py
+++ b/ipalib/plugins/automount.py
@@ -889,7 +889,7 @@ class automountkey_del(LDAPDelete):
),
)
def get_options(self):
- for option in self.takes_options:
+ for option in super(automountkey_del, self).get_options():
if option.name == 'continue':
# TODO: hide for now - remove in future major release
yield option.clone(exclude='webui',
diff --git a/ipalib/plugins/batch.py b/ipalib/plugins/batch.py
index db9c08f1..5fd5943f 100644
--- a/ipalib/plugins/batch.py
+++ b/ipalib/plugins/batch.py
@@ -95,6 +95,7 @@ class batch(Command):
a, kw = arg['params']
newkw = dict((str(k), v) for k, v in kw.iteritems())
params = api.Command[name].args_options_2_params(*a, **newkw)
+ newkw.setdefault('version', options['version'])
result = api.Command[name](*a, **newkw)
self.info(
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
index 51493c34..6b84c723 100644
--- a/ipalib/plugins/cert.py
+++ b/ipalib/plugins/cert.py
@@ -306,8 +306,7 @@ class cert_request(VirtualCommand):
ldap = self.api.Backend.ldap2
principal = kw.get('principal')
add = kw.get('add')
- del kw['principal']
- del kw['add']
+ request_type = kw.get('request_type')
service = None
"""
@@ -414,7 +413,8 @@ class cert_request(VirtualCommand):
api.Command['host_mod'](hostname, usercertificate=None)
# Request the certificate
- result = self.Backend.ra.request_certificate(csr, **kw)
+ result = self.Backend.ra.request_certificate(
+ csr, request_type=request_type)
cert = x509.load_certificate(result['certificate'])
result['issuer'] = unicode(cert.issuer)
result['valid_not_before'] = unicode(cert.valid_not_before_str)
@@ -596,10 +596,12 @@ class cert_revoke(VirtualCommand):
result = api.Command['cert_show'](unicode(serial_number))['result']
except errors.NotImplementedError:
pass
- if kw['revocation_reason'] == 7:
+ revocation_reason = kw['revocation_reason']
+ if revocation_reason == 7:
raise errors.CertificateOperationError(error=_('7 is not a valid revocation reason'))
return dict(
- result=self.Backend.ra.revoke_certificate(serial_number, **kw)
+ result=self.Backend.ra.revoke_certificate(
+ serial_number, revocation_reason=revocation_reason)
)
api.register(cert_revoke)
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index c329c100..61c2de32 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -2730,13 +2730,13 @@ class dnsrecord_del(LDAPUpdate):
error=_('Zone record \'%s\' cannot be deleted') \
% _dns_zone_record
)
- return self.obj.methods.delentry(*keys)
+ return self.obj.methods.delentry(*keys, version=options['version'])
result = super(dnsrecord_del, self).execute(*keys, **options)
if getattr(context, 'del_all', False) and not \
self.obj.is_pkey_zone_record(*keys):
- return self.obj.methods.delentry(*keys)
+ return self.obj.methods.delentry(*keys, version=options['version'])
return result
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
diff --git a/ipalib/plugins/hbacrule.py b/ipalib/plugins/hbacrule.py
index 0b1e8b83..8bc4c6df 100644
--- a/ipalib/plugins/hbacrule.py
+++ b/ipalib/plugins/hbacrule.py
@@ -303,7 +303,7 @@ class hbacrule_enable(LDAPQuery):
msg_summary = _('Enabled HBAC rule "%(value)s"')
has_output = output.standard_value
- def execute(self, cn):
+ def execute(self, cn, **options):
ldap = self.obj.backend
dn = self.obj.get_dn(cn)
@@ -330,7 +330,7 @@ class hbacrule_disable(LDAPQuery):
msg_summary = _('Disabled HBAC rule "%(value)s"')
has_output = output.standard_value
- def execute(self, cn):
+ def execute(self, cn, **options):
ldap = self.obj.backend
dn = self.obj.get_dn(cn)
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index cfb5d60f..e9fc9de4 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -682,7 +682,7 @@ class i18n_messages(Command):
has_output = (
Output('messages', dict, doc=_('Dict of I18N messages')),
)
- def execute(self):
+ def execute(self, **options):
return dict([("messages",json_serialize(self.messages))])
def output_for_cli(self, textui, result, *args, **options):
diff --git a/ipalib/plugins/passwd.py b/ipalib/plugins/passwd.py
index 68aa3ebb..280517cd 100644
--- a/ipalib/plugins/passwd.py
+++ b/ipalib/plugins/passwd.py
@@ -88,7 +88,7 @@ class passwd(Command):
has_output = output.standard_value
msg_summary = _('Changed password for "%(value)s"')
- def execute(self, principal, password, current_password):
+ def execute(self, principal, password, current_password, **options):
"""
Execute the passwd operation.
diff --git a/ipalib/plugins/ping.py b/ipalib/plugins/ping.py
index 0da07e0b..e9dc28fe 100644
--- a/ipalib/plugins/ping.py
+++ b/ipalib/plugins/ping.py
@@ -58,7 +58,7 @@ class ping(Command):
output.summary,
)
- def execute(self):
+ def execute(self, **options):
"""
A possible enhancement would be to take an argument and echo it
back but a fixed value works for now.
diff --git a/ipalib/plugins/selinuxusermap.py b/ipalib/plugins/selinuxusermap.py
index 32c55850..60eb053a 100644
--- a/ipalib/plugins/selinuxusermap.py
+++ b/ipalib/plugins/selinuxusermap.py
@@ -394,7 +394,7 @@ class selinuxusermap_enable(LDAPQuery):
msg_summary = _('Enabled SELinux User Map "%(value)s"')
has_output = output.standard_value
- def execute(self, cn):
+ def execute(self, cn, **options):
ldap = self.obj.backend
dn = self.obj.get_dn(cn)
@@ -421,7 +421,7 @@ class selinuxusermap_disable(LDAPQuery):
msg_summary = _('Disabled SELinux User Map "%(value)s"')
has_output = output.standard_value
- def execute(self, cn):
+ def execute(self, cn, **options):
ldap = self.obj.backend
dn = self.obj.get_dn(cn)
diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index 11108099..878033f0 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -321,7 +321,7 @@ api.register(sudorule_show)
class sudorule_enable(LDAPQuery):
__doc__ = _('Enable a Sudo Rule.')
- def execute(self, cn):
+ def execute(self, cn, **options):
ldap = self.obj.backend
dn = self.obj.get_dn(cn)
@@ -345,7 +345,7 @@ api.register(sudorule_enable)
class sudorule_disable(LDAPQuery):
__doc__ = _('Disable a Sudo Rule.')
- def execute(self, cn):
+ def execute(self, cn, **options):
ldap = self.obj.backend
dn = self.obj.get_dn(cn)
diff --git a/tests/test_ipalib/test_backend.py b/tests/test_ipalib/test_backend.py
index b8f8d557..e18c8d38 100644
--- a/tests/test_ipalib/test_backend.py
+++ b/tests/test_ipalib/test_backend.py
@@ -27,6 +27,7 @@ from tests.data import unicode_str
from ipalib.request import context, Connection
from ipalib.frontend import Command
from ipalib import backend, plugable, errors, base
+from ipapython.version import API_VERSION
@@ -184,7 +185,7 @@ class test_Executioner(ClassChecker):
api.register(echo)
class good(Command):
- def execute(self):
+ def execute(self, **options):
raise errors.ValidationError(
name='nurse',
error=u'Not naughty!',
@@ -192,7 +193,7 @@ class test_Executioner(ClassChecker):
api.register(good)
class bad(Command):
- def execute(self):
+ def execute(self, **options):
raise ValueError('This is private.')
api.register(bad)
@@ -224,10 +225,15 @@ class test_Executioner(ClassChecker):
arg1 = unicode_str
arg2 = (u'Hello', unicode_str, u'world!')
args = (arg1,) + arg2
- options = dict(option1=u'How are you?', option2=unicode_str)
+ options = dict(option1=u'How are you?', option2=unicode_str,
+ version=API_VERSION)
conn = Connection('The connection.', Disconnect('someconn'))
context.someconn = conn
+ print o.execute('echo', arg1, arg2, **options)
+ print dict(
+ result=(arg1, arg2, options)
+ )
assert o.execute('echo', arg1, arg2, **options) == dict(
result=(arg1, arg2, options)
)
@@ -261,4 +267,6 @@ class test_Executioner(ClassChecker):
# Test with option 'name':
conn = Connection('The connection.', Disconnect('someconn'))
context.someconn = conn
- assert o.execute('with_name', name=u'test') == dict(result=u'TEST')
+ expected = dict(result=u'TEST')
+ assert expected == o.execute('with_name', name=u'test',
+ version=API_VERSION)
diff --git a/tests/test_ipalib/test_crud.py b/tests/test_ipalib/test_crud.py
index 3700c508..b19605be 100644
--- a/tests/test_ipalib/test_crud.py
+++ b/tests/test_ipalib/test_crud.py
@@ -156,8 +156,8 @@ class test_Delete(CrudChecker):
Test the `ipalib.crud.Delete.get_options` method.
"""
api = self.get_api()
- assert list(api.Method.user_verb.options) == []
- assert len(api.Method.user_verb.options) == 0
+ assert list(api.Method.user_verb.options) == ['version']
+ assert len(api.Method.user_verb.options) == 1
class test_Search(CrudChecker):
diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py
index 528609d9..4b473559 100644
--- a/tests/test_ipalib/test_frontend.py
+++ b/tests/test_ipalib/test_frontend.py
@@ -243,10 +243,14 @@ class test_Command(ClassChecker):
"""
Test the `ipalib.frontend.Command.get_options` method.
"""
- assert list(self.cls().get_options()) == []
+ options = list(self.cls().get_options())
+ assert len(options) == 1
+ assert options[0].name == 'version'
options = ('verbose', 'debug')
o = self.get_instance(options=options)
- assert tuple(o.get_options()) == options
+ assert len(tuple(o.get_options())) == 3
+ assert 'verbose' in tuple(o.get_options())
+ assert 'debug' in tuple(o.get_options())
def test_args(self):
"""
@@ -305,12 +309,12 @@ class test_Command(ClassChecker):
o = self.cls()
o.finalize()
assert type(o.options) is plugable.NameSpace
- assert len(o.options) == 0
+ assert len(o.options) == 1
options = ('target', 'files*')
ns = self.get_instance(options=options).options
assert type(ns) is plugable.NameSpace
- assert len(ns) == len(options)
- assert list(ns) == ['target', 'files']
+ assert len(ns) == len(options) + 1
+ assert list(ns) == ['target', 'files', 'version']
assert type(ns.target) is parameters.Str
assert type(ns.files) is parameters.Str
assert ns.target.required is True
@@ -377,12 +381,13 @@ class test_Command(ClassChecker):
cmd = user_add()
cmd.env = config.Env(context='cli')
cmd.finalize()
- assert list(cmd.params) == ['givenname', 'sn', 'uid']
+ assert list(cmd.params) == ['givenname', 'sn', 'uid', 'version']
ret = cmd.soft_validate({})
- assert len(ret['values']) == 0
- assert len(ret['errors']) == 3
+ assert sorted(ret['values']) == ['version']
+ assert sorted(ret['errors']) == ['givenname', 'sn', 'uid']
assert cmd.soft_validate(dict(givenname=u'First', sn=u'Last')) == dict(
- values=dict(givenname=u'First', sn=u'Last', uid=u'flast'),
+ values=dict(givenname=u'First', sn=u'Last', uid=u'flast',
+ version=None),
errors=dict(),
)
@@ -604,7 +609,6 @@ class test_Command(ClassChecker):
o.set_api(api)
assert o.run.im_func is self.cls.run.im_func
out = o.run(*args, **kw)
- del kw['version']
assert ('execute', args, kw) == out
# Test in non-server context
@@ -749,7 +753,7 @@ class test_LocalOrRemote(ClassChecker):
o = self.cls()
o.finalize()
assert list(o.args) == []
- assert list(o.options) == ['server']
+ assert list(o.options) == ['server', 'version']
op = o.options.server
assert op.required is False
assert op.default is False
@@ -772,17 +776,17 @@ class test_LocalOrRemote(ClassChecker):
api.register(example)
api.finalize()
cmd = api.Command.example
- assert cmd() == dict(
- result=('execute', (None,), dict(server=False))
+ assert cmd(version=u'2.47') == dict(
+ result=('execute', (None,), dict(version=u'2.47', server=False))
)
- assert cmd(u'var') == dict(
- result=('execute', (u'var',), dict(server=False))
+ assert cmd(u'var', version=u'2.47') == dict(
+ result=('execute', (u'var',), dict(version=u'2.47', server=False))
)
- assert cmd(server=True) == dict(
- result=('forward', (None,), dict(server=True))
+ assert cmd(server=True, version=u'2.47') == dict(
+ result=('forward', (None,), dict(version=u'2.47', server=True))
)
- assert cmd(u'var', server=True) == dict(
- result=('forward', (u'var',), dict(server=True))
+ assert cmd(u'var', server=True, version=u'2.47') == dict(
+ result=('forward', (u'var',), dict(version=u'2.47', server=True))
)
# Test when in_server=True (should always call execute):
@@ -790,17 +794,17 @@ class test_LocalOrRemote(ClassChecker):
api.register(example)
api.finalize()
cmd = api.Command.example
- assert cmd() == dict(
- result=('execute', (None,), dict(server=False))
+ assert cmd(version=u'2.47') == dict(
+ result=('execute', (None,), dict(version=u'2.47', server=False))
)
- assert cmd(u'var') == dict(
- result=('execute', (u'var',), dict(server=False))
+ assert cmd(u'var', version=u'2.47') == dict(
+ result=('execute', (u'var',), dict(version=u'2.47', server=False))
)
- assert cmd(server=True) == dict(
- result=('execute', (None,), dict(server=True))
+ assert cmd(server=True, version=u'2.47') == dict(
+ result=('execute', (None,), dict(version=u'2.47', server=True))
)
- assert cmd(u'var', server=True) == dict(
- result=('execute', (u'var',), dict(server=True))
+ assert cmd(u'var', server=True, version=u'2.47') == dict(
+ result=('execute', (u'var',), dict(version=u'2.47', server=True))
)
diff --git a/tests/test_xmlrpc/test_cert.py b/tests/test_xmlrpc/test_cert_plugin.py
index 906d1977..906d1977 100644
--- a/tests/test_xmlrpc/test_cert.py
+++ b/tests/test_xmlrpc/test_cert_plugin.py