Hi, all,

This is my first patch, which fixes Ticket #2547 at https://fedorahosted.org/freeipa/ticket/2547

It introduces a --scope option to "ipa migrate-ds" which allows the user to specify the search depth of a migration. The previous default behavior is the same as --scope=onelevel. To search nested OUs, the user uses --scope=subtree. --scope=base will cause the migrate script not to find anything, but has been included for completeness. Any other option is invalid and will cause the command to abort.

Please review this one carefully, because I'm only like 98% confident it doesn't break anything. The only thing I'm not sure about is that if you run ipa migrate-ds without --scope specified, it gives an interactive input for that option; I'm not sure if it's supposed to do that.


Drew Erny
From b50522be44ade6af8ddd24f33eac100af67bc101 Mon Sep 17 00:00:00 2001
From: Drew Erny <dpe...@crimson.ua.edu>
Date: Wed, 27 May 2015 09:52:42 -0400
Subject: [PATCH] Migration now accepts scope as argument

Adds a new option to command ipa migrate-ds,
--scope=[base,onelevel,subtree], which allows the user to specify LDAP
search depth for users and groups. 'onelevel' was the previous default
level. Specify 'subtree' to to search nested OUs for users and groups.

 API.txt                     |  3 ++-
 ipalib/plugins/migration.py | 18 +++++++++++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/API.txt b/API.txt
index d987bc949948a280018f0f20d5af93838ecaeb20..f8f0bb1955b21385d85e59d7683698a30ca37181 100644
--- a/API.txt
+++ b/API.txt
@@ -2450,7 +2450,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: migrate_ds
-args: 2,18,4
+args: 2,19,4
 arg: Str('ldapuri', cli_name='ldap_uri')
 arg: Password('bindpw', cli_name='password', confirm=False)
 option: DNParam('basedn?', cli_name='base_dn')
@@ -2466,6 +2466,7 @@ option: Str('groupignoreobjectclass*', autofill=True, cli_name='group_ignore_obj
 option: Str('groupobjectclass+', autofill=True, cli_name='group_objectclass', csv=True, default=(u'groupOfUniqueNames', u'groupOfNames'))
 option: Flag('groupoverwritegid', autofill=True, cli_name='group_overwrite_gid', default=False)
 option: StrEnum('schema?', autofill=True, cli_name='schema', default=u'RFC2307bis', values=(u'RFC2307bis', u'RFC2307'))
+option: StrEnum('scope', cli_name='scope', default=u'onelevel', values=(u'base', u'onelevel', u'subtree'))
 option: DNParam('usercontainer', autofill=True, cli_name='user_container', default=ipapython.dn.DN('ou=people'))
 option: Str('userignoreattribute*', autofill=True, cli_name='user_ignore_attribute', csv=True, default=())
 option: Str('userignoreobjectclass*', autofill=True, cli_name='user_ignore_objectclass', csv=True, default=())
diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index c8379420d539ac35901d99f981b4c8e2f0f89ffc..da23d287afd9e21cb2e5f3edec9abfa9b98f0af4 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -139,6 +139,7 @@ _ref_err_msg = _('Migration of LDAP search reference is not supported.')
 _dn_err_msg = _('Malformed DN')
 _supported_schemas = (u'RFC2307bis', u'RFC2307')
+_supported_scopes = (u'base', u'onelevel', u'subtree')
 def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
@@ -607,6 +608,14 @@ class migrate_ds(Command):
             doc=_('Load CA certificate of LDAP server from FILE'),
+        StrEnum('scope',
+            cli_name='scope',
+            label=_('Search scope'),
+            doc=_('LDAP search scope for users and groups: base, onelevel, or '\
+                  'subtree. Defaults to onelevel'),
+            values=_supported_scopes,
+            default=_supported_scopes[1],
+        ),
     has_output = (
@@ -711,13 +720,20 @@ can use their Kerberos accounts.''')
             exclude = options['exclude_%ss' % to_cli(ldap_obj_name)]
             context = dict(ds_ldap = ds_ldap)
+            if options.get('scope') == 'base':
+                scope = ds_ldap.SCOPE_BASE
+            elif options.get('scope') == 'subtree':
+                scope = ds_ldap.SCOPE_SUBTREE
+            else:
+                scope = ds_ldap.SCOPE_ONELEVEL
             migrated[ldap_obj_name] = []
             failed[ldap_obj_name] = {}
                 entries, truncated = ds_ldap.find_entries(
                     search_filter, ['*'], search_bases[ldap_obj_name],
-                    ds_ldap.SCOPE_ONELEVEL,
+                    scope,
                     time_limit=0, size_limit=-1,
                     search_refs=True    # migrated DS may contain search references

Manage your subscription for the Freeipa-devel mailing list:
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to