summaryrefslogtreecommitdiffstats
path: root/ipaserver/install/plugins/rename_managed.py
diff options
context:
space:
mode:
Diffstat (limited to 'ipaserver/install/plugins/rename_managed.py')
-rw-r--r--ipaserver/install/plugins/rename_managed.py159
1 files changed, 96 insertions, 63 deletions
diff --git a/ipaserver/install/plugins/rename_managed.py b/ipaserver/install/plugins/rename_managed.py
index a9eed0be3..99dac8148 100644
--- a/ipaserver/install/plugins/rename_managed.py
+++ b/ipaserver/install/plugins/rename_managed.py
@@ -24,6 +24,7 @@ from ipalib.frontend import Updater
from ipaserver.install.plugins import baseupdate
from ipalib import api, errors
from ipapython import ipautil
+from ipapython.dn import DN, EditableDN
import ldap as _ldap
def entry_to_update(entry):
@@ -44,67 +45,99 @@ def entry_to_update(entry):
return update
-def generate_update(ldap, deletes=False):
- """
- We need to separate the deletes that need to happen from the
- new entries that need to be added.
- """
- suffix = ipautil.realm_to_suffix(api.env.realm)
- searchfilter = '(objectclass=*)'
- definitions_managed_entries = []
- old_template_container = 'cn=etc,%s' % suffix
- old_definition_container = 'cn=managed entries,cn=plugins,cn=config'
- new = 'cn=Managed Entries,cn=etc,%s' % suffix
- sub = ['cn=Definitions,', 'cn=Templates,']
- new_managed_entries = []
- old_templates = []
- template = None
- restart = False
-
- # If the old entries don't exist the server has already been updated.
- try:
- (definitions_managed_entries, truncated) = ldap.find_entries(
- searchfilter, ['*'], old_definition_container, _ldap.SCOPE_ONELEVEL, normalize=False
- )
- except errors.NotFound, e:
- return (False, new_managed_entries)
-
- for entry in definitions_managed_entries:
- new_definition = {}
- definition_managed_entry_updates = {}
- if deletes:
- old_definition = {'dn': str(entry[0]), 'deleteentry': ['dn: %s' % str(entry[0])]}
- old_template = str(entry[1]['managedtemplate'][0])
- definition_managed_entry_updates[old_definition['dn']] = old_definition
- old_templates.append(old_template)
- else:
- entry[1]['managedtemplate'] = str(entry[1]['managedtemplate'][0].replace(old_template_container, sub[1] + new))
- new_definition['dn'] = str(entry[0].replace(old_definition_container, sub[0] + new))
- new_definition['default'] = entry_to_update(entry[1])
- definition_managed_entry_updates[new_definition['dn']] = new_definition
- new_managed_entries.append(definition_managed_entry_updates)
- for old_template in old_templates: # Only happens when deletes is True
- try:
- (dn, template) = ldap.get_entry(old_template, ['*'], normalize=False)
- dn = str(dn)
- new_template = {}
- template_managed_entry_updates = {}
- old_template = {'dn': dn, 'deleteentry': ['dn: %s' % dn]}
- new_template['dn'] = str(dn.replace(old_template_container, sub[1] + new))
- new_template['default'] = entry_to_update(template)
- template_managed_entry_updates[new_template['dn']] = new_template
- template_managed_entry_updates[old_template['dn']] = old_template
- new_managed_entries.append(template_managed_entry_updates)
- except errors.NotFound, e:
- pass
+class GenerateUpdateMixin(object):
+ def generate_update(self, deletes=False):
+ """
+ We need to separate the deletes that need to happen from the
+ new entries that need to be added.
+ """
+ ldap = self.obj.backend
- if len(new_managed_entries) > 0:
- restart = True
- new_managed_entries.sort(reverse=True)
+ suffix = ipautil.realm_to_suffix(api.env.realm)
+ searchfilter = '(objectclass=*)'
+ definitions_managed_entries = []
- return (restart, new_managed_entries)
+ old_template_container = DN(('cn', 'etc'), suffix)
+ new_template_container = DN(('cn', 'Templates'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix)
-class update_managed_post_first(PreUpdate):
+ old_definition_container = DN(('cn', 'managed entries'), ('cn', 'plugins'), ('cn', 'config'), suffix)
+ new_definition_container = DN(('cn', 'Definitions'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix)
+
+ definitions_dn = DN(('cn', 'Definitions'))
+ update_list = []
+ restart = False
+
+ # If the old entries don't exist the server has already been updated.
+ try:
+ (definitions_managed_entries, truncated) = ldap.find_entries(
+ searchfilter, ['*'], old_definition_container, _ldap.SCOPE_ONELEVEL, normalize=False
+ )
+ except errors.NotFound, e:
+ return (False, update_list)
+
+ for entry in definitions_managed_entries:
+ assert isinstance(entry.dn, DN)
+ if deletes:
+ old_dn = entry.data['managedtemplate'][0]
+ assert isinstance(old_dn, DN)
+ try:
+ (old_dn, entry) = ldap.get_entry(old_dn, ['*'], normalize=False)
+ except errors.NotFound, e:
+ pass
+ else:
+ # Compute the new dn by replacing the old container with the new container
+ new_dn = EditableDN(old_dn)
+ if new_dn.replace(old_template_container, new_template_container) != 1:
+ self.error("unable to replace '%s' with '%s' in '%s'",
+ old_template_container, new_template_container, old_dn)
+ continue
+
+ new_dn = DN(new_dn)
+
+ # The old attributes become defaults for the new entry
+ new_update = {'dn': new_dn,
+ 'default': entry_to_update(entry)}
+
+ # Delete the old entry
+ old_update = {'dn': old_dn, 'deleteentry': None}
+
+ # Add the delete and replacement updates to the list of all updates
+ update_list.append({old_dn: old_update, new_dn: new_update})
+
+ else:
+ # Update the template dn by replacing the old containter with the new container
+ old_dn = entry.data['managedtemplate'][0]
+ new_dn = EditableDN(old_dn)
+ if new_dn.replace(old_template_container, new_template_container) != 1:
+ self.error("unable to replace '%s' with '%s' in '%s'",
+ old_template_container, new_template_container, old_dn)
+ continue
+ new_dn = DN(new_dn)
+ entry.data['managedtemplate'] = new_dn
+
+ # Edit the dn, then convert it back to an immutable DN
+ old_dn = entry.dn
+ new_dn = EditableDN(old_dn)
+ if new_dn.replace(old_definition_container, new_definition_container) != 1:
+ self.error("unable to replace '%s' with '%s' in '%s'",
+ old_definition_container, new_definition_container, old_dn)
+ continue
+ new_dn = DN(new_dn)
+
+ # The old attributes become defaults for the new entry
+ new_update = {'dn': new_dn,
+ 'default': entry_to_update(entry.data)}
+
+ # Add the replacement update to the collection of all updates
+ update_list.append({new_dn: new_update})
+
+ if len(update_list) > 0:
+ restart = True
+ update_list.sort(reverse=True)
+
+ return (restart, update_list)
+
+class update_managed_post_first(PreUpdate, GenerateUpdateMixin):
"""
Update managed entries
"""
@@ -112,21 +145,21 @@ class update_managed_post_first(PreUpdate):
def execute(self, **options):
# Never need to restart with the pre-update changes
- (ignore, new_managed_entries) = generate_update(self.obj.backend, False)
+ (ignore, update_list) = self.generate_update(False)
- return (False, True, new_managed_entries)
+ return (False, True, update_list)
api.register(update_managed_post_first)
-class update_managed_post(PostUpdate):
+class update_managed_post(PostUpdate, GenerateUpdateMixin):
"""
Update managed entries
"""
order=LAST
def execute(self, **options):
- (restart, new_managed_entries) = generate_update(self.obj.backend, True)
+ (restart, update_list) = self.generate_update(True)
- return (restart, True, new_managed_entries)
+ return (restart, True, update_list)
api.register(update_managed_post)