URL: https://github.com/freeipa/freeipa/pull/741
Author: stlaz
 Title: #741: 6.9 -> 7.4 migration fixes
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/741/head:pr741
git checkout pr741
From 802b2ad635f3e62290c95bb0636c85d90199d84b Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slazn...@redhat.com>
Date: Thu, 27 Apr 2017 12:51:30 +0200
Subject: [PATCH 1/2] Refresh Dogtag RestClient.ca_host property

Refresh the ca_host property of the Dogtag's RestClient class when
it's requested as a context manager.

This solves the problem which would occur on DL0 when installing
CA which needs to perform a set of steps against itself accessing
8443 port. This port should however only be available locally so
trying to connect to remote master would fail. We need to make
sure the right CA host is accessed.

https://pagure.io/freeipa/issue/6878
---
 ipaserver/install/cainstance.py |  5 ++---
 ipaserver/plugins/dogtag.py     | 30 ++++++++++++++++++------------
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 84d60bf..d72feb8 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -425,6 +425,8 @@ def configure_instance(self, host_name, dm_password, admin_password,
                 self.step("Configure HTTP to proxy connections",
                           self.http_proxy)
                 self.step("restarting certificate server", self.restart_instance)
+                self.step("updating IPA configuration", update_ipa_conf)
+                self.step("enabling CA instance", self.__enable_instance)
                 if not promote:
                     self.step("migrating certificate profiles to LDAP",
                               migrate_profiles_to_ldap)
@@ -432,9 +434,6 @@ def configure_instance(self, host_name, dm_password, admin_password,
                               import_included_profiles)
                     self.step("adding default CA ACL", ensure_default_caacl)
                     self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry)
-                self.step("updating IPA configuration", update_ipa_conf)
-
-                self.step("enabling CA instance", self.__enable_instance)
 
                 self.step("configuring certmonger renewal for lightweight CAs",
                           self.__add_lightweight_ca_tracking_requests)
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index 3997531..bddaab5 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -1202,7 +1202,6 @@ def select_any_master(ldap2, service='CA'):
 import random
 from ipaserver.plugins import rabase
 from ipalib.constants import TYPE_ERROR
-from ipalib.util import cachedproperty
 from ipalib import _
 from ipaplatform.paths import paths
 
@@ -1250,34 +1249,41 @@ def __init__(self, api):
             self.client_keyfile = paths.RA_AGENT_KEY
         super(RestClient, self).__init__(api)
 
+        self._ca_host = None
         # session cookie
         self.override_port = None
         self.cookie = None
 
-    @cachedproperty
+    @property
     def ca_host(self):
         """
-        :return:   host
-                   as str
+        :returns: FQDN of a host hopefully providing a CA service
 
-        Select our CA host.
+        Select our CA host, cache it for the first time.
         """
+        if self._ca_host is not None:
+            return self._ca_host
+
         ldap2 = self.api.Backend.ldap2
         if host_has_service(api.env.ca_host, ldap2, "CA"):
-            return api.env.ca_host
-        if api.env.host != api.env.ca_host:
+            object.__setattr__(self, '_ca_host', api.env.ca_host)
+        elif api.env.host != api.env.ca_host:
             if host_has_service(api.env.host, ldap2, "CA"):
-                return api.env.host
-        host = select_any_master(ldap2)
-        if host:
-            return host
+                object.__setattr__(self, '_ca_host', api.env.host)
         else:
-            return api.env.ca_host
+            object.__setattr__(self, '_ca_host', select_any_master(ldap2))
+        if self._ca_host is None:
+            object.__setattr__(self, '_ca_host', api.env.ca_host)
+        return self._ca_host
 
     def __enter__(self):
         """Log into the REST API"""
         if self.cookie is not None:
             return
+
+        # Refresh the ca_host property
+        object.__setattr__(self, '_ca_host', None)
+
         status, resp_headers, _resp_body = dogtag.https_request(
             self.ca_host, self.override_port or self.env.ca_agent_port,
             url='/ca/rest/account/login',

From f57ed03e97836876f21d18e68fd0f13f394dc471 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slazn...@redhat.com>
Date: Fri, 28 Apr 2017 09:31:45 +0200
Subject: [PATCH 2/2] Remove the cachedproperty class

The cachedproperty class was used in one special use-case where it only
caused issues. Let's get rid of it.

https://pagure.io/freeipa/issue/6878
---
 ipalib/util.py | 34 ----------------------------------
 1 file changed, 34 deletions(-)

diff --git a/ipalib/util.py b/ipalib/util.py
index e9d4105..8973a19 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -34,7 +34,6 @@
 import encodings
 import sys
 import ssl
-from weakref import WeakKeyDictionary
 
 import netaddr
 from dns import resolver, rdatatype
@@ -492,39 +491,6 @@ def remove_sshpubkey_from_output_list_post(context, entries):
         delattr(context, 'ipasshpubkey_added')
 
 
-class cachedproperty(object):
-    """
-    A property-like attribute that caches the return value of a method call.
-
-    When the attribute is first read, the method is called and its return
-    value is saved and returned. On subsequent reads, the saved value is
-    returned.
-
-    Typical usage:
-    class C(object):
-        @cachedproperty
-        def attr(self):
-            return 'value'
-    """
-    __slots__ = ('getter', 'store')
-
-    def __init__(self, getter):
-        self.getter = getter
-        self.store = WeakKeyDictionary()
-
-    def __get__(self, obj, cls):
-        if obj is None:
-            return None
-        if obj not in self.store:
-            self.store[obj] = self.getter(obj)
-        return self.store[obj]
-
-    def __set__(self, obj, value):
-        raise AttributeError("can't set attribute")
-
-    def __delete__(self, obj):
-        raise AttributeError("can't delete attribute")
-
 # regexp matching signed floating point number (group 1) followed by
 # optional whitespace followed by time unit, e.g. day, hour (group 7)
 time_duration_re = re.compile(r'([-+]?((\d+)|(\d+\.\d+)|(\.\d+)|(\d+\.)))\s*([a-z]+)', re.IGNORECASE)
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to