mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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:
@@ -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
|
||||
|
||||
@@ -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":
|
||||
|
||||
9
install/updates/21-replicas_container.update
Normal file
9
install/updates/21-replicas_container.update
Normal 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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user