summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2011-11-29 09:59:11 +0100
committerMartin Kosek <mkosek@redhat.com>2011-11-29 10:08:28 +0100
commit1b0b9645d197f512eee61051775414ca35ee7f6d (patch)
treeaf96542f62da62d8c4021474fc326b7470e46a95
parent046147b3a44b793049ee0100d775b8fe5c709999 (diff)
downloadfreeipa-1b0b9645d197f512eee61051775414ca35ee7f6d.tar.gz
freeipa-1b0b9645d197f512eee61051775414ca35ee7f6d.tar.xz
freeipa-1b0b9645d197f512eee61051775414ca35ee7f6d.zip
Add --delattr option to complement --setattr/--addattr
Add a --delattr option to round out multi-valued attribute manipulation. The new option is available for all LDAPUpdate based commands. --delattr is evaluated last, it can remove any value present either in --addattr/--setattr option or in current LDAP object. --*attr processing was completely refactored and placed to one independent function available for all baseldap commands. For this purpose a missing common base class for all baseldap commands has been implemented. The new class should serve not only for --*attr processing but also for other common baseldap methods and attributes. This approach will also benefit other custom commands based neither on LDAPCreate nor LDAPUpdate. They can easily integrate --*attr option processing when needed. https://fedorahosted.org/freeipa/ticket/1929
-rw-r--r--API.txt156
-rw-r--r--VERSION2
-rw-r--r--ipalib/frontend.py62
-rw-r--r--ipalib/plugins/baseldap.py235
-rw-r--r--tests/test_xmlrpc/test_attr.py126
-rw-r--r--tests/test_xmlrpc/test_group_plugin.py4
6 files changed, 393 insertions, 192 deletions
diff --git a/API.txt b/API.txt
index 135b07908..72e7025b9 100644
--- a/API.txt
+++ b/API.txt
@@ -218,8 +218,8 @@ arg: Str('automountlocationcn', cli_name='automountlocation', query=True, requir
arg: IA5Str('automountmapautomountmapname', cli_name='automountmap', query=True, required=True)
option: IA5Str('automountkey', attribute=True, cli_name='key', multivalue=False, required=True)
option: IA5Str('automountinformation', attribute=True, cli_name='info', multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -253,13 +253,14 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: automountkey_mod
-args: 2,10,3
+args: 2,11,3
arg: Str('automountlocationcn', cli_name='automountlocation', query=True, required=True)
arg: IA5Str('automountmapautomountmapname', cli_name='automountmap', query=True, required=True)
option: IA5Str('automountkey', alwaysask=False, attribute=True, cli_name='key', multivalue=False, required=True)
option: IA5Str('automountinformation', attribute=True, autofill=False, cli_name='info', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: IA5Str('newautomountinformation?', cli_name='newinfo')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -285,8 +286,8 @@ output: Output('value', <type 'unicode'>, None)
command: automountlocation_add
args: 1,5,3
arg: Str('cn', attribute=True, cli_name='location', multivalue=False, primary_key=True, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -339,8 +340,8 @@ args: 2,6,3
arg: Str('automountlocationcn', cli_name='automountlocation', query=True, required=True)
arg: IA5Str('automountmapname', attribute=True, cli_name='map', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -352,8 +353,8 @@ args: 2,8,3
arg: Str('automountlocationcn', cli_name='automountlocation', query=True, required=True)
arg: IA5Str('automountmapname', attribute=True, cli_name='map', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('key', cli_name='mount')
option: Str('parentmap?', autofill=True, cli_name='parentmap', default=u'auto.master')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -387,12 +388,13 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: automountmap_mod
-args: 2,7,3
+args: 2,8,3
arg: Str('automountlocationcn', cli_name='automountlocation', query=True, required=True)
arg: IA5Str('automountmapname', attribute=True, cli_name='map', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -442,7 +444,7 @@ args: 1,0,1
arg: Str('request_id')
output: Output('result', None, None)
command: config_mod
-args: 0,19,3
+args: 0,20,3
option: Int('ipamaxusernamelength', attribute=True, autofill=False, cli_name='maxusername', minvalue=1, multivalue=False, required=False)
option: IA5Str('ipahomesrootdir', attribute=True, autofill=False, cli_name='homedirectory', multivalue=False, required=False)
option: Str('ipadefaultloginshell', attribute=True, autofill=False, cli_name='defaultshell', multivalue=False, required=False)
@@ -456,8 +458,9 @@ option: Bool('ipamigrationenabled', attribute=True, autofill=False, cli_name='en
option: List('ipagroupobjectclasses', attribute=True, autofill=False, cli_name='groupobjectclasses', multivalue=True, required=False)
option: List('ipauserobjectclasses', attribute=True, autofill=False, cli_name='userobjectclasses', multivalue=True, required=False)
option: Int('ipapwdexpadvnotify', attribute=True, autofill=False, cli_name='pwdexpnotify', minvalue=0, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -479,8 +482,8 @@ args: 1,7,3
arg: Str('cn', attribute=True, cli_name='cn', multivalue=False, primary_key=True, required=True)
option: Str('krbpwdpolicyreference', attribute=True, cli_name='krbpwdpolicyreference', multivalue=False, required=True)
option: Int('cospriority', attribute=True, cli_name='cospriority', minvalue=0, multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -511,12 +514,13 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: cosentry_mod
-args: 1,8,3
+args: 1,9,3
arg: Str('cn', attribute=True, cli_name='cn', multivalue=False, primary_key=True, query=True, required=True)
option: Str('krbpwdpolicyreference', attribute=True, autofill=False, cli_name='krbpwdpolicyreference', multivalue=False, required=False)
option: Int('cospriority', attribute=True, autofill=False, cli_name='cospriority', minvalue=0, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -607,8 +611,8 @@ arg: Str('dnszoneidnsname', cli_name='dnszone', query=True, required=True)
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
option: Int('dnsttl', attribute=True, cli_name='ttl', multivalue=False, required=False)
option: StrEnum('dnsclass', attribute=True, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('force', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -868,8 +872,8 @@ option: Int('dnsttl', attribute=True, cli_name='ttl', multivalue=False, required
option: StrEnum('dnsclass', attribute=True, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
option: Str('idnsupdatepolicy', attribute=True, cli_name='update_policy', multivalue=False, required=False)
option: Bool('idnsallowdynupdate', attribute=True, autofill=True, cli_name='dynamic_update', default=False, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('force', autofill=True, default=False)
option: Str('ip_address?')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -926,7 +930,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: dnszone_mod
-args: 1,18,3
+args: 1,19,3
arg: Str('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('name_from_ip', attribute=False, autofill=False, cli_name='name_from_ip', multivalue=False, required=False)
option: Str('idnssoamname', attribute=True, autofill=False, cli_name='name_server', multivalue=False, required=False)
@@ -940,8 +944,9 @@ option: Int('dnsttl', attribute=True, autofill=False, cli_name='ttl', multivalue
option: StrEnum('dnsclass', attribute=True, autofill=False, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
option: Str('idnsupdatepolicy', attribute=True, autofill=False, cli_name='update_policy', multivalue=False, required=False)
option: Bool('idnsallowdynupdate', attribute=True, autofill=False, cli_name='dynamic_update', default=False, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -993,15 +998,15 @@ output: Output('truncated', <type 'bool'>, None)
command: entitle_import
args: 1,3,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('addattr*', cli_name='addattr', exclude='webui')
option: Str('uuid?', autofill=True, default=u'IMPORTED')
output: Output('result', <type 'dict'>, None)
command: entitle_register
args: 1,7,3
arg: Str('username')
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('ipaentitlementid?')
option: Password('password', confirm=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -1036,8 +1041,8 @@ args: 1,8,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_.$-]?$', pattern_errmsg='may only include letters, numbers, _, -, . and $', primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
option: Int('gidnumber', attribute=True, cli_name='gid', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('nonposix', autofill=True, cli_name='nonposix', default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1101,12 +1106,13 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: group_mod
-args: 1,10,3
+args: 1,11,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_.$-]?$', pattern_errmsg='may only include letters, numbers, _, -, . and $', primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
option: Int('gidnumber', attribute=True, autofill=False, cli_name='gid', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('posix', autofill=True, cli_name='posix', default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -1146,8 +1152,8 @@ option: StrEnum('hostcategory', attribute=True, cli_name='hostcat', multivalue=F
option: StrEnum('sourcehostcategory', attribute=True, cli_name='srchostcat', multivalue=False, required=False, values=(u'all',))
option: StrEnum('servicecategory', attribute=True, cli_name='servicecat', multivalue=False, required=False, values=(u'all',))
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -1238,7 +1244,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: hbacrule_mod
-args: 1,12,3
+args: 1,13,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: StrEnum('accessruletype', attribute=True, autofill=False, cli_name='type', default=u'allow', exclude='webui', multivalue=False, required=False, values=(u'allow', u'deny'))
option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
@@ -1246,8 +1252,9 @@ option: StrEnum('hostcategory', attribute=True, autofill=False, cli_name='hostca
option: StrEnum('sourcehostcategory', attribute=True, autofill=False, cli_name='srchostcat', multivalue=False, required=False, values=(u'all',))
option: StrEnum('servicecategory', attribute=True, autofill=False, cli_name='servicecat', multivalue=False, required=False, values=(u'all',))
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1313,8 +1320,8 @@ command: hbacsvc_add
args: 1,6,3
arg: Str('cn', attribute=True, cli_name='service', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -1344,11 +1351,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: hbacsvc_mod
-args: 1,7,3
+args: 1,8,3
arg: Str('cn', attribute=True, cli_name='service', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1370,8 +1378,8 @@ command: hbacsvcgroup_add
args: 1,6,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -1411,11 +1419,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: hbacsvcgroup_mod
-args: 1,7,3
+args: 1,8,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1537,7 +1546,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: host_mod
-args: 1,15,3
+args: 1,16,3
arg: Str('fqdn', attribute=True, cli_name='hostname', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9][a-zA-Z0-9-\\.]{0,254}$', pattern_errmsg='may only include letters, numbers, and -', primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
option: Str('l', attribute=True, autofill=False, cli_name='locality', multivalue=False, required=False)
@@ -1547,8 +1556,9 @@ option: Str('nsosversion', attribute=True, autofill=False, cli_name='os', multiv
option: Str('userpassword', attribute=True, autofill=False, cli_name='password', multivalue=False, required=False)
option: Flag('random', attribute=False, autofill=True, cli_name='random', default=False, multivalue=False, required=False)
option: Bytes('usercertificate', attribute=True, autofill=False, cli_name='certificate', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Str('krbprincipalname?', attribute=True, cli_name='principalname')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -1582,8 +1592,8 @@ command: hostgroup_add
args: 1,6,3
arg: Str('cn', attribute=True, cli_name='hostgroup_name', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -1636,11 +1646,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: hostgroup_mod
-args: 1,7,3
+args: 1,8,3
arg: Str('cn', attribute=True, cli_name='hostgroup_name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1679,12 +1690,13 @@ arg: Str('methodname?')
output: Output('objects', <type 'dict'>, None)
output: Output('methods', <type 'dict'>, None)
command: krbtpolicy_mod
-args: 1,8,3
+args: 1,9,3
arg: Str('uid', attribute=True, cli_name='user', multivalue=False, primary_key=True, query=True, required=False)
option: Int('krbmaxticketlife', attribute=True, autofill=False, cli_name='maxlife', minvalue=1, multivalue=False, required=False)
option: Int('krbmaxrenewableage', attribute=True, autofill=False, cli_name='maxrenew', minvalue=1, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1739,8 +1751,8 @@ option: Str('description', attribute=True, cli_name='desc', multivalue=False, re
option: Str('nisdomainname', attribute=True, cli_name='nisdomain', multivalue=False, required=False)
option: StrEnum('usercategory', attribute=True, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
option: StrEnum('hostcategory', attribute=True, cli_name='hostcat', multivalue=False, required=False, values=(u'all',))
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -1802,14 +1814,15 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: netgroup_mod
-args: 1,10,3
+args: 1,11,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
option: Str('nisdomainname', attribute=True, autofill=False, cli_name='nisdomain', multivalue=False, required=False)
option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
option: StrEnum('hostcategory', attribute=True, autofill=False, cli_name='hostcat', multivalue=False, required=False, values=(u'all',))
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1859,8 +1872,8 @@ option: Str('memberof', alwaysask=True, attribute=True, autofill=False, cli_name
option: Str('filter', alwaysask=True, attribute=True, autofill=False, cli_name='filter', multivalue=False, query=True, required=False)
option: Str('subtree', alwaysask=True, attribute=True, autofill=False, cli_name='subtree', multivalue=False, query=True, required=False)
option: Str('targetgroup', alwaysask=True, attribute=True, autofill=False, cli_name='targetgroup', multivalue=False, query=True, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -1906,7 +1919,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: permission_mod
-args: 1,14,3
+args: 1,15,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: List('permissions', attribute=True, autofill=False, cli_name='permissions', multivalue=True, required=False)
option: List('attrs', alwaysask=True, attribute=True, autofill=False, cli_name='attrs', multivalue=True, query=True, required=False)
@@ -1915,8 +1928,9 @@ option: Str('memberof', alwaysask=True, attribute=True, autofill=False, cli_name
option: Str('filter', alwaysask=True, attribute=True, autofill=False, cli_name='filter', multivalue=False, query=True, required=False)
option: Str('subtree', alwaysask=True, attribute=True, autofill=False, cli_name='subtree', multivalue=False, query=True, required=False)
option: Str('targetgroup', alwaysask=True, attribute=True, autofill=False, cli_name='targetgroup', multivalue=False, query=True, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -1963,8 +1977,8 @@ command: privilege_add
args: 1,6,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -2014,11 +2028,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: privilege_mod
-args: 1,8,3
+args: 1,9,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2069,8 +2084,8 @@ option: Int('cospriority', attribute=False, cli_name='priority', minvalue=0, mul
option: Int('krbpwdmaxfailure', attribute=True, cli_name='maxfail', minvalue=0, multivalue=False, required=False)
option: Int('krbpwdfailurecountinterval', attribute=True, cli_name='failinterval', minvalue=0, multivalue=False, required=False)
option: Int('krbpwdlockoutduration', attribute=True, cli_name='lockouttime', minvalue=0, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -2108,7 +2123,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: pwpolicy_mod
-args: 1,15,3
+args: 1,16,3
arg: Str('cn', attribute=True, cli_name='group', multivalue=False, primary_key=True, query=True, required=False)
option: Int('krbmaxpwdlife', attribute=True, autofill=False, cli_name='maxlife', minvalue=0, multivalue=False, required=False)
option: Int('krbminpwdlife', attribute=True, autofill=False, cli_name='minlife', minvalue=0, multivalue=False, required=False)
@@ -2119,8 +2134,9 @@ option: Int('cospriority', attribute=False, autofill=False, cli_name='priority',
option: Int('krbpwdmaxfailure', attribute=True, autofill=False, cli_name='maxfail', minvalue=0, multivalue=False, required=False)
option: Int('krbpwdfailurecountinterval', attribute=True, autofill=False, cli_name='failinterval', minvalue=0, multivalue=False, required=False)
option: Int('krbpwdlockoutduration', attribute=True, autofill=False, cli_name='lockouttime', minvalue=0, multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2143,8 +2159,8 @@ command: role_add
args: 1,6,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -2197,11 +2213,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: role_mod
-args: 1,8,3
+args: 1,9,3
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2344,11 +2361,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: service_mod
-args: 1,7,3
+args: 1,8,3
arg: Str('krbprincipalname', attribute=True, cli_name='principal', multivalue=False, primary_key=True, query=True, required=True)
option: Bytes('usercertificate', attribute=True, autofill=False, cli_name='certificate', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2381,8 +2399,8 @@ command: sudocmd_add
args: 1,6,3
arg: Str('sudocmd', attribute=True, cli_name='command', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -2412,11 +2430,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: sudocmd_mod
-args: 1,7,3
+args: 1,8,3
arg: Str('sudocmd', attribute=True, cli_name='command', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2438,8 +2457,8 @@ command: sudocmdgroup_add
args: 1,6,3
arg: Str('cn', attribute=True, cli_name='sudocmdgroup_name', multivalue=False, primary_key=True, required=True)
option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=True)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -2479,11 +2498,12 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: sudocmdgroup_mod
-args: 1,7,3
+args: 1,8,3
arg: Str('cn', attribute=True, cli_name='sudocmdgroup_name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2523,8 +2543,8 @@ option: StrEnum('ipasudorunasgroupcategory', attribute=True, cli_name='runasgrou
option: Str('externaluser', attribute=True, cli_name='externaluser', multivalue=False, required=False)
option: Str('ipasudorunasextuser', attribute=True, cli_name='runasexternaluser', multivalue=False, required=False)
option: Str('ipasudorunasextgroup', attribute=True, cli_name='runasexternalgroup', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
option: Str('version?', exclude='webui')
@@ -2640,7 +2660,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: sudorule_mod
-args: 1,15,3
+args: 1,16,3
arg: Str('cn', attribute=True, cli_name='sudorule_name', multivalue=False, primary_key=True, query=True, required=True)
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
option: StrEnum('usercategory', attribute=True, autofill=False, cli_name='usercat', multivalue=False, required=False, values=(u'all',))
@@ -2651,8 +2671,9 @@ option: StrEnum('ipasudorunasgroupcategory', attribute=True, autofill=False, cli
option: Str('externaluser', attribute=True, autofill=False, cli_name='externaluser', multivalue=False, required=False)
option: Str('ipasudorunasextuser', attribute=True, autofill=False, cli_name='runasexternaluser', multivalue=False, required=False)
option: Str('ipasudorunasextgroup', attribute=True, autofill=False, cli_name='runasexternalgroup', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2768,8 +2789,8 @@ option: Str('ou', attribute=True, cli_name='orgunit', multivalue=False, required
option: Str('title', attribute=True, cli_name='title', multivalue=False, required=False)
option: Str('manager', attribute=True, cli_name='manager', multivalue=False, required=False)
option: Str('carlicense', attribute=True, cli_name='carlicense', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Flag('noprivate', autofill=True, cli_name='noprivate', default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -2847,7 +2868,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
output: Output('count', <type 'int'>, None)
output: Output('truncated', <type 'bool'>, None)
command: user_mod
-args: 1,31,3
+args: 1,32,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_.$-]?$', pattern_errmsg='may only include letters, numbers, _, -, . and $', primary_key=True, query=True, required=True)
option: Str('givenname', attribute=True, autofill=False, cli_name='first', multivalue=False, required=False)
option: Str('sn', attribute=True, autofill=False, cli_name='last', multivalue=False, required=False)
@@ -2873,8 +2894,9 @@ option: Str('ou', attribute=True, autofill=False, cli_name='orgunit', multivalue
option: Str('title', attribute=True, autofill=False, cli_name='title', multivalue=False, required=False)
option: Str('manager', attribute=True, autofill=False, cli_name='manager', multivalue=False, required=False)
option: Str('carlicense', attribute=True, autofill=False, cli_name='carlicense', multivalue=False, required=False)
-option: Str('addattr*', cli_name='addattr', exclude='webui')
option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
option: Flag('rights', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
diff --git a/VERSION b/VERSION
index a191c2eed..0b0ff1939 100644
--- a/VERSION
+++ b/VERSION
@@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=15
+IPA_API_VERSION_MINOR=16
diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index 2ab457c3d..b79aad955 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -30,7 +30,7 @@ from util import make_repr
from output import Output, Entry, ListOfEntries
from text import _, ngettext
-from errors import ZeroArgumentError, MaxArgumentError, OverlapError, RequiresRoot, VersionError, RequirementError, ValidationError
+from errors import ZeroArgumentError, MaxArgumentError, OverlapError, RequiresRoot, VersionError, RequirementError
from errors import InvocationError
from constants import TYPE_ERROR
from ipapython.version import API_VERSION
@@ -535,45 +535,6 @@ class Command(HasParam):
kw = self.args_options_2_params(*args, **options)
return dict(self.__attributes_2_entry(kw))
- def __convert_2_dict(self, attrs, append=True):
- """
- Convert a string in the form of name/value pairs into
- a dictionary. The incoming attribute may be a string or
- a list.
-
- Any attribute found that is also a param is validated.
-
- append controls whether this returns a list of values or a single
- value.
- """
- newdict = {}
- if not type(attrs) in (list, tuple):
- attrs = [attrs]
- for a in attrs:
- m = re.match("\s*(.*?)\s*=\s*(.*?)\s*$", a)
- attr = str(m.group(1)).lower()
- value = m.group(2)
- if len(value) == 0:
- # None means "delete this attribute"
- value = None
- if attr in self.params:
- try:
- value = self.params[attr](value)
- except ValidationError, err:
- (name, error) = str(err.strerror).split(':')
- raise ValidationError(name=attr, error=error)
- if append and attr in newdict:
- if type(value) in (tuple,):
- newdict[attr] += list(value)
- else:
- newdict[attr].append(value)
- else:
- if type(value) in (tuple,):
- newdict[attr] = list(value)
- else:
- newdict[attr] = [value]
- return newdict
-
def __attributes_2_entry(self, kw):
for name in self.params:
if self.params[name].attribute and name in kw:
@@ -583,27 +544,6 @@ class Command(HasParam):
else:
yield (name, kw[name])
- adddict = {}
- if kw.get('setattr'):
- adddict = self.__convert_2_dict(kw['setattr'], append=False)
-
- if kw.get('addattr'):
- for (k, v) in self.__convert_2_dict(kw['addattr']).iteritems():
- if k in adddict:
- adddict[k] += v
- else:
- adddict[k] = v
-
- for name in adddict:
- value = adddict[name]
- if isinstance(value, list):
- if len(value) == 1:
- yield (name, value[0])
- else:
- yield (name, [v for v in value])
- else:
- yield (name, value)
-
def params_2_args_options(self, **params):
"""
Split params into (args, options).
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 4fd5fe4a1..1766077be 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -26,7 +26,7 @@ import time
from copy import deepcopy
from ipalib import api, crud, errors
-from ipalib import Method, Object
+from ipalib import Method, Object, Command
from ipalib import Flag, Int, List, Str
from ipalib.base import NameSpace
from ipalib.cli import to_cli, from_cli
@@ -175,23 +175,14 @@ def validate_add_attribute(ugettext, attr):
def validate_set_attribute(ugettext, attr):
validate_attribute(ugettext, 'setattr', attr)
+def validate_del_attribute(ugettext, attr):
+ validate_attribute(ugettext, 'delattr', attr)
+
def validate_attribute(ugettext, name, attr):
m = re.match("\s*(.*?)\s*=\s*(.*?)\s*$", attr)
if not m or len(m.groups()) != 2:
raise errors.ValidationError(name=name, error='Invalid format. Should be name=value')
-def get_attributes(attrs):
- """
- Given a list of values in the form name=value, return a list of name.
- """
- attrlist=[]
- if attrs:
- for attr in attrs:
- m = re.match("\s*(.*?)\s*=\s*(.*?)\s*$", attr)
- attrlist.append(str(m.group(1)).lower())
- return attrlist
-
-
def get_effective_rights(ldap, dn, attrs=None):
if attrs is None:
attrs = ['*', 'nsaccountlock', 'cospriority']
@@ -498,21 +489,6 @@ class LDAPObject(Object):
return json_dict
-# Options used by create and update.
-_attr_options = (
- Str('addattr*', validate_add_attribute,
- cli_name='addattr',
- doc=_('Add an attribute/value pair. Format is attr=value. The attribute must be part of the schema.'),
- exclude='webui',
- ),
- Str('setattr*', validate_set_attribute,
- cli_name='setattr',
- doc=_("""Set an attribute to a name/value pair. Format is attr=value.
-For multi-valued attributes, the command replaces the values already present."""),
- exclude='webui',
- ),
-)
-
# addattr can cause parameters to have more than one value even if not defined
# as multivalue, make sure this isn't the case
def _check_single_value_attrs(params, entry_attrs):
@@ -647,11 +623,169 @@ class CallbackInterface(Method):
return rv
-class LDAPCreate(CallbackInterface, crud.Create):
+class BaseLDAPCommand(CallbackInterface, Command):
+ """
+ Base class for Base LDAP Commands.
+ """
+ setattr_option = Str('setattr*', validate_set_attribute,
+ cli_name='setattr',
+ doc=_("""Set an attribute to a name/value pair. Format is attr=value.
+For multi-valued attributes, the command replaces the values already present."""),
+ exclude='webui',
+ )
+ addattr_option = Str('addattr*', validate_add_attribute,
+ cli_name='addattr',
+ doc=_("""Add an attribute/value pair. Format is attr=value. The attribute
+must be part of the schema."""),
+ exclude='webui',
+ )
+ delattr_option = Str('delattr*', validate_del_attribute,
+ cli_name='delattr',
+ doc=_("""Delete an attribute/value pair. The option will be evaluated
+last, after all sets and adds."""),
+ exclude='webui',
+ )
+
+ def _convert_2_dict(self, attrs, append=True):
+ """
+ Convert a string in the form of name/value pairs into a dictionary.
+ The incoming attribute may be a string or a list.
+
+ Any attribute found that is also a param is validated.
+
+ :param attrs: A list of name/value pairs
+
+ :param append: controls whether this returns a list of values or a single
+ value.
+ """
+ newdict = {}
+ if not type(attrs) in (list, tuple):
+ attrs = [attrs]
+ for a in attrs:
+ m = re.match("\s*(.*?)\s*=\s*(.*?)\s*$", a)
+ attr = str(m.group(1)).lower()
+ value = m.group(2)
+ if len(value) == 0:
+ # None means "delete this attribute"
+ value = None
+ if attr in self.params:
+ try:
+ value = self.params[attr](value)
+ except errors.ValidationError, err:
+ (name, error) = str(err.strerror).split(':')
+ raise errors.ValidationError(name=attr, error=error)
+ if append and attr in newdict:
+ if type(value) in (tuple,):
+ newdict[attr] += list(value)
+ else:
+ newdict[attr].append(value)
+ else:
+ if type(value) in (tuple,):
+ newdict[attr] = list(value)
+ else:
+ newdict[attr] = [value]
+ return newdict
+
+ def process_attr_options(self, entry_attrs, dn, keys, options):
+ """
+ Process all --setattr, --addattr, and --delattr options and add the
+ resulting value to the list of attributes. --setattr is processed first,
+ then --addattr and finally --delattr.
+
+ When --setattr is not used then the original LDAP object is looked up
+ (of course, not when dn is None) and the changes are applied to old
+ object values.
+
+ Attribute values deleted by --delattr may be deleted from attribute
+ values set or added by --setattr, --addattr. For example, the following
+ attributes will result in a NOOP:
+
+ --addattr=attribute=foo --delattr=attribute=foo
+
+ AttrValueNotFound exception may be raised when an attribute value was
+ not found either by --setattr and --addattr nor in existing LDAP object.
+
+ :param entry_attrs: A list of attributes that will be updated
+ :param dn: dn of updated LDAP object or None if a new object is created
+ :param keys: List of command arguments
+ :param options: List of options
+ """
+ if all(k not in options for k in ("setattr", "addattr", "delattr")):
+ return
+
+ ldap = self.obj.backend
+
+ adddict = self._convert_2_dict(options.get('addattr', []))
+ setdict = self._convert_2_dict(options.get('setattr', []))
+ deldict = self._convert_2_dict(options.get('delattr', []))
+
+ setattrs = set(setdict.keys())
+ addattrs = set(adddict.keys())
+ delattrs = set(deldict.keys())
+
+ if dn is None:
+ direct_add = addattrs
+ direct_del = delattrs
+ needldapattrs = []
+ else:
+ direct_add = setattrs & addattrs
+ direct_del = setattrs & delattrs
+ needldapattrs = list((addattrs | delattrs) - setattrs)
+
+ for attr, val in setdict.iteritems():
+ entry_attrs[attr] = val
+
+ for attr in direct_add:
+ entry_attrs.setdefault(attr, []).extend(adddict[attr])
+
+ for attr in direct_del:
+ for delval in deldict[attr]:
+ try:
+ entry_attrs[attr].remove(delval)
+ except ValueError:
+ raise errors.AttrValueNotFound(attr=attr,
+ value=delval)
+
+ if needldapattrs:
+ try:
+ (dn, old_entry) = ldap.get_entry(
+ dn, needldapattrs, normalize=self.obj.normalize_dn
+ )
+ except errors.ExecutionError, e:
+ try:
+ (dn, old_entry) = self._call_exc_callbacks(
+ keys, options, e, ldap.get_entry, dn, [],
+ normalize=self.obj.normalize_dn
+ )
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ for attr in needldapattrs:
+ entry_attrs[attr] = old_entry.get(attr, [])
+
+ if attr in addattrs:
+ entry_attrs[attr].extend(adddict.get(attr, []))
+
+ for delval in deldict.get(attr, []):
+ try:
+ entry_attrs[attr].remove(delval)
+ except ValueError:
+ raise errors.AttrValueNotFound(attr=attr, value=delval)
+
+ # normalize all values
+ changedattrs = setattrs | addattrs | delattrs
+ for attr in changedattrs:
+ # remove duplicite and invalid values
+ entry_attrs[attr] = list(set([val for val in entry_attrs[attr] if val]))
+ if not entry_attrs[attr]:
+ entry_attrs[attr] = None
+ elif len(entry_attrs[attr]) == 1:
+ entry_attrs[attr] = entry_attrs[attr][0]
+
+class LDAPCreate(BaseLDAPCommand, crud.Create):
"""
Create a new entry in LDAP.
"""
- takes_options = _attr_options
+ takes_options = (BaseLDAPCommand.setattr_option, BaseLDAPCommand.addattr_option)
def get_args(self):
#pylint: disable=E1003
@@ -668,6 +802,9 @@ class LDAPCreate(CallbackInterface, crud.Create):
ldap = self.obj.backend
entry_attrs = self.args_options_2_entry(*keys, **options)
+
+ self.process_attr_options(entry_attrs, None, keys, options)
+
entry_attrs['objectclass'] = deepcopy(self.obj.object_class)
if self.obj.object_class_config:
@@ -794,7 +931,7 @@ class LDAPCreate(CallbackInterface, crud.Create):
)
return json_dict
-class LDAPQuery(CallbackInterface, crud.PKQuery):
+class LDAPQuery(BaseLDAPCommand, crud.PKQuery):
"""
Base class for commands that need to retrieve an existing entry.
"""
@@ -917,7 +1054,10 @@ class LDAPUpdate(LDAPQuery, crud.Update):
Update an LDAP entry.
"""
- takes_options = _attr_options + (
+ takes_options = (
+ BaseLDAPCommand.setattr_option,
+ BaseLDAPCommand.addattr_option,
+ BaseLDAPCommand.delattr_option,
Flag('rights',
label=_('Rights'),
doc=_('Display the access rights of this entry (requires --all). See ipa man page for details.'),
@@ -951,34 +1091,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
entry_attrs = self.args_options_2_entry(**options)
- """
- Some special handling is needed because we need to update the
- values here rather than letting ldap.update_entry() do the work. We
- have to do the work of adding new values to an existing attribute
- because if we pass just what is addded only the new values get
- set.
- """
- if 'addattr' in options:
- setset = set(get_attributes(options.get('setattr', [])))
- addset = set(get_attributes(options.get('addattr', [])))
- difflist = list(addset.difference(setset))
- if difflist:
- try:
- (dn, old_entry) = ldap.get_entry(
- dn, difflist, normalize=self.obj.normalize_dn
- )
- except errors.ExecutionError, e:
- try:
- (dn, old_entry) = self._call_exc_callbacks(
- keys, options, e, ldap.get_entry, dn, [],
- normalize=self.obj.normalize_dn
- )
- except errors.NotFound:
- self.obj.handle_not_found(*keys)
- for a in old_entry:
- if not isinstance(entry_attrs[a], (list, tuple)):
- entry_attrs[a] = [entry_attrs[a]]
- entry_attrs[a] = list(entry_attrs[a]) + old_entry[a]
+ self.process_attr_options(entry_attrs, dn, keys, options)
if options.get('all', False):
attrs_list = ['*'] + self.obj.default_attributes
@@ -1426,7 +1539,7 @@ class LDAPRemoveMember(LDAPModMember):
return
-class LDAPSearch(CallbackInterface, crud.Search):
+class LDAPSearch(BaseLDAPCommand, crud.Search):
"""
Retrieve all LDAP entries matching the given criteria.
"""
diff --git a/tests/test_xmlrpc/test_attr.py b/tests/test_xmlrpc/test_attr.py
index 11aaa01e3..ef239709d 100644
--- a/tests/test_xmlrpc/test_attr.py
+++ b/tests/test_xmlrpc/test_attr.py
@@ -210,6 +210,128 @@ class test_attr(Declarative):
dict(
+ desc='Delete one phone number for %r' % user1,
+ command=(
+ 'user_mod', [user1], dict(delattr=u'telephoneNumber=301-555-1212')
+ ),
+ expected=dict(
+ result=dict(
+ givenname=[u'Finkle'],
+ homedirectory=[u'/home/tuser1'],
+ loginshell=[u'/bin/sh'],
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ gidnumber=[fuzzy_digits],
+ mail=[u'test@example.com', u'test2@example.com'],
+ memberof_group=[u'ipausers'],
+ telephonenumber=[u'202-888-9833', u'703-555-1212'],
+ nsaccountlock=False,
+ has_keytab=False,
+ has_password=False,
+ ),
+ summary=u'Modified user "tuser1"',
+ value=user1,
+ ),
+ ),
+
+
+ dict(
+ desc='Try deleting the number again for %r' % user1,
+ command=(
+ 'user_mod', [user1], dict(delattr=u'telephoneNumber=301-555-1212')
+ ),
+ expected=errors.AttrValueNotFound(attr='telephoneNumber', value='301-555-1212')
+ ),
+
+
+ dict(
+ desc='Add and delete one phone number for %r' % user1,
+ command=(
+ 'user_mod', [user1], dict(addattr=u'telephoneNumber=301-555-1212',
+ delattr=u'telephoneNumber=202-888-9833')
+ ),
+ expected=dict(
+ result=dict(
+ givenname=[u'Finkle'],
+ homedirectory=[u'/home/tuser1'],
+ loginshell=[u'/bin/sh'],
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ gidnumber=[fuzzy_digits],
+ mail=[u'test@example.com', u'test2@example.com'],
+ memberof_group=[u'ipausers'],
+ telephonenumber=[u'301-555-1212', u'703-555-1212'],
+ nsaccountlock=False,
+ has_keytab=False,
+ has_password=False,
+ ),
+ summary=u'Modified user "tuser1"',
+ value=user1,
+ ),
+ ),
+
+
+ dict(
+ desc='Add and delete the same phone number for %r' % user1,
+ command=(
+ 'user_mod', [user1], dict(addattr=(u'telephoneNumber=301-555-1212',
+ u'telephoneNumber=202-888-9833'),
+ delattr=u'telephoneNumber=301-555-1212')
+ ),
+ expected=dict(
+ result=dict(
+ givenname=[u'Finkle'],
+ homedirectory=[u'/home/tuser1'],
+ loginshell=[u'/bin/sh'],
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ gidnumber=[fuzzy_digits],
+ mail=[u'test@example.com', u'test2@example.com'],
+ memberof_group=[u'ipausers'],
+ telephonenumber=[u'703-555-1212', u'301-555-1212', u'202-888-9833'],
+ nsaccountlock=False,
+ has_keytab=False,
+ has_password=False,
+ ),
+ summary=u'Modified user "tuser1"',
+ value=user1,
+ ),
+ ),
+
+
+ dict(
+ desc='Set and delete the a phone number for %r' % user1,
+ command=(
+ 'user_mod', [user1], dict(setattr=(u'telephoneNumber=301-555-1212',
+ u'telephoneNumber=202-888-9833'),
+ delattr=u'telephoneNumber=301-555-1212')
+ ),
+ expected=dict(
+ result=dict(
+ givenname=[u'Finkle'],
+ homedirectory=[u'/home/tuser1'],
+ loginshell=[u'/bin/sh'],
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ gidnumber=[fuzzy_digits],
+ mail=[u'test@example.com', u'test2@example.com'],
+ memberof_group=[u'ipausers'],
+ telephonenumber=[u'202-888-9833'],
+ nsaccountlock=False,
+ has_keytab=False,
+ has_password=False,
+ ),
+ summary=u'Modified user "tuser1"',
+ value=user1,
+ ),
+ ),
+
+
+ dict(
desc='Try setting givenname to None with setattr in %r' % user1,
command=(
'user_mod', [user1], dict(setattr=(u'givenname='))
@@ -243,7 +365,7 @@ class test_attr(Declarative):
gidnumber=[fuzzy_digits],
mail=[u'test@example.com', u'test2@example.com'],
memberof_group=[u'ipausers'],
- telephonenumber=[u'301-555-1212', u'202-888-9833', u'703-555-1212'],
+ telephonenumber=[u'202-888-9833'],
nsaccountlock=False,
has_keytab=False,
has_password=False,
@@ -270,7 +392,7 @@ class test_attr(Declarative):
gidnumber=[fuzzy_digits],
mail=[u'test@example.com', u'test2@example.com'],
memberof_group=[u'ipausers'],
- telephonenumber=[u'301-555-1212', u'202-888-9833', u'703-555-1212'],
+ telephonenumber=[u'202-888-9833'],
nsaccountlock=False,
has_keytab=False,
has_password=False,
diff --git a/tests/test_xmlrpc/test_group_plugin.py b/tests/test_xmlrpc/test_group_plugin.py
index 6403251e6..86c0d90da 100644
--- a/tests/test_xmlrpc/test_group_plugin.py
+++ b/tests/test_xmlrpc/test_group_plugin.py
@@ -755,6 +755,10 @@ class test_group(Declarative):
dn=lambda x: DN(x) == \
DN(('uid','tuser1'),('cn','users'),('cn','accounts'),
api.env.basedn),
+ krbpwdpolicyreference=lambda x: [DN(i) for i in x] == \
+ [DN(('cn','global_policy'),('cn',api.env.realm),
+ ('cn','kerberos'),api.env.basedn)],
+ memberof_group=[u'ipausers'],
has_keytab=False,
has_password=False,
),