Store list of non-master replicas in DIT and provide way to list them

Fixes: https://fedorahosted.org/freeipa/ticket/1007
This commit is contained in:
Simo Sorce
2011-02-28 17:35:44 -05:00
parent 998dd701a7
commit 54b2627018
5 changed files with 108 additions and 30 deletions

View File

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

View File

@@ -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":

View File

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

View File

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

View File

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