From 6e44557b601f769d23ee74555a72e8b5cc62c0c9 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Thu, 28 Apr 2016 10:30:05 +0200 Subject: ipalib: move server-side plugins to ipaserver Move the remaining plugin code from ipalib.plugins to ipaserver.plugins. Remove the now unused ipalib.plugins package. https://fedorahosted.org/freeipa/ticket/4739 Reviewed-By: David Kupka --- ipaserver/plugins/domainlevel.py | 137 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 ipaserver/plugins/domainlevel.py (limited to 'ipaserver/plugins/domainlevel.py') diff --git a/ipaserver/plugins/domainlevel.py b/ipaserver/plugins/domainlevel.py new file mode 100644 index 000000000..23fa2a1b2 --- /dev/null +++ b/ipaserver/plugins/domainlevel.py @@ -0,0 +1,137 @@ +# +# Copyright (C) 2015 FreeIPA Contributors see COPYING for license +# + +from collections import namedtuple + +from ipalib import _ +from ipalib import Command +from ipalib import errors +from ipalib import output +from ipalib.parameters import Int +from ipalib.plugable import Registry + +from ipapython.dn import DN + + +__doc__ = _(""" +Raise the IPA Domain Level. +""") + +register = Registry() + +DomainLevelRange = namedtuple('DomainLevelRange', ['min', 'max']) + +domainlevel_output = ( + output.Output('result', int, _('Current domain level:')), +) + + +def get_domainlevel_dn(api): + domainlevel_dn = DN( + ('cn', 'Domain Level'), + ('cn', 'ipa'), + ('cn', 'etc'), + api.env.basedn + ) + + return domainlevel_dn + + +def get_domainlevel_range(master_entry): + try: + return DomainLevelRange( + int(master_entry['ipaMinDomainLevel'][0]), + int(master_entry['ipaMaxDomainLevel'][0]) + ) + except KeyError: + return DomainLevelRange(0, 0) + + +def get_master_entries(ldap, api): + """ + Returns list of LDAPEntries representing IPA masters. + """ + + container_masters = DN( + ('cn', 'masters'), + ('cn', 'ipa'), + ('cn', 'etc'), + api.env.basedn + ) + + masters, _ = ldap.find_entries( + filter="(cn=*)", + base_dn=container_masters, + scope=ldap.SCOPE_ONELEVEL, + paged_search=True, # we need to make sure to get all of them + ) + + return masters + + +@register() +class domainlevel_get(Command): + __doc__ = _('Query current Domain Level.') + + has_output = domainlevel_output + + def execute(self, *args, **options): + ldap = self.api.Backend.ldap2 + entry = ldap.get_entry( + get_domainlevel_dn(self.api), + ['ipaDomainLevel'] + ) + + return {'result': int(entry.single_value['ipaDomainLevel'])} + + +@register() +class domainlevel_set(Command): + __doc__ = _('Change current Domain Level.') + + has_output = domainlevel_output + + takes_args = ( + Int('ipadomainlevel', + cli_name='level', + label=_('Domain Level'), + minvalue=0, + ), + ) + + def execute(self, *args, **options): + """ + Checks all the IPA masters for supported domain level ranges. + + If the desired domain level is within the supported range of all + masters, it will be raised. + + Domain level cannot be lowered. + """ + + ldap = self.api.Backend.ldap2 + + current_entry = ldap.get_entry(get_domainlevel_dn(self.api)) + current_value = int(current_entry.single_value['ipadomainlevel']) + desired_value = int(args[0]) + + # Domain level cannot be lowered + if int(desired_value) < int(current_value): + message = _("Domain Level cannot be lowered.") + raise errors.InvalidDomainLevelError(reason=message) + + # Check if every master supports the desired level + for master in get_master_entries(ldap, self.api): + supported = get_domainlevel_range(master) + + if supported.min > desired_value or supported.max < desired_value: + message = _("Domain Level cannot be raised to {0}, server {1} " + "does not support it." + .format(desired_value, master['cn'][0])) + raise errors.InvalidDomainLevelError(reason=message) + + current_entry.single_value['ipaDomainLevel'] = desired_value + ldap.update_entry(current_entry) + + return {'result': int(current_entry.single_value['ipaDomainLevel'])} -- cgit