diff options
-rw-r--r-- | API.txt | 52 | ||||
-rw-r--r-- | ipalib/constants.py | 3 | ||||
-rw-r--r-- | ipalib/plugins/range.py | 140 | ||||
-rw-r--r-- | tests/test_xmlrpc/test_range_plugin.py | 79 |
4 files changed, 273 insertions, 1 deletions
@@ -2367,6 +2367,58 @@ option: Str('version?', exclude='webui') output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None)) output: Output('value', <type 'unicode'>, None) +command: range_add +args: 1,10,3 +arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True) +option: Int('ipabaseid', attribute=True, cli_name='base_id', multivalue=False, required=True) +option: Int('ipaidrangesize', attribute=True, cli_name='range_size', multivalue=False, required=True) +option: Int('ipabaserid', attribute=True, cli_name='rid_base', multivalue=False, required=True) +option: Int('ipasecondarybaserid', attribute=True, cli_name='secondary_rid_base', multivalue=False, required=False) +option: Str('ipanttrusteddomainsid', attribute=True, cli_name='dom_sid', multivalue=False, required=False) +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') +output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) +output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None)) +output: Output('value', <type 'unicode'>, None) +command: range_del +args: 1,1,3 +arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True) +option: Flag('continue', autofill=True, cli_name='continue', default=False) +output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) +output: Output('result', <type 'dict'>, None) +output: Output('value', <type 'unicode'>, None) +command: range_find +args: 1,12,4 +arg: Str('criteria?', noextrawhitespace=False) +option: Str('cn', attribute=True, autofill=False, cli_name='name', multivalue=False, primary_key=True, query=True, required=False) +option: Int('ipabaseid', attribute=True, autofill=False, cli_name='base_id', multivalue=False, query=True, required=False) +option: Int('ipaidrangesize', attribute=True, autofill=False, cli_name='range_size', multivalue=False, query=True, required=False) +option: Int('ipabaserid', attribute=True, autofill=False, cli_name='rid_base', multivalue=False, query=True, required=False) +option: Int('ipasecondarybaserid', attribute=True, autofill=False, cli_name='secondary_rid_base', multivalue=False, query=True, required=False) +option: Str('ipanttrusteddomainsid', attribute=True, autofill=False, cli_name='dom_sid', multivalue=False, query=True, required=False) +option: Int('timelimit?', autofill=False, minvalue=0) +option: Int('sizelimit?', autofill=False, minvalue=0) +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') +option: Flag('pkey_only?', autofill=True, default=False) +output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) +output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None)) +output: Output('count', <type 'int'>, None) +output: Output('truncated', <type 'bool'>, None) +command: range_show +args: 1,4,3 +arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True) +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') +option: Str('version?', exclude='webui') +output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) +output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None)) +output: Output('value', <type 'unicode'>, None) command: role_add args: 1,6,3 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True) diff --git a/ipalib/constants.py b/ipalib/constants.py index 8f87a18ee..f503472c9 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -104,7 +104,8 @@ DEFAULT_CONFIG = ( ('container_cifsdomains', 'cn=ad,cn=etc'), ('container_trusts', 'cn=trusts'), ('container_adtrusts', 'cn=ad,cn=trusts'), - + ('container_ranges', 'cn=ranges,cn=etc'), + # Ports, hosts, and URIs: # FIXME: let's renamed xmlrpc_uri to rpc_xml_uri ('xmlrpc_uri', 'http://localhost:8888/ipa/xml'), diff --git a/ipalib/plugins/range.py b/ipalib/plugins/range.py new file mode 100644 index 000000000..4448aad81 --- /dev/null +++ b/ipalib/plugins/range.py @@ -0,0 +1,140 @@ +# Authors: +# Sumit Bose <sbose@redhat.com> +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from ipalib.plugins.baseldap import * +from ipalib import api, Str, Password, DefaultFrom, _, ngettext, Object +from ipalib.parameters import Enum +from ipalib import Command +from ipalib import errors +from ipapython import ipautil +from ipalib import util + + +__doc__ = _(""" +Manage ID ranges +""") + +class range(LDAPObject): + """ + Range object. + """ + + range_type = ('domain', 'ad', 'ipa') + container_dn = api.env.container_ranges + object_name = ('range') + object_name_plural = ('ranges') + object_class = ['ipaIDrange'] + possible_objectclasses = ['ipadomainidrange', 'ipatrustedaddomainrange'] + default_attributes = ['cn', 'ipabaseid', 'ipaidrangesize', 'ipabaserid', + 'ipasecondarybaserid', 'ipanttrusteddomainsid', + 'iparangetype'] + + label = _('Ranges') + label_singular = _('Range') + + takes_params = ( + Str('cn', + cli_name='name', + label=_('Range name'), + primary_key=True, + ), + Int('ipabaseid', + cli_name='base_id', + label=_("First Posix ID of the range"), + ), + Int('ipaidrangesize', + cli_name='range_size', + label=_("Number of IDs in the range"), + ), + Int('ipabaserid', + cli_name='rid_base', + label=_('First RID of the corresponding RID range'), + ), + Int('ipasecondarybaserid?', + cli_name='secondary_rid_base', + label=_('First RID of the secondary RID range'), + ), + Str('ipanttrusteddomainsid?', + cli_name='dom_sid', + label=_('Domain SID of the trusted domain'), + ), + Str('iparangetype?', + label=_('Range type'), + flags=['no_option'], + ) + ) + +class range_add(LDAPCreate): + __doc__ = _('Add new ID range.') + + msg_summary = _('Added ID range "%(value)s"') + + def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): + if ('ipanttrusteddomainsid' not in options and + 'ipasecondarybaserid' not in options): + raise errors.ValidationError(name=_('Range setup'), + error=_('Ranges for local domain ' \ + 'must have a secondary RID base')) + + if 'ipanttrusteddomainsid' in options: + entry_attrs['objectclass'].append('ipatrustedaddomainrange') + else: + entry_attrs['objectclass'].append('ipadomainidrange') + + return dn + +class range_del(LDAPDelete): + __doc__ = _('Delete an ID range.') + + msg_summary = _('Deleted ID range "%(value)s"') + +class range_find(LDAPSearch): + __doc__ = _('Search for ranges.') + + msg_summary = ngettext( + '%(count)d range matched', '%(count)d ranges matched', 0 + ) + + # Since all range types are stored within separate containers under + # 'cn=ranges,cn=etc' search can be done on a one-level scope + def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options): + return (filters, base_dn, ldap.SCOPE_ONELEVEL) + +class range_show(LDAPRetrieve): + __doc__ = _('Display information about a range.') + + def pre_callback(self, ldap, dn, attrs_list, *keys, **options): + attrs_list.append('objectclass') + return dn + + def post_callback(self, ldap, dn, entry_attrs, *keys, **options): + if 'ipatrustedaddomainrange' in entry_attrs['objectclass']: + entry_attrs['iparangetype']=(u'Active Directory domain range') + else: + entry_attrs['iparangetype']=(u'local domain range') + del entry_attrs['objectclass'] + return dn + +api.register(range) +api.register(range_add) +#api.register(range_mod) +api.register(range_del) +api.register(range_find) +api.register(range_show) + diff --git a/tests/test_xmlrpc/test_range_plugin.py b/tests/test_xmlrpc/test_range_plugin.py new file mode 100644 index 000000000..7c95cd57a --- /dev/null +++ b/tests/test_xmlrpc/test_range_plugin.py @@ -0,0 +1,79 @@ +# Authors: +# Alexander Bokovoy <abokovoy@redhat.com> +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +""" +Test the `ipalib/plugins/range.py` module, and XML-RPC in general. +""" + +from ipalib import api, errors, _ +from tests.util import assert_equal, Fuzzy +from xmlrpc_test import Declarative +from ipalib.dn import * + +testrange1 = u't-range-1' + +class test_range(Declarative): + cleanup_commands = [ + ('range_del', [testrange1], {}), + ] + + tests = [ + dict( + desc='Create range %r' % (testrange1), + command=('range_add', [testrange1], + dict(ipabaseid=900000, ipaidrangesize=99999, + ipabaserid=1000, ipasecondarybaserid=20000)), + expected=dict( + result=dict( + dn=lambda x: DN(x) == \ + DN(('cn',testrange1),('cn','ranges'),('cn','etc'), + api.env.basedn), + cn=[testrange1], + objectclass=[u'ipaIDrange', u'ipadomainidrange'], + ipabaseid=[u'900000'], + ipabaserid=[u'1000'], + ipasecondarybaserid=[u'20000'], + ipaidrangesize=[u'99999'] + ), + value=testrange1, + summary=u'Added ID range "%s"' % (testrange1), + ), + ), + + dict( + desc='Retrieve range %r' % (testrange1), + command=('range_show', [testrange1], dict()), + expected=dict( + result=dict( + dn=lambda x: DN(x) == \ + DN(('cn',testrange1),('cn','ranges'),('cn','etc'), + api.env.basedn), + cn=[testrange1], + ipabaseid=[u'900000'], + ipabaserid=[u'1000'], + ipasecondarybaserid=[u'20000'], + ipaidrangesize=[u'99999'], + iparangetype=u'local domain range', + ), + value=testrange1, + summary=None, + ), + ), + + ] |