pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0165-Add-an-attribute-reporting-client-PKINIT-capable-ser.patch

483b06
From 48f20550f175503cb226bac47c570a2ff3e79be1 Mon Sep 17 00:00:00 2001
483b06
From: Martin Babinsky <mbabinsk@redhat.com>
483b06
Date: Fri, 12 May 2017 15:15:37 +0200
483b06
Subject: [PATCH] Add an attribute reporting client PKINIT-capable servers
483b06
483b06
A new multi-valued server attribute `pkinit_server` was added which
483b06
reports IPA masters that have PKINIT configuration usable by clients.
483b06
483b06
The existing tests were modified to allow for testing the new attribute.
483b06
483b06
https://pagure.io/freeipa/issue/6937
483b06
483b06
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
483b06
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
483b06
---
483b06
 ipaserver/servroles.py                      |   7 ++
483b06
 ipatests/test_ipaserver/test_serverroles.py | 109 +++++++++++++---------------
483b06
 2 files changed, 59 insertions(+), 57 deletions(-)
483b06
483b06
diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py
483b06
index 84fed1046b3b46dc9f5f8bbe6e03354725f1136c..f6e79338b9187aa741fe45b9fae42476cc65f724 100644
483b06
--- a/ipaserver/servroles.py
483b06
+++ b/ipaserver/servroles.py
483b06
@@ -625,4 +625,11 @@ attribute_instances = (
483b06
         u"DNSSEC",
483b06
         u"dnssecKeyMaster",
483b06
     ),
483b06
+    ServerAttribute(
483b06
+        u"pkinit_server_server",
483b06
+        u"PKINIT enabled server",
483b06
+        u"ipa_master_server",
483b06
+        u"KDC",
483b06
+        u"pkinitEnabled"
483b06
+    )
483b06
 )
483b06
diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py
483b06
index e671272783d8d71c2ee56074459433b98b79dd0a..b373a4d32f60e5ef48bcf07ac29162516113e8a8 100644
483b06
--- a/ipatests/test_ipaserver/test_serverroles.py
483b06
+++ b/ipatests/test_ipaserver/test_serverroles.py
483b06
@@ -58,7 +58,7 @@ _adtrust_agents = DN(
483b06
 
483b06
 
483b06
 master_data = {
483b06
-    'ca-dns-dnssec-keymaster': {
483b06
+    'ca-dns-dnssec-keymaster-pkinit-server': {
483b06
         'services': {
483b06
             'CA': {
483b06
                 'enabled': True,
483b06
@@ -72,14 +72,19 @@ master_data = {
483b06
             'DNSSEC': {
483b06
                 'enabled': True,
483b06
                 'config': ['DNSSecKeyMaster']
483b06
+            },
483b06
+            'KDC': {
483b06
+                'enabled': True,
483b06
+                'config': ['pkinitEnabled']
483b06
             }
483b06
         },
483b06
         'expected_roles': {
483b06
             'enabled': ['IPA master', 'CA server', 'DNS server']
483b06
         },
483b06
-        'expected_attributes': {'DNS server': 'dnssec_key_master_server'}
483b06
+        'expected_attributes': {'DNS server': 'dnssec_key_master_server',
483b06
+                                'IPA master': 'pkinit_server_server'}
483b06
     },
483b06
-    'ca-kra-renewal-master': {
483b06
+    'ca-kra-renewal-master-pkinit-server': {
483b06
         'services': {
483b06
             'CA': {
483b06
                 'enabled': True,
483b06
@@ -88,11 +93,16 @@ master_data = {
483b06
             'KRA': {
483b06
                 'enabled': True,
483b06
             },
483b06
+            'KDC': {
483b06
+                'enabled': True,
483b06
+                'config': ['pkinitEnabled']
483b06
+            },
483b06
         },
483b06
         'expected_roles': {
483b06
             'enabled': ['IPA master', 'CA server', 'KRA server']
483b06
         },
483b06
-        'expected_attributes': {'CA server': 'ca_renewal_master_server'}
483b06
+        'expected_attributes': {'CA server': 'ca_renewal_master_server',
483b06
+                                'IPA master': 'pkinit_server_server'}
483b06
     },
483b06
     'dns-trust-agent': {
483b06
         'services': {
483b06
@@ -234,7 +244,7 @@ class MockMasterTopology(object):
483b06
                 no_members=True,
483b06
                 raw=True)['result']}
483b06
 
483b06
-        self.existing_attributes = self._check_test_host_attributes()
483b06
+        self.original_dns_configs = self._remove_test_host_attrs()
483b06
 
483b06
     def iter_domain_data(self):
483b06
         MasterData = namedtuple('MasterData',
483b06
@@ -287,7 +297,6 @@ class MockMasterTopology(object):
483b06
             pass
483b06
 
483b06
     def _add_svc_entries(self, master_dn, svc_desc):
483b06
-        self._add_ipamaster_services(master_dn)
483b06
         for name in svc_desc:
483b06
             svc_dn = self.get_service_dn(name, master_dn)
483b06
             svc_mods = svc_desc[name]
483b06
@@ -298,6 +307,8 @@ class MockMasterTopology(object):
483b06
                     enabled=svc_mods['enabled'],
483b06
                     other_config=svc_mods.get('config', None)))
483b06
 
483b06
+        self._add_ipamaster_services(master_dn)
483b06
+
483b06
     def _remove_svc_master_entries(self, master_dn):
483b06
         try:
483b06
             entries = self.ldap.connection.search_s(
483b06
@@ -317,7 +328,11 @@ class MockMasterTopology(object):
483b06
         """
483b06
         for svc_name in self.ipamaster_services:
483b06
             svc_dn = self.get_service_dn(svc_name, master_dn)
483b06
-            self.ldap.add_entry(str(svc_dn), _make_service_entry_mods())
483b06
+            try:
483b06
+                self.api.Backend.ldap2.get_entry(svc_dn)
483b06
+            except errors.NotFound:
483b06
+                self.ldap.add_entry(
483b06
+                    str(svc_dn), _make_service_entry_mods())
483b06
 
483b06
     def _add_members(self, dn, fqdn, member_attrs):
483b06
         _entry, attrs = self.ldap.connection.search_s(
483b06
@@ -376,57 +391,36 @@ class MockMasterTopology(object):
483b06
         except (ldap.NO_SUCH_OBJECT, ldap.NO_SUCH_ATTRIBUTE):
483b06
             pass
483b06
 
483b06
-    def _check_test_host_attributes(self):
483b06
-        existing_attributes = set()
483b06
-
483b06
-        for service, value, attr_name in (
483b06
-                ('CA', 'caRenewalMaster', 'ca renewal master'),
483b06
-                ('DNSSEC', 'DNSSecKeyMaster', 'dnssec key master')):
483b06
+    def _remove_test_host_attrs(self):
483b06
+        original_dns_configs = []
483b06
 
483b06
-            svc_dn = DN(('cn', service), self.test_master_dn)
483b06
+        for attr_name in (
483b06
+                'caRenewalMaster', 'dnssecKeyMaster', 'pkinitEnabled'):
483b06
             try:
483b06
-                svc_entry = self.api.Backend.ldap2.get_entry(svc_dn)
483b06
+                svc_entry = self.api.Backend.ldap2.find_entry_by_attr(
483b06
+                    'ipaConfigString', attr_name, 'ipaConfigObject',
483b06
+                    base_dn=self.test_master_dn)
483b06
             except errors.NotFound:
483b06
                 continue
483b06
             else:
483b06
-                config_string_val = svc_entry.get('ipaConfigString', [])
483b06
+                original_dns_configs.append(
483b06
+                    (svc_entry.dn, list(svc_entry.get('ipaConfigString', [])))
483b06
+                )
483b06
+                svc_entry[u'ipaConfigString'].remove(attr_name)
483b06
+                self.api.Backend.ldap2.update_entry(svc_entry)
483b06
 
483b06
-                if value in config_string_val:
483b06
-                    existing_attributes.add(attr_name)
483b06
-
483b06
-        return existing_attributes
483b06
-
483b06
-    def _remove_ca_renewal_master(self):
483b06
-        if 'ca renewal master' not in self.existing_attributes:
483b06
-            return
483b06
+        return original_dns_configs
483b06
 
483b06
-        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
483b06
-        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)
483b06
-
483b06
-        config_string_val = ca_entry.get('ipaConfigString', [])
483b06
-        try:
483b06
-            config_string_val.remove('caRenewalMaster')
483b06
-        except KeyError:
483b06
-            return
483b06
-
483b06
-        ca_entry.update({'ipaConfigString': config_string_val})
483b06
-        self.api.Backend.ldap2.update_entry(ca_entry)
483b06
-
483b06
-    def _restore_ca_renewal_master(self):
483b06
-        if 'ca renewal master' not in self.existing_attributes:
483b06
-            return
483b06
-
483b06
-        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
483b06
-        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)
483b06
-
483b06
-        config_string_val = ca_entry.get('ipaConfigString', [])
483b06
-        config_string_val.append('caRenewalMaster')
483b06
-
483b06
-        ca_entry.update({'ipaConfigString': config_string_val})
483b06
-        self.api.Backend.ldap2.update_entry(ca_entry)
483b06
+    def _restore_test_host_attrs(self):
483b06
+        for dn, config in self.original_dns_configs:
483b06
+            try:
483b06
+                svc_entry = self.api.Backend.ldap2.get_entry(dn)
483b06
+                svc_entry['ipaConfigString'] = config
483b06
+                self.api.Backend.ldap2.update_entry(svc_entry)
483b06
+            except (errors.NotFound, errors.EmptyModlist):
483b06
+                continue
483b06
 
483b06
     def setup_data(self):
483b06
-        self._remove_ca_renewal_master()
483b06
         for master_data in self.iter_domain_data():
483b06
             # create host
483b06
             self._add_host_entry(master_data.fqdn)
483b06
@@ -449,7 +443,6 @@ class MockMasterTopology(object):
483b06
                     )
483b06
 
483b06
     def teardown_data(self):
483b06
-        self._restore_ca_renewal_master()
483b06
         for master_data in self.iter_domain_data():
483b06
             # first remove the master entries and service containers
483b06
             self._remove_svc_master_entries(master_data.dn)
483b06
@@ -466,6 +459,8 @@ class MockMasterTopology(object):
483b06
             # finally remove host entry
483b06
             self._del_host_entry(master_data.fqdn)
483b06
 
483b06
+        self._restore_test_host_attrs()
483b06
+
483b06
 
483b06
 @pytest.fixture(scope='module')
483b06
 def mock_api(request):
483b06
@@ -665,14 +660,14 @@ class TestServerRoleStatusRetrieval(object):
483b06
 
483b06
     def test_unknown_role_status_raises_notfound(self, mock_api, mock_masters):
483b06
         unknown_role = 'IAP maestr'
483b06
-        fqdn = mock_masters.get_fqdn('ca-dns-dnssec-keymaster')
483b06
+        fqdn = mock_masters.get_fqdn('ca-dns-dnssec-keymaster-pkinit-server')
483b06
         with pytest.raises(errors.NotFound):
483b06
             mock_api.Backend.serverroles.server_role_retrieve(
483b06
                 fqdn, unknown_role)
483b06
 
483b06
     def test_no_servrole_queries_all_roles_on_server(self, mock_api,
483b06
                                                      mock_masters):
483b06
-        master_name = 'ca-dns-dnssec-keymaster'
483b06
+        master_name = 'ca-dns-dnssec-keymaster-pkinit-server'
483b06
         enabled_roles = master_data[master_name]['expected_roles']['enabled']
483b06
         result = self.find_role(None, mock_api, mock_masters,
483b06
                                 master=master_name)
483b06
@@ -688,7 +683,7 @@ class TestServerRoleStatusRetrieval(object):
483b06
         invalid_substr = 'fwfgbb'
483b06
 
483b06
         assert (not self.find_role(invalid_substr, mock_api, mock_masters,
483b06
-                                   'ca-dns-dnssec-keymaster'))
483b06
+                                   'ca-dns-dnssec-keymaster-pkinit-server'))
483b06
 
483b06
 
483b06
 class TestServerAttributes(object):
483b06
@@ -706,7 +701,7 @@ class TestServerAttributes(object):
483b06
         actual_attr_masters = self.config_retrieve(
483b06
             assoc_role, mock_api)[attr_name]
483b06
 
483b06
-        assert actual_attr_masters == [fqdn]
483b06
+        assert fqdn in actual_attr_masters
483b06
 
483b06
     def test_set_attribute_on_the_same_provider_raises_emptymodlist(
483b06
             self, mock_api, mock_masters):
483b06
@@ -744,10 +739,10 @@ class TestServerAttributes(object):
483b06
         original_renewal_master = self.config_retrieve(
483b06
             role_name, mock_api)[attr_name]
483b06
 
483b06
-        other_ca_server = mock_masters.get_fqdn('trust-controller-ca')
483b06
+        other_ca_server = [mock_masters.get_fqdn('trust-controller-ca')]
483b06
 
483b06
         for host in (other_ca_server, original_renewal_master):
483b06
-            self.config_update(mock_api, **{attr_name: [host]})
483b06
+            self.config_update(mock_api, **{attr_name: host})
483b06
 
483b06
             assert (
483b06
-                self.config_retrieve(role_name, mock_api)[attr_name] == [host])
483b06
+                self.config_retrieve(role_name, mock_api)[attr_name] == host)
483b06
-- 
483b06
2.9.4
483b06