A workaround to avoid usage of slow LDAPEntry._sync_attr #4946.

I originally wanted to avoid DN processing as well but we can't do that because of DNs which are encoded - e.g. contains '+' or ','. Therefore patch 811 - faster DN implementation is very useful. Also patch 809 is useful to avoid high load of 389.

https://fedorahosted.org/freeipa/ticket/4965
--
Petr Vobornik
From 7d55a7e2bd88cb9c754cb8cc8a05fd947fd5438a Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Wed, 18 Mar 2015 18:48:54 +0100
Subject: [PATCH] speed up convert_attribute_members

A workaround to avoid usage of slow LDAPEntry._sync_attr #4946

https://fedorahosted.org/freeipa/ticket/4965
---
 ipalib/plugins/baseldap.py | 36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 4b1c701924d57919538e0c428ea181c2e898505e..42509d63de6078b01cc794a005a528d27a168f26 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -631,16 +631,36 @@ class LDAPObject(Object):
     def convert_attribute_members(self, entry_attrs, *keys, **options):
         if options.get('raw', False):
             return
+
+        container_dns = {}
+        new_attrs = {}
+
+        def get_container_dn(ldap_obj_name):
+            dn = container_dns.get(ldap_obj_name, None)
+            if not dn:
+                ldap_obj = self.api.Object[ldap_obj_name]
+                dn = DN(ldap_obj.container_dn, api.env.basedn)
+                container_dns[ldap_obj_name] = dn
+            return dn
+
+        def get_new_attr(attr, ldap_obj_name):
+            name = u'%s_%s' % (attr, ldap_obj_name)
+            new_attr = new_attrs.get(name, None)
+            if not new_attr:
+                new_attr = entry_attrs.setdefault(name, [])
+                new_attrs[name] = new_attr
+            return new_attr
+
         for attr in self.attribute_members:
-            for member in entry_attrs.setdefault(attr, []):
+            for member in entry_attrs.raw.setdefault(attr, []):
                 for ldap_obj_name in self.attribute_members[attr]:
-                    ldap_obj = self.api.Object[ldap_obj_name]
-                    container_dn = DN(ldap_obj.container_dn, api.env.basedn)
-                    if member.endswith(container_dn):
-                        new_attr = '%s_%s' % (attr, ldap_obj.name)
-                        entry_attrs.setdefault(new_attr, []).append(
-                            ldap_obj.get_primary_key_from_dn(member)
-                        )
+                    container_dn = get_container_dn(ldap_obj_name)
+                    memberdn = DN(member)
+                    if memberdn.endswith(container_dn):
+                        ldap_obj = self.api.Object[ldap_obj_name]
+                        pkey = ldap_obj.get_primary_key_from_dn(memberdn)
+                        get_new_attr(attr, ldap_obj_name).append(pkey)
+                        break
             del entry_attrs[attr]
 
     def get_password_attributes(self, ldap, dn, entry_attrs):
-- 
2.1.0

-- 
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