diff options
| author | Milan KubĂk <mkubik@redhat.com> | 2016-07-22 17:07:56 +0200 |
|---|---|---|
| committer | Martin Basti <mbasti@redhat.com> | 2016-07-29 09:04:42 +0200 |
| commit | 5582d1df3213a0727e313d543ee560a09d0cdff8 (patch) | |
| tree | 14328ceadea026c2ad7823e66eba5477d60da757 /ipatests | |
| parent | 6eb9eb730350937692a442b66e4d79d3ebd4eb01 (diff) | |
| download | freeipa-5582d1df3213a0727e313d543ee560a09d0cdff8.tar.gz freeipa-5582d1df3213a0727e313d543ee560a09d0cdff8.tar.xz freeipa-5582d1df3213a0727e313d543ee560a09d0cdff8.zip | |
ipatests: Add tracker class for kerberos principal aliases
The commit implements a mixin class providing capability
to track and modify kerberos principal aliases on supported
types of entries.
The class using the mixin must inherit from the Tracker class
and must provide the implementation of two methods:
* _make_add_alias_cmd
* _make_remove_alias_cmd
These are used to get the type specific command for the particular
entry class. The methods provided will not work on entries that
do not have 'krbprincipalname' attribute.
The service, host and user trackers are being extended to use this
new mixin class.
https://fedorahosted.org/freeipa/ticket/6142
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Diffstat (limited to 'ipatests')
| -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) |
