This patch registers winsync replica in the public tree with enough
information to know which master is handling the agreement.

Now when listing replicas, the type is also returned and winsync
agreements are listed.
When listing a specific server with --verbose, in case of a winsync
peer the winsync peer status is shown by contacting the master that has
the agreement.

On winsync link removal, the public information about the agreement is
also removed.

Ticket 1007

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
>From 3bf5a3f8fcb257e5f91d4327fd15c281c01cce92 Mon Sep 17 00:00:00 2001
From: Simo Sorce <sso...@redhat.com>
Date: Mon, 28 Feb 2011 17:35:44 -0500
Subject: [PATCH] Store list of non-master replicas in DIT and provide way to list them

Fixes: https://fedorahosted.org/freeipa/ticket/1007
---
 install/share/bootstrap-template.ldif        |    6 ++
 install/tools/ipa-replica-manage             |  124 ++++++++++++++++++--------
 install/updates/21-replicas_container.update |    9 ++
 install/updates/Makefile.am                  |    1 +
 ipaserver/install/replication.py             |   12 +++
 5 files changed, 115 insertions(+), 37 deletions(-)
 create mode 100644 install/updates/21-replicas_container.update

diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
index 3cfff958733bd89f4aefb4433be52a9ace41aab8..9ad8fef3d52503093808ef39bb624bc080072887 100644
--- a/install/share/bootstrap-template.ldif
+++ b/install/share/bootstrap-template.ldif
@@ -143,6 +143,12 @@ objectClass: nsContainer
 objectClass: top
 cn: masters
 
+dn: cn=replicas,cn=ipa,cn=etc,$SUFFIX
+changetype: add
+objectClass: nsContainer
+objectClass: top
+cn: replicas
+
 dn: cn=dna,cn=ipa,cn=etc,$SUFFIX
 changetype: add
 objectClass: nsContainer
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index 931b13921b3a3bf4a340a7f301d325a487333497..87c994aa5a494364d28123a4fb68eba1b7942d05 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -117,42 +117,77 @@ def test_connection(realm, host):
     except ldap.LOCAL_ERROR:
         return False
 
-def list_masters(realm, host, replica, dirman_passwd, verbose):
-
-    if replica:
-        try:
-            repl = replication.ReplicationManager(realm, replica, dirman_passwd)
-        except Exception, e:
-            print "Failed to get data from '%s': %s" % (replica, str(e))
-            return
-
-        entries = repl.find_replication_agreements()
-
-        for entry in entries:
-            print entry.nsds5replicahost
-
-            if verbose:
-                print "  last init status: %s" % entry.nsds5replicalastinitstatus
-                print "  last init ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastinitend))
-                print "  last update status: %s" % entry.nsds5replicalastupdatestatus
-                print "  last update ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastupdateend))
-    else:
-        try:
-            conn = ipaldap.IPAdmin(host, 636, cacert=CACERT)
-            if dirman_passwd:
-                conn.do_simple_bind(bindpw=dirman_passwd)
-            else:
-                conn.do_sasl_gssapi_bind()
-
-            dn = 'cn=masters,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
-            entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
-
-            for ent in entries:
-                print ent.cn
-
-        except Exception, e:
-            print "Failed to get data from '%s': %s" % (host, str(e))
-            return
+def list_replicas(realm, host, replica, dirman_passwd, verbose):
+
+    is_replica = False
+    winsync_peer = None
+    peers = {}
+
+    try:
+        conn = ipaldap.IPAdmin(host, 636, cacert=CACERT)
+        if dirman_passwd:
+            conn.do_simple_bind(bindpw=dirman_passwd)
+        else:
+            conn.do_sasl_gssapi_bind()
+
+        dn = 'cn=masters,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
+        entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
+
+        for ent in entries:
+            peers[ent.cn] = ['master', '']
+
+        dn = 'cn=replicas,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
+        entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
+
+        for ent in entries:
+            peers[ent.cn] = ent.ipaconfigstring.split(':')
+
+    except Exception, e:
+        print "Failed to get data from '%s': %s" % (host, str(e))
+        return
+
+
+    if not replica:
+        for k, p in peers.iteritems():
+            print '%s: %s' % (k, p[0])
+        return
+
+    # ok we are being ask for info about a specific replica
+    for k, p in peers.iteritems():
+        if replica == k:
+            is_replica = True
+            if p[0] == 'winsync':
+                winsync_peer = p[1]
+
+    if not is_replica:
+        print "Cannot find %s in public server list" % replica
+        return
+
+    try:
+        if winsync_peer:
+            repl = replication.ReplicationManager(realm, winsync_peer,
+                                                  dirman_passwd)
+            cn, dn = repl.agreement_dn(replica)
+            entries = repl.conn.search_s(dn, ldap.SCOPE_BASE,
+                                         "(objectclass=nsDSWindowsReplicationAgreement)")
+            ent_type = 'winsync'
+        else:
+            repl = replication.ReplicationManager(realm, replica,
+                                                  dirman_passwd)
+            entries = repl.find_replication_agreements()
+            ent_type = 'replica'
+    except Exception, e:
+        print "Failed to get data from '%s': %s" % (replica, str(e))
+        return
+
+    for entry in entries:
+        print '%s: %s' % (entry.nsds5replicahost, ent_type)
+
+        if verbose:
+            print "  last init status: %s" % entry.nsds5replicalastinitstatus
+            print "  last init ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastinitend))
+            print "  last update status: %s" % entry.nsds5replicalastupdatestatus
+            print "  last update ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastupdateend))
 
 def del_link(realm, replica1, replica2, dirman_passwd, force=False):
 
@@ -228,6 +263,21 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
     repl1.delete_agreement(replica2)
     repl1.delete_referral(replica2)
 
+    if type1 == replication.WINSYNC:
+        try:
+            dn = 'cn=%s,cn=replicas,cn=ipa,cn=etc,%s' % (replica2,
+                                                         util.realm_to_suffix(realm))
+            entries = repl1.conn.search_s(dn, ldap.SCOPE_SUBTREE)
+            if len(entries) != 0:
+                dnset = repl1.conn.get_dns_sorted_by_length(entries,
+                                                            reverse=True)
+                for dns in dnset:
+                    for dn in dns:
+                        repl1.conn.deleteEntry(dn)
+        except Exception, e:
+            print "Error deleting winsync replica shared info: %s" % str(e)
+
+
 def del_master(realm, hostname, options):
 
     force_del = False
@@ -390,7 +440,7 @@ def main():
         replica = None
         if len(args) == 2:
             replica = args[1]
-        list_masters(realm, host, replica, dirman_passwd, options.verbose)
+        list_replicas(realm, host, replica, dirman_passwd, options.verbose)
     elif args[0] == "del":
         del_master(realm, args[1], options)
     elif args[0] == "re-initialize":
diff --git a/install/updates/21-replicas_container.update b/install/updates/21-replicas_container.update
new file mode 100644
index 0000000000000000000000000000000000000000..44b14f82d8bea97382f248391a460e7e97dbcdf8
--- /dev/null
+++ b/install/updates/21-replicas_container.update
@@ -0,0 +1,9 @@
+#
+# Add replicas container if not available
+#
+
+dn: cn=replicas,cn=ipa,cn=etc,$SUFFIX
+add:objectClass: top
+add:objectClass: nsContainer
+add:cn: replicas
+
diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
index 26318e144447ef55d500137e691462e43a529325..46db676430fc5f65072a752f72d60a8fc74716d9 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -9,6 +9,7 @@ app_DATA =				\
 	20-nss_ldap.update		\
 	20-replication.update		\
 	20-winsync_index.update		\
+	21-replicas_container.update	\
 	40-delegation.update		\
 	50-lockout-policy.update		\
 	$(NULL)
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 516878cbf53fe7b1b34a066360ae634d99efde8c..eab29720524ad01aa6839c10286305b0a01c599f 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -673,6 +673,18 @@ class ReplicationManager:
         self.wait_for_repl_update(self.conn, dn, 30)
         logging.info("Agreement is ready, starting replication . . .")
 
+        # Add winsync replica to the public DIT
+        dn = 'cn=%s,cn=replicas,cn=ipa,cn=etc,%s' % (ad_dc_name, self.suffix)
+        entry = ipaldap.Entry(dn)
+        entry.setValues("objectclass", ["nsContainer", "ipaConfigObject"])
+        entry.setValues("cn", ad_dc_name)
+        entry.setValues("ipaConfigString", "winsync:%s" % self.hostname)
+
+        try:
+            self.conn.add_s(entry)
+        except Exception, e:
+            logging.info("Failed to create public entry for winsync replica")
+
         #Finally start replication
         ret = self.start_replication(self.conn, ad_dc_name)
         if ret != 0:
-- 
1.7.4

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

Reply via email to