Add ability to initialize a replication agreement

Add ability to force a synch to occur
Clean up a lot of unused code in ipaldap.py. This lets us do a simple bind
  without being root (it used to try to read dse.ldif)

436237
This commit is contained in:
Rob Crittenden 2008-03-07 10:56:03 -05:00
parent 03d7125eac
commit 092b1b694c
3 changed files with 73 additions and 51 deletions

View File

@ -18,13 +18,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import sys
import getpass, ldap, re, krbV
from ipa import ipautil
from ipaserver import replication, ipaldap, dsinstance, installutils
def parse_options():
from optparse import OptionParser
@ -36,8 +29,8 @@ def parse_options():
options, args = parser.parse_args()
if not len(args) or not ("list" in args[0] or "add" in args[0] or "del" in args[0]):
parser.error("must provide a comment [list | add | del]")
if not len(args) or not ("list" in args[0] or "add" in args[0] or "del" in args[0] or "init" in args[0] or "synch" in args[0]):
parser.error("must provide a comment [list | add | del | init | synch]")
return options, args
@ -69,6 +62,8 @@ def list_masters(replman, verbose):
print other
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))
@ -83,6 +78,26 @@ def del_master(replman, hostname):
def add_master(replman, hostname):
replman.setup_replication(hostname, get_realm_name())
def init_master(replman, hostname):
filter = "(&(nsDS5ReplicaHost=%s)(objectclass=nsds5ReplicationAgreement))" % hostname
entry = replman.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
if len(entry) == 0:
logging.error("Unable to find replication agreement for %s" % hostname)
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)
def synch_master(replman, hostname):
filter = "(&(nsDS5ReplicaHost=%s)(objectclass=nsds5ReplicationAgreement))" % hostname
entry = replman.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
if len(entry) == 0:
logging.error("Unable to find replication agreement for %s" % hostname)
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)
def main():
options, args = parse_options()
@ -111,8 +126,33 @@ def main():
print "must provide hostname of master to add"
sys.exit(1)
add_master(r, args[1])
elif args[0] == "init":
if len(args) != 2:
print "hostname of supplier to initialize from is required."
sys.exit(1)
init_master(r, args[1])
elif args[0] == "synch":
if len(args) != 2:
print "must provide hostname of supplier to synchronize with"
sys.exit(1)
synch_master(r, args[1])
try:
import sys
import getpass, ldap, re, krbV
import traceback, logging
from ipa import ipautil
from ipaserver import replication, ipaldap, dsinstance, installutils
main()
except KeyboardInterrupt:
sys.exit(1)
except SystemExit, e:
sys.exit(e)
except ldap.INVALID_CREDENTIALS:
print "Invalid password"
sys.exit(1)
except Exception, e:
print "unexpected error: %s" % str(e)

View File

@ -231,25 +231,12 @@ class IPAdmin(SimpleLDAPObject):
[ 'nsslapd-instancedir', 'nsslapd-errorlog',
'nsslapd-certdir', 'nsslapd-schemadir' ])
self.errlog = ent.getValue('nsslapd-errorlog')
self.confdir = None
if self.isLocal:
self.confdir = ent.getValue('nsslapd-certdir')
if not self.confdir or not os.access(self.confdir + '/dse.ldif', os.R_OK):
self.confdir = ent.getValue('nsslapd-schemadir')
if self.confdir:
self.confdir = os.path.dirname(self.confdir)
instdir = ent.getValue('nsslapd-instancedir')
if not instdir:
# get instance name from errorlog
self.inst = re.match(r'(.*)[\/]slapd-([\w-]+)/errors', self.errlog).group(2)
self.confdir = ent.getValue('nsslapd-certdir')
if not self.confdir:
self.confdir = ent.getValue('nsslapd-schemadir')
if self.confdir:
instdir = self.getDseAttr('nsslapd-instancedir')
else:
if self.isLocal:
print instdir
self.sroot, self.inst = re.match(r'(.*)[\/]slapd-([\w-]+)$', instdir).groups()
instdir = re.match(r'(.*/slapd-.*)/errors', self.errlog).group(1)
#self.sroot, self.inst = re.match(r'(.*)[\/]slapd-([\w-]+)$', instdir).groups()
self.confdir = os.path.dirname(self.confdir)
instdir = ent.getValue('nsslapd-instancedir')
ent = self.getEntry('cn=config,cn=ldbm database,cn=plugins,cn=config',
ldap.SCOPE_BASE, '(objectclass=*)',
[ 'nsslapd-directory' ])
@ -293,10 +280,6 @@ class IPAdmin(SimpleLDAPObject):
self.bindcert = bindcert
self.bindkey = bindkey
self.proxydn = proxydn
# see if is local or not
host1 = IPAdmin.getfqdn(host)
host2 = IPAdmin.getfqdn()
self.isLocal = (host1 == host2)
self.suffixes = {}
self.__localinit__()
@ -692,26 +675,6 @@ class IPAdmin(SimpleLDAPObject):
return 'dc=localdomain'
getdefaultsuffix = staticmethod(getdefaultsuffix)
def getnewhost(args):
"""One of the arguments to createInstance is newhost. If this is specified, we need
to convert it to the fqdn. If not given, we need to figure out what the fqdn of the
local host is. This method sets newhost in args to the appropriate value and
returns True if newhost is the localhost, False otherwise"""
isLocal = False
if args.has_key('newhost'):
args['newhost'] = IPAdmin.getfqdn(args['newhost'])
myhost = IPAdmin.getfqdn()
if myhost == args['newhost']:
isLocal = True
elif args['newhost'] == 'localhost' or \
args['newhost'] == 'localhost.localdomain':
isLocal = True
else:
isLocal = True
args['newhost'] = IPAdmin.getfqdn()
return isLocal
getnewhost = staticmethod(getnewhost)
def is_a_dn(dn):
"""Returns True if the given string is a DN, False otherwise."""
return (dn.find("=") > 0)

View File

@ -20,6 +20,7 @@
import time, logging
import ipaldap, ldap, dsinstance
from ldap import modlist
from ipa import ipaerror
DIRMAN_CN = "cn=directory manager"
@ -320,3 +321,21 @@ class ReplicationManager:
self.setup_agreement(self.conn, other_conn)
return self.start_replication(other_conn)
def initialize_replication(self, dn, conn):
mod = [(ldap.MOD_ADD, 'nsds5BeginReplicaRefresh', 'start')]
try:
conn.modify_s(dn, mod)
except ldap.ALREADY_EXISTS:
return
def force_synch(self, dn, schedule, conn):
newschedule = '2358-2359 0'
# On the remote chance of a match. We force a synch to happen right
# now by changing the schedule to something else and quickly changing
# it back.
if newschedule == schedule:
newschedule = '2358-2359 1'
mod = [(ldap.MOD_REPLACE, 'nsDS5ReplicaUpdateSchedule', [ newschedule ])]
conn.modify_s(dn, mod)