Files
freeipa/ipaserver/install/plugins/rename_managed.py
T
Petr Viktorin 5178e9a597 Modernize use of range()
In Python 3, range() behaves like the old xrange().
The difference between range() and xrange() is usually not significant,
especially if the whole result is iterated over.

Convert xrange() usage to range() for small ranges.
Use modern idioms in a few other uses of range().

Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
2015-09-01 11:42:01 +02:00

172 lines
6.2 KiB
Python

# Authors:
# Rob Crittenden <rcritten@redhat.com>
#
# Copyright (C) 2011 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 import api, errors
from ipalib import Updater
from ipapython import ipautil
from ipapython.dn import DN
def entry_to_update(entry):
"""
Convert an entry into a name/value pair list that looks like an update.
An entry is a dict.
An update is a list of name/value pairs.
"""
update = []
for attr in entry.keys():
if isinstance(entry[attr], list):
for item in entry[attr]:
update.append(dict(attr=str(attr), value=str(item)))
else:
update.append(dict(attr=str(attr), value=str(entry[attr])))
return update
class GenerateUpdateMixin(object):
def _dn_suffix_replace(self, dn, old_suffix, new_suffix):
"""Replace all occurences of "old" AVAs in a DN by "new"
If the input DN doesn't end with old_suffix, log, an raise ValueError.
"""
if not dn.endswith(old_suffix):
self.error("unable to replace suffix '%s' with '%s' in '%s'",
old_suffix, new_suffix, dn)
raise ValueError('no replacement made')
return DN(*dn[:-len(old_suffix)]) + new_suffix
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.api.Backend.ldap2
suffix = ipautil.realm_to_suffix(self.api.env.realm)
searchfilter = '(objectclass=*)'
definitions_managed_entries = []
old_template_container = DN(('cn', 'etc'), suffix)
new_template_container = DN(('cn', 'Templates'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix)
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)
except errors.NotFound as e:
return (False, update_list)
for entry in definitions_managed_entries:
assert isinstance(entry.dn, DN)
if deletes:
old_dn = entry['managedtemplate'][0]
assert isinstance(old_dn, DN)
try:
entry = ldap.get_entry(old_dn, ['*'])
except errors.NotFound as e:
pass
else:
# Compute the new dn by replacing the old container with the new container
try:
new_dn = self._dn_suffix_replace(
entry.dn,
old_suffix=old_template_container,
new_suffix=new_template_container)
except ValueError:
continue
# 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': entry.dn, 'deleteentry': None}
# Add the delete and replacement updates to the list of all updates
update_list.append(old_update)
update_list.append(new_update)
else:
# Update the template dn by replacing the old containter with the new container
try:
new_dn = self._dn_suffix_replace(
entry['managedtemplate'][0],
old_suffix=old_template_container,
new_suffix=new_template_container)
except ValueError:
continue
entry['managedtemplate'] = new_dn
# Update the entry dn similarly
try:
new_dn = self._dn_suffix_replace(
entry.dn,
old_suffix=old_definition_container,
new_suffix=new_definition_container)
except ValueError:
continue
# The old attributes become defaults for the new entry
new_update = {'dn': new_dn,
'default': entry_to_update(entry)}
# Add the replacement update to the collection of all updates
update_list.append(new_update)
if len(update_list) > 0:
restart = True
update_list.sort(reverse=True, key=lambda x: x['dn'])
return (restart, update_list)
class update_managed_post_first(Updater, GenerateUpdateMixin):
"""
Update managed entries
"""
def execute(self, **options):
# Never need to restart with the pre-update changes
(ignore, update_list) = self.generate_update(False)
return False, update_list
api.register(update_managed_post_first)
class update_managed_post(Updater, GenerateUpdateMixin):
"""
Update managed entries
"""
def execute(self, **options):
(restart, update_list) = self.generate_update(True)
return restart, update_list
api.register(update_managed_post)