summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2010-12-20 23:34:00 -0500
committerSimo Sorce <ssorce@redhat.com>2010-12-21 17:28:13 -0500
commit613f5feb0e87efb668f1facdc55c43216ff3169e (patch)
tree787bf474e6e297ee017cc3021f9be86d6617f5b7
parent91f3e79d81671441bbf7c187d1415d864f80d101 (diff)
downloadfreeipa-613f5feb0e87efb668f1facdc55c43216ff3169e.tar.gz
freeipa-613f5feb0e87efb668f1facdc55c43216ff3169e.tar.xz
freeipa-613f5feb0e87efb668f1facdc55c43216ff3169e.zip
Rework old init and synch commands and use better names.
These commands can now be run exclusively o the replica that needs to be resynced or reinitialized and the --from command must be used to tell from which other replica it can will pull data. Fixes: https://fedorahosted.org/freeipa/ticket/626
-rw-r--r--install/share/replica-acis.ldif4
-rwxr-xr-xinstall/tools/ipa-replica-manage70
-rw-r--r--ipaserver/install/service.py21
3 files changed, 65 insertions, 30 deletions
diff --git a/install/share/replica-acis.ldif b/install/share/replica-acis.ldif
index feda1d9b7..9ff4ed1b9 100644
--- a/install/share/replica-acis.ldif
+++ b/install/share/replica-acis.ldif
@@ -15,3 +15,7 @@ changetype: modify
add: aci
aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "Remove Replication Agreements";allow (delete) groupdn = "ldap:///cn=removereplica,cn=permissions,cn=accounts,$SUFFIX";)
+dn: cn=tasks,cn=config
+changetype: modify
+add: aci
+aci: (targetattr=*)(version 3.0; acl "Run tasks after replica re-initialization"; allow (add) groupdn = "ldap:///cn=modifyreplica,cn=permissions,cn=accounts,$SUFFIX";)
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index 9894d2ad4..524384efa 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -39,10 +39,8 @@ commands = {
"must provide the name of the server to disconnect"),
"del":(1, 1, "<master fqdn>",
"must provide hostname of master to delete"),
- "init":(1, 1, "<master fqdn>",
- "hostname of master to initialize is required"),
- "synch":(1, 1, "master fqdn>",
- "must provide hostname of supplier to synchronize with")
+ "re-initialize":(0, 0, "", ""),
+ "force-sync":(0, 0, "", "")
}
def parse_options():
@@ -69,6 +67,7 @@ def parse_options():
help="DN of Windows subtree containing the users you want to sync (default cn=Users,<domain suffix)")
parser.add_option("--passsync", dest="passsync",
help="Password for the Windows PassSync user")
+ parser.add_option("--from", dest="fromhost", help="Host to get data from")
options, args = parser.parse_args()
@@ -340,27 +339,50 @@ def add_link(replica1, replica2, dirman_passwd, options):
repl1.setup_replication(replica2, get_realm_name(), **other_args)
print "Connected '%s' to '%s'" % (replica1, replica2)
-def init_master(replman, dirman_passwd, hostname):
- filter = "(&(nsDS5ReplicaHost=%s)(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement)))" % hostname
- entry = replman.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
+def re_initialize(options):
+
+ if not options.fromhost:
+ print "re-initialize requires the option --from <host name>"
+ sys.exit(1)
+
+ repl = replication.ReplicationManager(options.fromhost, options.dirman_passwd)
+ repl.suffix = get_suffix()
+
+ thishost = installutils.get_fqdn()
+
+ filter = "(&(nsDS5ReplicaHost=%s)(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement)))" % thishost
+ entry = repl.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
if len(entry) == 0:
- logging.error("Unable to find replication agreement for %s" % hostname)
+ logging.error("Unable to find %s -> %s replication agreement" % (options.fromhost, thishost))
sys.exit(1)
if len(entry) > 1:
- logging.error("Found multiple agreements for %s. Only initializing the first one returned: %s" % (hostname, entry[0].dn))
- replman.initialize_replication(entry[0].dn, replman.conn)
- ds = dsinstance.DsInstance(realm_name = get_realm_name(), dm_password = dirman_passwd)
+ logging.error("Found multiple agreements for %s. Only initializing the first one returned: %s" % (thishost, entry[0].dn))
+
+ repl.initialize_replication(entry[0].dn, repl.conn)
+ repl.wait_for_repl_init(repl.conn, entry[0].dn)
+
+ ds = dsinstance.DsInstance(realm_name = get_realm_name(), dm_password = options.dirman_passwd)
ds.init_memberof()
-def synch_master(replman, hostname):
- filter = "(&(nsDS5ReplicaHost=%s)(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement)))" % hostname
- entry = replman.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
+def force_sync(options):
+
+ if not options.fromhost:
+ print "force-sync requires the option --from <host name>"
+ sys.exit(1)
+
+ repl = replication.ReplicationManager(options.fromhost, options.dirman_passwd)
+ repl.suffix = get_suffix()
+
+ thishost = installutils.get_fqdn()
+
+ filter = "(&(nsDS5ReplicaHost=%s)(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement)))" % thishost
+ entry = repl.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
if len(entry) == 0:
- logging.error("Unable to find replication agreement for %s" % hostname)
+ logging.error("Unable to find %s -> %s replication agreement" % (options.fromhost, thishost))
sys.exit(1)
if len(entry) > 1:
- logging.error("Found multiple agreements for %s. Only initializing the first one returned: %s" % (hostname, entry[0].dn))
- replman.force_synch(entry[0].dn, entry[0].nsds5replicaupdateschedule, replman.conn)
+ logging.error("Found multiple agreements for %s. Only initializing the first one returned: %s" % (thishost, entry[0].dn))
+ repl.force_synch(entry[0].dn, entry[0].nsds5replicaupdateschedule, repl.conn)
def main():
options, args = parse_options()
@@ -375,9 +397,11 @@ def main():
if options.dirman_passwd:
dirman_passwd = options.dirman_passwd
else:
- if (not test_connection(host)) or args[0] in ["connect", "init"]:
+ if not test_connection(host):
dirman_passwd = getpass.getpass("Directory Manager password: ")
+ options.dirman_passwd = dirman_passwd
+
r = replication.ReplicationManager(host, dirman_passwd)
r.suffix = get_suffix()
@@ -388,10 +412,10 @@ def main():
list_masters(host, replica, dirman_passwd, options.verbose)
elif args[0] == "del":
del_master(r, args[1], options.force)
- elif args[0] == "init":
- init_master(r, dirman_passwd, args[1])
- elif args[0] == "synch":
- synch_master(r, args[1])
+ elif args[0] == "re-initialize":
+ re_initialize(options)
+ elif args[0] == "force-sync":
+ force_sync(options)
elif args[0] == "connect":
if len(args) == 3:
replica1 = args[1]
@@ -412,7 +436,7 @@ def main():
try:
main()
except KeyboardInterrupt:
- sys.exit(1)
+ sys.exit(1)
except SystemExit, e:
sys.exit(e)
except ldap.INVALID_CREDENTIALS:
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 6517b8905..b8d049fee 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -28,6 +28,7 @@ from ipaserver import ipaldap
import base64
import time
import datetime
+from ipaserver.install import installutils
SERVICE_LIST = {
'KDC':('krb5kdc', 10),
@@ -105,22 +106,27 @@ class Service:
self.sstore = sysrestore.StateFile('/var/lib/ipa/sysrestore')
def _ldap_mod(self, ldif, sub_dict = None):
- assert self.dm_password is not None
+ pw_name = None
fd = None
path = ipautil.SHARE_DIR + ldif
+ hostname = installutils.get_fqdn()
if sub_dict is not None:
txt = ipautil.template_file(path, sub_dict)
fd = ipautil.write_tmp_file(txt)
path = fd.name
- [pw_fd, pw_name] = tempfile.mkstemp()
- os.write(pw_fd, self.dm_password)
- os.close(pw_fd)
+ if self.dm_password:
+ [pw_fd, pw_name] = tempfile.mkstemp()
+ os.write(pw_fd, self.dm_password)
+ os.close(pw_fd)
+ auth_parms = ["-x", "-D", "cn=Directory Manager", "-y", pw_name]
+ else:
+ auth_parms = ["-Y", "GSSAPI"]
- args = ["/usr/bin/ldapmodify", "-h", "127.0.0.1", "-xv",
- "-D", "cn=Directory Manager", "-y", pw_name, "-f", path]
+ args = ["/usr/bin/ldapmodify", "-h", hostname, "-v", "-f", path]
+ args += auth_parms
try:
try:
@@ -128,7 +134,8 @@ class Service:
except ipautil.CalledProcessError, e:
logging.critical("Failed to load %s: %s" % (ldif, str(e)))
finally:
- os.remove(pw_name)
+ if pw_name:
+ os.remove(pw_name)
if fd is not None:
fd.close()