From d223a74a591245cd7c30cb87ae7ad2cf6328f7f9 Mon Sep 17 00:00:00 2001 From: Martin Kosek Date: Jan 11 2012 17:04:18 +0000 Subject: 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 --- diff --git a/API.txt b/API.txt index 135b079..72e7025 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', , 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', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', , None) output: Output('methods', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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', (, ), Gettext('A list output: Output('count', , None) output: Output('truncated', , 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 f1010bf..4ea4f9d 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 2ab457c..b79aad9 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 4fd5fe4..1766077 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 11aaa01..ef23970 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 6403251..86c0d90 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, ),