Generalize the fix_replica_memberof update plugin to allow updating more
replication attributes.

Add nsds5ReplicaStripAttrs to replication agreements on update and
replica install.

https://fedorahosted.org/freeipa/ticket/2534


--
PetrĀ³
From d6eceb17f6ed43aa5a085288c87684b9462b4cce Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 17 Jul 2012 10:09:35 -0400
Subject: [PATCH] Add nsds5ReplicaStripAttrs to replica agreements

Generalize the fix_replica_memberof update plugin to allow updating more
replication attributes.

Add nsds5ReplicaStripAttrs to replication agreements on update and
replica install.

https://fedorahosted.org/freeipa/ticket/2534
---
 ipaserver/install/plugins/Makefile.am              |  2 +-
 ...plica_memberof.py => fix_replica_agreements.py} | 94 +++++++++++++++-------
 ipaserver/install/replication.py                   |  9 +++
 3 files changed, 73 insertions(+), 32 deletions(-)
 rename ipaserver/install/plugins/{fix_replica_memberof.py => fix_replica_agreements.py} (45%)

diff --git a/ipaserver/install/plugins/Makefile.am b/ipaserver/install/plugins/Makefile.am
index e3b2e989b17458bf46c82c65666c746574b2dac0..9670273c8cd14c2ec98da9d228664b06289483a1 100644
--- a/ipaserver/install/plugins/Makefile.am
+++ b/ipaserver/install/plugins/Makefile.am
@@ -4,7 +4,7 @@ appdir = $(pythondir)/ipaserver/install
 app_PYTHON = 			\
 	__init__.py		\
 	baseupdate.py		\
-	fix_replica_memberof.py	\
+	fix_replica_agreements.py	\
 	rename_managed.py	\
 	dns.py			\
 	updateclient.py		\
diff --git a/ipaserver/install/plugins/fix_replica_memberof.py b/ipaserver/install/plugins/fix_replica_agreements.py
similarity index 45%
rename from ipaserver/install/plugins/fix_replica_memberof.py
rename to ipaserver/install/plugins/fix_replica_agreements.py
index d4ab75348eea29b61a0442b1e451f81a0471ad67..2819acc923c8ee45ab697312df4df73c7c0a0a18 100644
--- a/ipaserver/install/plugins/fix_replica_memberof.py
+++ b/ipaserver/install/plugins/fix_replica_agreements.py
@@ -25,7 +25,10 @@
 from ipaserver.install import replication
 from ipalib import api
 
-class update_replica_exclude_attribute_list(PreUpdate):
+EXCLUDE_TEMPLATE = '(objectclass=*) $ EXCLUDE %s'
+
+
+class update_replica_attribute_lists(PreUpdate):
     """
     Run through all replication agreements and ensure that EXCLUDE list
     has all the required attributes so that we don't cause replication
@@ -45,39 +48,68 @@ def execute(self, **options):
         self.log.debug("Found %d agreement(s)", len(entries))
         for replica in entries:
             self.log.debug(replica.getValue('description'))
-            attrlist = replica.getValue('nsDS5ReplicatedAttributeList')
-            if attrlist is None:
-                self.log.debug("Adding nsDS5ReplicatedAttributeList and nsDS5ReplicatedAttributeListTotal")
+
+            self._update_attr(repl, replica,
+                'nsDS5ReplicatedAttributeList',
+                replication.EXCLUDES, template=EXCLUDE_TEMPLATE)
+            self._update_attr(repl, replica,
+                'nsDS5ReplicatedAttributeListTotal',
+                replication.TOTAL_EXCLUDES, template=EXCLUDE_TEMPLATE)
+            self._update_attr(repl, replica,
+                'nsds5ReplicaStripAttrs', replication.STRIP_ATTRS)
+
+        self.log.debug("Done updating agreements")
+
+        return (False, False, [])  # No restart, no apply now, no updates
+
+    def _update_attr(self, repl, replica, attribute, values, template='%s'):
+        """Add or update an attribute of a replication agreement
+
+        If the attribute doesn't already exist, it is added and set to
+        `template` with %s substituted by a space-separated `values`.
+        If the attribute does exist, `values` missing from it are just
+        appended to the end, also space-separated.
+
+        :param repl: Replication manager
+        :param replica: Replica agreement
+        :param attribute: Attribute to add or update
+        :param values: List of values the attribute should hold
+        :param template: Template to use when adding attribute
+        """
+        attrlist = replica.getValue(attribute)
+        if attrlist is None:
+            self.log.debug("Adding %s", attribute)
+
+            current = replica.toDict()
+            # Need to add it altogether
+            replica.setValues(attribute, template % " ".join(values))
+
+            try:
+                repl.conn.updateEntry(replica.dn, current, replica.toDict())
+                self.log.debug("Updated")
+            except Exception, e:
+                self.log.error("Error caught updating replica: %s", str(e))
+
+        else:
+            attrlist_normalized = attrlist.lower().split()
+            missing = [a for a in values
+                if a.lower() not in attrlist_normalized]
+
+            if missing:
+                self.log.debug("%s needs updating (missing: %s)", attribute,
+                    ', '.join(missing))
                 current = replica.toDict()
-                # Need to add it altogether
-                replica.setValues('nsDS5ReplicatedAttributeList',
-                    '(objectclass=*) $ EXCLUDE %s' % " ".join(replication.EXCLUDES))
-                replica.setValues('nsDS5ReplicatedAttributeListTotal',
-                    '(objectclass=*) $ EXCLUDE %s' % " ".join(replication.TOTAL_EXCLUDES))
+
+                replica.setValue(attribute,
+                    '%s %s' % (attrlist, ' '.join(missing)))
+
                 try:
                     repl.conn.updateEntry(replica.dn, current, replica.toDict())
-                    self.log.debug("Updated")
+                    self.log.debug("Updated %s", attribute)
                 except Exception, e:
-                    self.log.error("Error caught updating replica: %s", str(e))
+                    self.log.error("Error caught updating %s: %s",
+                        attribute, str(e))
             else:
-                attrlist_normalized = attrlist.lower()
-                missing = [attr for attr in replication.EXCLUDES
-                                if attr not in attrlist_normalized]
+                self.log.debug("%s: No update necessary" % attribute)
 
-                if missing:
-                    self.log.debug("Attribute list needs updating")
-                    current = replica.toDict()
-                    replica.setValue('nsDS5ReplicatedAttributeList',
-                        replica.getValue('nsDS5ReplicatedAttributeList') + ' %s' % ' '.join(missing))
-                    try:
-                        repl.conn.updateEntry(replica.dn, current, replica.toDict())
-                        self.log.debug("Updated")
-                    except Exception, e:
-                        self.log.error("Error caught updating replica: %s", str(e))
-                else:
-                    self.log.debug("No update necessary")
-        self.log.debug("Done updating agreements")
-
-        return (False, False, []) # No restart, no apply now, no updates
-
-api.register(update_replica_exclude_attribute_list)
+api.register(update_replica_attribute_lists)
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 950e8ffc65795da4533612250725b7997a6f6e60..eb834185071d5fa4a1346f0c52875b057092ab6d 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -51,6 +51,13 @@
 # List of attributes that need to be excluded from normal replication.
 EXCLUDES = ('memberof', 'idnssoaserial') + TOTAL_EXCLUDES
 
+# List of attributes that are not updated on empty replication
+STRIP_ATTRS = ('modifiersName',
+               'modifyTimestamp',
+               'internalModifiersName',
+               'internalModifyTimestamp')
+
+
 def replica_conn_check(master_host, host_name, realm, check_ca,
                        admin_password=None):
     """
@@ -519,6 +526,8 @@ def setup_agreement(self, a_conn, b_hostname, port=389,
             # that we will have to set the memberof fixup task
             self.need_memberof_fixup = True
 
+        entry.setValues('nsds5ReplicaStripAttrs', " ".join(STRIP_ATTRS))
+
         entry = a_conn.waitForEntry(entry)
 
     def needs_memberof_fixup(self):
-- 
1.7.11.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to