diff options
| -rw-r--r-- | ipatests/test_xmlrpc/tracker/host_plugin.py | 10 | ||||
| -rw-r--r-- | ipatests/test_xmlrpc/tracker/kerberos_aliases.py | 99 | ||||
| -rw-r--r-- | ipatests/test_xmlrpc/tracker/service_plugin.py | 17 | ||||
| -rw-r--r-- | ipatests/test_xmlrpc/tracker/user_plugin.py | 10 |
4 files changed, 130 insertions, 6 deletions
diff --git a/ipatests/test_xmlrpc/tracker/host_plugin.py b/ipatests/test_xmlrpc/tracker/host_plugin.py index 03113b8fe..45be169e0 100644 --- a/ipatests/test_xmlrpc/tracker/host_plugin.py +++ b/ipatests/test_xmlrpc/tracker/host_plugin.py @@ -7,13 +7,14 @@ from __future__ import print_function from ipapython.dn import DN from ipatests.test_xmlrpc.tracker.base import Tracker +from ipatests.test_xmlrpc.tracker.kerberos_aliases import KerberosAliasMixin from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_uuid from ipatests.test_xmlrpc import objectclasses from ipatests.util import assert_deepequal from ipalib import errors -class HostTracker(Tracker): +class HostTracker(KerberosAliasMixin, Tracker): """Wraps and tracks modifications to a Host object Implements the helper functions for host plugin. @@ -175,3 +176,10 @@ class HostTracker(Tracker): pass request.addfinalizer(cleanup) + + # Kerberos aliases methods + def _make_add_alias_cmd(self): + return self.make_command('host_add_principal', self.name) + + def _make_remove_alias_cmd(self): + return self.make_command('host_remove_principal', self.name) diff --git a/ipatests/test_xmlrpc/tracker/kerberos_aliases.py b/ipatests/test_xmlrpc/tracker/kerberos_aliases.py new file mode 100644 index 000000000..da7b04fa4 --- /dev/null +++ b/ipatests/test_xmlrpc/tracker/kerberos_aliases.py @@ -0,0 +1,99 @@ +# +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license +# +"""kerberos_aliases + +The module implements a mixin class that provides an interface +to the Kerberos Aliases feature of freeIPA. + +In order to use the class the child class must implement the +`_make_add_alias_cmd` and `_make_remove_alias_cmd` methods that +are different for each entity type. + +The KerberosAliasMixin class then provides the implementation +of the manipulation of the kerberos alias in general. + +It is up to the child class or the user to validate the +alias being added for a particular type of an entry. +""" + + +class KerberosAliasError(Exception): + pass + + +class KerberosAliasMixin(object): + """KerberosAliasMixin""" + + def _make_add_alias_cmd(self): + raise NotImplementedError("The _make_add_alias_cmd method " + "is not implemented.") + + def _make_remove_alias_cmd(self): + raise NotImplementedError("The _make_remove_alias_cmd method " + "is not implemented.") + + def _check_for_krbprincipalname_attr(self): + # Check if the tracker has a principal name + # Each compatible entry has at least one kerberos + # principal matching the canonical principal name + principals = self.attrs.get('krbprincipalname') + if self.exists: + if not principals: + raise KerberosAliasError( + "{} doesn't have krbprincipalname attribute" + .format(self.__class__.__name__)) + else: + raise ValueError("The entry {} doesn't seem to exist" + .format(self.name)) + + def _normalize_principal_list(self, principal_list): + """Normalize the list for further manipulation.""" + if not isinstance(principal_list, (list, tuple)): + return [principal_list] + else: + return principal_list + + def _normalize_principal_value(self, principal): + """Normalize principal value by appending the realm string.""" + return u'@'.join((principal, self.api.env.realm)) + + def add_principal(self, principal_list, **options): + """Add kerberos principal alias to the entity. + + Add principal alias to the underlying entry and + update the attributes in the Tracker instance. + """ + self._check_for_krbprincipalname_attr() + + principal_list = self._normalize_principal_list(principal_list) + + cmd = self._make_add_alias_cmd() + cmd(principal_list, **options) + + tracker_principals = self.attrs.get('krbprincipalname') + tracker_principals.extend(( + self._normalize_principal_value(item) for item in principal_list)) + + def remove_principal(self, principal_list, **options): + """Remove kerberos principal alias from an entry. + + Remove principal alias from the tracked entry. + """ + self._check_for_krbprincipalname_attr() + + principal_list = self._normalize_principal_list(principal_list) + + cmd = self._make_remove_alias_cmd() + cmd(principal_list, **options) + + # Make a copy of the list so the tracker instance is not modified + # if there is an error deleting the aliases + # This can happen when deleting multiple aliases and at least + # one of them doesn't exist, raising ValueError + tracker_principals = self.attrs.get('krbprincipalname')[:] + + for item in principal_list: + tracker_principals.remove(self._normalize_principal_value(item)) + + self.attrs['krbprincipalname'] = tracker_principals diff --git a/ipatests/test_xmlrpc/tracker/service_plugin.py b/ipatests/test_xmlrpc/tracker/service_plugin.py index 89c27e821..e51232f80 100644 --- a/ipatests/test_xmlrpc/tracker/service_plugin.py +++ b/ipatests/test_xmlrpc/tracker/service_plugin.py @@ -7,6 +7,7 @@ import six from ipalib import api from ipatests.test_xmlrpc.tracker.base import Tracker +from ipatests.test_xmlrpc.tracker.kerberos_aliases import KerberosAliasMixin from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_uuid from ipatests.test_xmlrpc import objectclasses from ipatests.util import assert_deepequal @@ -16,7 +17,7 @@ if six.PY3: unicode = str -class ServiceTracker(Tracker): +class ServiceTracker(KerberosAliasMixin, Tracker): """ Tracker class for service plugin @@ -49,14 +50,14 @@ class ServiceTracker(Tracker): u'usercertificate', u'has_keytab'} update_keys = retrieve_keys - {u'dn'} - def __init__(self, name, host_fqdn, options): + def __init__(self, name, host_fqdn, options=None): super(ServiceTracker, self).__init__(default_version=None) self._name = "{0}/{1}@{2}".format(name, host_fqdn, api.env.realm) self.dn = DN( ('krbprincipalname', self.name), api.env.container_service, api.env.basedn) self.host_fqdn = host_fqdn - self.options = options + self.options = options or {} @property def name(self): @@ -92,7 +93,8 @@ class ServiceTracker(Tracker): u'objectclass': objectclasses.service, u'ipauniqueid': [fuzzy_uuid], u'managedby_host': [self.host_fqdn], - u'krbcanonicalname': [u'{0}'.format(self.name)] + u'krbcanonicalname': [u'{0}'.format(self.name)], + u'has_keytab': False } for key in self.options: @@ -150,3 +152,10 @@ class ServiceTracker(Tracker): u'summary': u'Modified service "{0}"'.format(self.name), u'result': self.filter_attrs(self.update_keys | set(extra_keys)) }, result) + + # Kerberos aliases methods + def _make_add_alias_cmd(self): + return self.make_command('service_add_principal', self.name) + + def _make_remove_alias_cmd(self): + return self.make_command('service_remove_principal', self.name) diff --git a/ipatests/test_xmlrpc/tracker/user_plugin.py b/ipatests/test_xmlrpc/tracker/user_plugin.py index ee49d418c..ae3d39c4a 100644 --- a/ipatests/test_xmlrpc/tracker/user_plugin.py +++ b/ipatests/test_xmlrpc/tracker/user_plugin.py @@ -12,12 +12,13 @@ from ipatests.test_xmlrpc import objectclasses from ipatests.test_xmlrpc.xmlrpc_test import ( fuzzy_digits, fuzzy_uuid, raises_exact) from ipatests.test_xmlrpc.tracker.base import Tracker +from ipatests.test_xmlrpc.tracker.kerberos_aliases import KerberosAliasMixin if six.PY3: unicode = str -class UserTracker(Tracker): +class UserTracker(KerberosAliasMixin, Tracker): """ Class for host plugin like tests """ retrieve_keys = { @@ -492,3 +493,10 @@ class UserTracker(Tracker): 'description': [u'Account administrators group'], }, ), result) + + # Kerberos aliases methods + def _make_add_alias_cmd(self): + return self.make_command('user_add_principal', self.name) + + def _make_remove_alias_cmd(self): + return self.make_command('user_remove_principal', self.name) |
