summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2011-02-28 17:35:44 -0500
committerSimo Sorce <ssorce@redhat.com>2011-03-02 09:46:46 -0500
commit54b26270186422607ef52b9b408326744b2d86d1 (patch)
tree79af223f7a47592e3ada31111feec40b004d897b
parent998dd701a728465aa70fe8041aa8daf8c0f1eefc (diff)
downloadfreeipa-54b26270186422607ef52b9b408326744b2d86d1.zip
freeipa-54b26270186422607ef52b9b408326744b2d86d1.tar.gz
freeipa-54b26270186422607ef52b9b408326744b2d86d1.tar.xz
Store list of non-master replicas in DIT and provide way to list them
Fixes: https://fedorahosted.org/freeipa/ticket/1007
-rw-r--r--install/share/bootstrap-template.ldif6
-rwxr-xr-xinstall/tools/ipa-replica-manage110
-rw-r--r--install/updates/21-replicas_container.update9
-rw-r--r--install/updates/Makefile.am1
-rw-r--r--ipaserver/install/replication.py12
5 files changed, 108 insertions, 30 deletions
diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
index b941d5f..0a81b63 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 931b139..87c994a 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):
+def list_replicas(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
+ is_replica = False
+ winsync_peer = None
+ peers = {}
- entries = repl.find_replication_agreements()
+ try:
+ conn = ipaldap.IPAdmin(host, 636, cacert=CACERT)
+ if dirman_passwd:
+ conn.do_simple_bind(bindpw=dirman_passwd)
+ else:
+ conn.do_sasl_gssapi_bind()
- for entry in entries:
- print entry.nsds5replicahost
+ dn = 'cn=masters,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
+ entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
- 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()
+ for ent in entries:
+ peers[ent.cn] = ['master', '']
- dn = 'cn=masters,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
- entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
+ 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:
- print ent.cn
+ 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
+ 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 0000000..44b14f8
--- /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 5b45c6e..947ccd1 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -10,6 +10,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 \
45-roles.update \
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index c9afc5d..091a4de 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: