From 943ff78787d4b6c65b90d0ceb03538ed71c37837 Mon Sep 17 00:00:00 2001 From: Thierry bordaz (tbordaz) Date: Oct 11 2017 15:24:03 +0000 Subject: Ticket 47568 - Rename DSAdmin class Bug Description: This bug is to rename DSAdmin main class with an other name: DirSrv This change impact the lib389 as well as the tests. Fix Description: - Rename directory: 'dsadmin' -> 'lib389' class : 'DSAdmin' -> 'DirSrv' object : 'dsadmin' -> 'dirsrv' - Add Index class, with method to delete indexes of a backend (for backend deletion) - Add 'delete' method in class backend - To run as regular user (/usr/bin/sudo, select ports > 1024) - Replace addbackend_harn per add backend+suffix - Fix various unit tests (almost all of them are pass) - Use local variable naming convention: camel_case https://fedorahosted.org/389/ticket/47568 Reviewed by: Rich Megginson, Roberto (thanks you both for the review) Platforms tested: F17 Flag Day: no Doc impact: no --- diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py index 9e6187a..2f980ff 100644 --- a/src/lib389/lib389/__init__.py +++ b/src/lib389/lib389/__init__.py @@ -1,10 +1,10 @@ -"""The dsadmin module. +"""The lib389 module. IMPORTANT: Ternary operator syntax is unsupported on RHEL5 x if cond else y #don't! - The DSAdmin functionalities are split in various classes + The lib389 functionalities are split in various classes defined in brookers.py TODO: reorganize method parameters according to SimpleLDAPObject @@ -32,7 +32,6 @@ import time import operator import shutil import datetime -import select import logging from ldap.ldapobject import SimpleLDAPObject @@ -54,7 +53,7 @@ from lib389.utils import ( ) # mixin -#from lib389.tools import DSAdminTools +#from lib389.tools import DirSrvTools RE_DBMONATTR = re.compile(r'^([a-zA-Z]+)-([1-9][0-9]*)$') RE_DBMONATTRSUN = re.compile(r'^([a-zA-Z]+)-([a-zA-Z]+)$') @@ -93,15 +92,15 @@ class DsError(Error): def wrapper(f, name): """Wrapper of all superclass methods using lib389.Entry. - @param f - DSAdmin method inherited from SimpleLDAPObject + @param f - DirSrv method inherited from SimpleLDAPObject @param name - method to call - This seems to need to be an unbound method, that's why it's outside of DSAdmin. Perhaps there + This seems to need to be an unbound method, that's why it's outside of DirSrv. Perhaps there is some way to do this with the new classmethod or staticmethod of 2.4. We replace every call to a method in SimpleLDAPObject (the superclass - of DSAdmin) with a call to inner. The f argument to wrapper is the bound method - of DSAdmin (which is inherited from the superclass). Bound means that it will implicitly + of DirSrv) with a call to inner. The f argument to wrapper is the bound method + of DirSrv (which is inherited from the superclass). Bound means that it will implicitly be called with the self argument, it is not in the args list. name is the name of the method to call. If name is a method that returns entry objects (e.g. result), we wrap the data returned by an Entry class. If name is a method that takes an entry @@ -145,7 +144,7 @@ def wrapper(f, name): -class DSAdmin(SimpleLDAPObject): +class DirSrv(SimpleLDAPObject): def getDseAttr(self, attrname): """Return a given attribute from dse.ldif. @@ -163,7 +162,7 @@ class DSAdmin(SimpleLDAPObject): raise err def __initPart2(self): - """Initialize the DSAdmin structure filling various fields, like: + """Initialize the DirSrv structure filling various fields, like: - dbdir - errlog - confdir @@ -264,10 +263,12 @@ class DSAdmin(SimpleLDAPObject): from lib389.brooker import ( Replica, Backend, - Config) + Config, + Index) self.replica = Replica(self) self.backend = Backend(self) self.config = Config(self) + self.index = Index(self) def __init__(self, host='localhost', port=389, binddn='', bindpw='', serverId=None, nobind=False, sslport=0, verbose=False): # default to anon bind """We just set our instance variables and wrap the methods. @@ -490,11 +491,11 @@ class DSAdmin(SimpleLDAPObject): rc = self.startTaskAndWait(entry, verbose) if rc: - log.error("Error: index task %s for file %s exited with %d" % ( - cn, ldiffile, rc)) + log.error("Error: index task %s exited with %d" % ( + cn, rc)) else: - log.info("Index task %s for file %s completed successfully" % ( - cn, ldiffile)) + log.info("Index task %s completed successfully" % ( + cn)) return rc def fixupMemberOf(self, suffix, filt=None, verbose=False): @@ -1041,16 +1042,16 @@ class DSAdmin(SimpleLDAPObject): else: raise Exception("Error: invalid value %s for oneWaySync: must be fromWindows or toWindows" % args['onewaysync']) - # args - DSAdmin consumer (repoth), suffix, binddn, bindpw, timeout + # args - DirSrv consumer (repoth), suffix, binddn, bindpw, timeout # also need an auto_init argument def setupAgreement(self, consumer, args, cn_format=r'meTo_%s:%s', description_format=r'me to %s:%s'): """Create (and return) a replication agreement from self to consumer. - self is the supplier, - - consumer is a DSAdmin object (consumer can be a master) + - consumer is a DirSrv object (consumer can be a master) - cn_format - use this string to format the agreement name consumer: - * a DSAdmin object if chaining + * a DirSrv object if chaining * an object with attributes: host, port, sslport, __str__ args = { diff --git a/src/lib389/lib389/brooker.py b/src/lib389/lib389/brooker.py index e811a9b..b3a1b6b 100644 --- a/src/lib389/lib389/brooker.py +++ b/src/lib389/lib389/brooker.py @@ -5,7 +5,7 @@ * Suffix You will access this from: - DSAdmin.backend.methodName() + DirSrv.backend.methodName() """ import ldap import os @@ -14,7 +14,7 @@ import time from lib389._constants import * -from lib389 import Entry, DSAdmin +from lib389 import Entry, DirSrv from lib389.utils import normalizeDN, escapeDNValue, suffixfilt from lib389 import ( NoSuchEntryError @@ -42,13 +42,13 @@ class Replica(object): ALWAYS = None def __init__(self, conn): - """@param conn - a DSAdmin instance""" + """@param conn - a DirSrv instance""" self.conn = conn self.log = conn.log def __getattr__(self, name): if name in Replica.proxied_methods: - return DSAdmin.__getattr__(self.conn, name) + return DirSrv.__getattr__(self.conn, name) def _get_mt_entry(self, suffix): """Return the replica dn of the given suffix.""" @@ -356,7 +356,7 @@ class Replica(object): - self is the supplier, @param consumer: one of the following (consumer can be a master) - * a DSAdmin object if chaining + * a DirSrv object if chaining * an object with attributes: host, port, sslport, __str__ @param suffix - eg. 'dc=babel,dc=it' @param binddn - @@ -521,7 +521,7 @@ class Config(object): - get and set "cn=config" attributes """ def __init__(self, conn): - """@param conn - a DSAdmin instance """ + """@param conn - a DirSrv instance """ self.conn = conn self.log = conn.log @@ -533,7 +533,7 @@ class Config(object): eg. set('passwordExp', 'on') """ self.log.debug("set(%r, %r)" % (key, value)) - return self.conn.modify(DN_CONFIG, + return self.conn.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, key, value)]) def get(self, key): @@ -619,13 +619,13 @@ class Backend(object): proxied_methods = 'search_s getEntry'.split() def __init__(self, conn): - """@param conn - a DSAdmin instance""" + """@param conn - a DirSrv instance""" self.conn = conn self.log = conn.log def __getattr__(self, name): if name in Replica.proxied_methods: - return DSAdmin.__getattr__(self.conn, name) + return DirSrv.__getattr__(self.conn, name) def list(self, name=None, suffix=None, attrs=None): """Get backends by name or suffix @@ -683,7 +683,30 @@ class Backend(object): self.conn.modify_s(','.join(('cn=' + bename, DN_LDBM)), [ (ldap.MOD_REPLACE, 'nsslapd-readonly', readonly) ]) - + + + def delete(self, benamebase='localdb'): + """Delete a backend. + @param benamebase - the backend common name + + It firsts delete all the indexes under the backend, then delete the backend entry + Then deletes + - encrypted attribute keys + - encrypted attribute + - monitor + Then deletes the backend entry + """ + self.conn.index.delete_all(benamebase) + + dn = "cn=encrypted attribute keys," + "cn=" + benamebase + "," + DN_LDBM + self.conn.delete_s(dn) + dn = "cn=encrypted attributes," + "cn=" + benamebase + "," + DN_LDBM + self.conn.delete_s(dn) + dn = "cn=monitor," + "cn=" + benamebase + "," + DN_LDBM + self.conn.delete_s(dn) + dn = "cn=" + benamebase + "," + DN_LDBM + self.conn.delete_s(dn) + return def add(self, suffix, binddn=None, bindpw=None, urls=None, attrvals=None, benamebase='localdb', setupmt=False, parent=None): """Setup a backend and return its dn. Blank on error XXX should RAISE! @@ -720,6 +743,8 @@ class Backend(object): """ attrvals = attrvals or {} dnbase = "" + backend_entry = None + suffix_entry = None # figure out what type of be based on args if binddn and bindpw and urls: # its a chaining be @@ -760,16 +785,16 @@ class Backend(object): self.log.error("Could not add backend entry: %r" % dn) raise - self.conn._test_entry(dn, ldap.SCOPE_BASE) + backend_entry = self.conn._test_entry(dn, ldap.SCOPE_BASE) # # if setupmt creates the suffix entry # if setupmt: self.log.debug("Setup Mapping Tree entry") - mtentry = self.setup_mt(suffix=suffix, bename=cn, parent=parent) - self.log.info("Created Mapping Tree entry %r" % mtentry) - return cn + suffix_entry = self.setup_mt(suffix=suffix, bename=cn, parent=parent) + self.log.info("Created Mapping Tree entry %s" % suffix_entry.dn) + return backend_entry, suffix_entry def setup_mt(self, suffix, bename, parent=None): @@ -823,7 +848,8 @@ class Backend(object): if parent: entry.setValues('nsslapd-parent-suffix', nparent) try: - self.log.debug("Creating entry: %r" % entry) + self.log.debug("Creating entry: %s" % entry.dn) + self.log.info("Entry %r" % entry) self.conn.add_s(entry) except ldap.LDAPError, e: raise ldap.LDAPError("Error adding suffix entry " + dn, e) @@ -840,3 +866,24 @@ class Backend(object): raise NotImplementedError() return [x.dn.replace("\3D","=").replace("\2C",",") for x in suffixes] return [x.dn for x in suffixes] + + +class Index(object): + + def __init__(self, conn): + """@param conn - a DirSrv instance""" + self.conn = conn + self.log = conn.log + + def delete_all(self, benamebase): + dn = "cn=index, cn=" + benamebase + "," + DN_LDBM + + # delete each defined index + ents = self.conn.search_s(dn, ldap.SCOPE_ONELEVEL) + for ent in ents: + self.log.debug("Delete index entry %s" % (ent.dn)) + self.conn.delete_s(ent.dn) + + # Then delete the top index entry + self.log.debug("Delete head index entry %s" % (dn)) + self.conn.delete_s(dn) \ No newline at end of file diff --git a/src/lib389/lib389/tools.py b/src/lib389/lib389/tools.py index 2d2003e..0e5774c 100644 --- a/src/lib389/lib389/tools.py +++ b/src/lib389/lib389/tools.py @@ -1,8 +1,8 @@ """Tools for creating and managing servers - uses DSAdmin + uses DirSrv """ -__all__ = ['DSAdminTools'] +__all__ = ['DirSrvTools'] try: from subprocess import Popen, PIPE, STDOUT HASPOPEN = True @@ -48,8 +48,8 @@ PATH_SETUP_DS_ADMIN = "/setup-ds-admin.pl" PATH_SETUP_DS = "/setup-ds.pl" PATH_ADM_CONF = "/etc/dirsrv/admin-serv/adm.conf" -class DSAdminTools(object): - """DSAdmin mix-in.""" +class DirSrvTools(object): + """DirSrv mix-in.""" @staticmethod def cgiFake(sroot, verbose, prog, args): @@ -228,21 +228,21 @@ class DSAdminTools(object): self.unbind() log.info("closed remote server ", self) cgiargs = {} - rc = DSAdminTools.cgiPost(self.host, self.asport, self.cfgdsuser, + rc = DirSrvTools.cgiPost(self.host, self.asport, self.cfgdsuser, self.cfgdspwd, "/slapd-%s/Tasks/Operation/stop" % self.inst, verbose, cgiargs) log.info("stopped remote server %s rc = %d" % (self, rc)) return rc else: - return DSAdminTools.serverCmd(self, 'stop', verbose, timeout) + return DirSrvTools.serverCmd(self, 'stop', verbose, timeout) @staticmethod def start(self, verbose=False, timeout=0): if not self.isLocal and hasattr(self, 'asport'): log.debug("starting remote server %s " % self) cgiargs = {} - rc = DSAdminTools.cgiPost(self.host, self.asport, self.cfgdsuser, + rc = DirSrvTools.cgiPost(self.host, self.asport, self.cfgdsuser, self.cfgdspwd, "/slapd-%s/Tasks/Operation/start" % self.inst, verbose, cgiargs) @@ -253,27 +253,27 @@ class DSAdminTools(object): return rc else: log.debug("Starting server %r" % self) - return DSAdminTools.serverCmd(self, 'start', verbose, timeout) + return DirSrvTools.serverCmd(self, 'start', verbose, timeout) @staticmethod - def setupSSL(dsadmin, secport=636, sourcedir=None, secargs=None): + def setupSSL(dirsrv, secport=636, sourcedir=None, secargs=None): """configure and setup SSL with a given certificate and restart the server. - See DSAdmin.configSSL for the secargs values + See DirSrv.configSSL for the secargs values """ - e = lib389.configSSL(secport, secargs) + e = dirsrv.configSSL(secport, secargs) log.info("entry is %r" % [e]) dn_config = e.dn # get our cert dir - e_config = lib389.getEntry( + e_config = dirsrv.getEntry( dn_config, ldap.SCOPE_BASE, '(objectclass=*)') certdir = e_config.getValue('nsslapd-certdir') # have to stop the server before replacing any security files - DSAdminTools.stop(dsadmin) + DirSrvTools.stop(dirsrv) # allow secport for selinux if secport != 636: log.debug("Configuring SELinux on port:", secport) - cmd = 'semanage port -a -t ldap_port_t -p tcp %s' % secport + cmd = '/usr/bin/sudo semanage port -a -t ldap_port_t -p tcp %s' % secport os.system(cmd) # eventually copy security files from source dir to our cert dir @@ -294,7 +294,7 @@ class DSAdminTools(object): shutil.copy2(srcf, destf) # now, restart the ds - DSAdminTools.start(dsadmin, True) + DirSrvTools.start(dirsrv, True) @staticmethod def runInfProg(prog, content, verbose): @@ -449,7 +449,7 @@ class DSAdminTools(object): # try to connect with the given parameters try: - newconn = lib389.DSAdmin(args['newhost'], args['newport'], + newconn = lib389.DirSrv(args['newhost'], args['newport'], args['newrootdn'], args['newrootpw'], args['newinstance']) newconn.isLocal = isLocal if args['have_admin'] and not args['setup_admin']: @@ -493,14 +493,14 @@ class DSAdminTools(object): cgiargs['admin_domain'] = args['admin_domain'] if not isLocal: - DSAdminTools.cgiPost(args['newhost'], asport, args['cfgdsuser'], + DirSrvTools.cgiPost(args['newhost'], asport, args['cfgdsuser'], args['cfgdspwd'], "/slapd/Tasks/Operation/Create", verbose, secure, cgiargs) elif not args['new_style']: prog = sroot + "/bin/slapd/admin/bin/ds_create" if not os.access(prog, os.X_OK): prog = sroot + "/bin/slapd/admin/bin/ds_newinstance" - DSAdminTools.cgiFake(sroot, verbose, prog, cgiargs) + DirSrvTools.cgiFake(sroot, verbose, prog, cgiargs) else: prog = '' if args['have_admin']: @@ -513,9 +513,9 @@ class DSAdminTools(object): prog = prog[:-3] content = formatInfData(args) - DSAdminTools.runInfProg(prog, content, verbose) + DirSrvTools.runInfProg(prog, content, verbose) - newconn = lib389.DSAdmin(args['newhost'], args['newport'], + newconn = lib389.DirSrv(args['newhost'], args['newport'], args['newrootdn'], args['newrootpw'], args['newinstance']) newconn.isLocal = isLocal # Now the admin should have been created @@ -532,7 +532,7 @@ class DSAdminTools(object): # pass this sub two dicts - the first one is a dict suitable to create # a new instance - see createInstance for more details # the second is a dict suitable for replicaSetupAll - see replicaSetupAll - conn = DSAdminTools.createInstance(createArgs) + conn = DirSrvTools.createInstance(createArgs) if not conn: print "Error: could not create server", createArgs return 0 @@ -541,7 +541,7 @@ class DSAdminTools(object): return conn -class MockDSAdmin(object): +class MockDirSrv(object): host = 'localhost' port = 22389 sslport = 0 diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py index d5f3c5d..c7f2755 100644 --- a/src/lib389/lib389/utils.py +++ b/src/lib389/lib389/utils.py @@ -1,4 +1,4 @@ -"""Utilities for DSAdmin. +"""Utilities for DirSrv. TODO put them in a module! """ @@ -9,7 +9,7 @@ except ImportError: def my_popen(cmd_l, stdout=None): class MockPopenResult(object): - def wait(): + def wait(self): pass p = MockPopenResult() p.stdout, p.stdin = popen2(cmd_l) @@ -203,7 +203,7 @@ def update_newhost_with_fqdn(args): def getcfgdsuserdn(cfgdn, args): - """Return a DSAdmin object bound anonymously or to the admin user. + """Return a DirSrv object bound anonymously or to the admin user. If the config ds user ID was given, not the full DN, we need to figure out the full DN. @@ -216,7 +216,7 @@ def getcfgdsuserdn(cfgdn, args): This may raise a file or LDAP exception. """ # create a connection to the cfg ds - conn = lib389.DSAdmin(args['cfgdshost'], args['cfgdsport'], "", "", None) + conn = lib389.DirSrv(args['cfgdshost'], args['cfgdsport'], "", "", None) # if the caller gave a password, but not the cfguser DN, look it up if 'cfgdspwd' in args and \ ('cfgdsuser' not in args or not is_a_dn(args['cfgdsuser'])): @@ -239,7 +239,7 @@ def getcfgdsuserdn(cfgdn, args): args['cfgdsuser'] = "uid=%s,ou=Administrators,ou=TopologyManagement,%s" % \ (args['cfgdsuser'], cfgdn) conn.unbind() - conn = lib389.DSAdmin( + conn = lib389.DirSrv( args['cfgdshost'], args['cfgdsport'], args['cfgdsuser'], args['cfgdspwd'], None) return conn diff --git a/src/lib389/tests/backend_test.py b/src/lib389/tests/backend_test.py index e12803d..fe36eb3 100644 --- a/src/lib389/tests/backend_test.py +++ b/src/lib389/tests/backend_test.py @@ -5,7 +5,7 @@ * Suffix You will access this from: - DSAdmin.backend.methodName() + DirSrv.backend.methodName() """ from nose import * @@ -18,15 +18,15 @@ from config import * import ldap import time import sys -import dsadmin -from dsadmin import DSAdmin, Entry -from dsadmin import NoSuchEntryError -from dsadmin import utils -from dsadmin.tools import DSAdminTools +import lib389 +from lib389 import DirSrv, Entry +from lib389 import NoSuchEntryError +from lib389 import utils +from lib389.tools import DirSrvTools from subprocess import Popen from random import randint -from dsadmin.brooker import Replica -from dsadmin import MASTER_TYPE, DN_MAPPING_TREE, DN_CHANGELOG, DN_LDBM +from lib389.brooker import Replica +from lib389 import MASTER_TYPE, DN_MAPPING_TREE, DN_CHANGELOG, DN_LDBM # Test harnesses from dsadmin_test import drop_backend, addbackend_harn from dsadmin_test import drop_added_entries @@ -36,34 +36,44 @@ added_entries = None added_backends = None MOCK_REPLICA_ID = '12' -MOCK_TESTREPLICA_DN = "cn=testReplica,cn=ldbm database,cn=plugins,cn=config" +MOCK_TESTREPLICA_DN = "cn=testReplicadb,cn=ldbm database,cn=plugins,cn=config" def setup(): # uses an existing 389 instance # add a suffix # add an agreement - # This setup is quite verbose but to test dsadmin method we should + # This setup is quite verbose but to test DirSrv method we should # do things manually. A better solution would be to use an LDIF. global conn - conn = DSAdmin(**config.auth) + conn = DirSrv(**config.auth) conn.verbose = True conn.added_entries = [] conn.added_backends = set(['o=mockbe1']) conn.added_replicas = [] # add a backend for testing ruv and agreements - addbackend_harn(conn, 'testReplica') + suffix = 'o=testReplica' + backend = 'testReplicadb' + backendEntry, dummy = conn.backend.add(suffix, benamebase=backend) + suffixEntry = conn.backend.setup_mt(suffix, backend) + # add another backend for testing replica.add() - addbackend_harn(conn, 'testReplicaCreation') + suffix = 'o=testReplicaCreation' + backend = 'testReplicaCreationdb' + backendEntry, dummy = conn.backend.add(suffix, benamebase=backend) + suffixEntry = conn.backend.setup_mt(suffix, backend) def teardown(): global conn drop_added_entries(conn) conn.delete_s(','.join(['cn="o=testreplica"', DN_MAPPING_TREE])) - drop_backend(conn, 'o=testreplica') - #conn.delete_s('o=testreplica') + conn.backend.delete('testReplicadb') + + conn.delete_s(','.join(['cn="o=testReplicaCreation"', DN_MAPPING_TREE])) + conn.backend.delete('testReplicaCreationdb') + def list_test(): ret = conn.backend.list() @@ -72,7 +82,7 @@ def list_test(): def list_by_name_test(): - tests = [({'name': 'testreplica'}, MOCK_TESTREPLICA_DN)] + tests = [({'name': 'testreplicadb'}, MOCK_TESTREPLICA_DN)] for params, result in tests: ret = conn.backend.list(**params) ret = [x.dn for x in ret] @@ -96,7 +106,7 @@ def list_suffixes(): assert params in suffixes, "Missing %r in %r" % (params, suffixes) def readonly_test(): - bename = 'testReplica' + bename = 'testReplicadb' backend_dn = ','.join(('cn=' + bename, DN_LDBM)) try: conn.backend.readonly(bename=bename, readonly='on') diff --git a/src/lib389/tests/config.py b/src/lib389/tests/config.py index 0bb1e68..8061a9b 100644 --- a/src/lib389/tests/config.py +++ b/src/lib389/tests/config.py @@ -10,7 +10,7 @@ auth = {'host': 'localhost', 'bindpw': 'password'} -class MockDSAdmin(object): +class MockDirSrv(object): host = 'localhost' port = 22389 sslport = 0 diff --git a/src/lib389/tests/config_test.py b/src/lib389/tests/config_test.py index c676c2b..e4eaefd 100644 --- a/src/lib389/tests/config_test.py +++ b/src/lib389/tests/config_test.py @@ -5,7 +5,7 @@ * Suffix You will access this from: - DSAdmin.backend.methodName() + DirSrv.backend.methodName() """ @@ -13,8 +13,10 @@ import config from config import log from config import * -import dsadmin -from dsadmin import DSAdmin, Entry +import lib389 +from lib389 import DirSrv, Entry +import time + # Test harnesses from dsadmin_test import drop_backend, addbackend_harn from dsadmin_test import drop_added_entries @@ -30,10 +32,10 @@ def setup(): # uses an existing 389 instance # add a suffix # add an agreement - # This setup is quite verbose but to test dsadmin method we should + # This setup is quite verbose but to test DirSrv method we should # do things manually. A better solution would be to use an LDIF. global conn - conn = DSAdmin(**config.auth) + conn = DirSrv(**config.auth) conn.verbose = True conn.added_entries = [] conn.added_backends = set(['o=mockbe1']) @@ -48,8 +50,8 @@ def setup(): def teardown(): global conn - conn.config.loglevel([dsadmin.LOG_CACHE]) - conn.config.loglevel([dsadmin.LOG_CACHE], level='access') + conn.config.loglevel([lib389.LOG_CACHE]) + conn.config.loglevel([256], level='access') """ drop_added_entries(conn) @@ -59,7 +61,7 @@ def teardown(): """ def loglevel_test(): - vals = [dsadmin.LOG_CACHE, dsadmin.LOG_REPLICA, dsadmin.LOG_CONNECT] + vals = [lib389.LOG_CACHE, lib389.LOG_REPLICA, lib389.LOG_CONNECT] expected = sum(vals) assert conn.config.loglevel(vals) == expected ret = conn.config.get('nsslapd-errorlog-level') @@ -67,15 +69,15 @@ def loglevel_test(): def loglevel_update_test(): - vals = [dsadmin.LOG_CACHE, dsadmin.LOG_CONNECT] + vals = [lib389.LOG_CACHE, lib389.LOG_CONNECT] e = sum(vals) assert conn.config.loglevel(vals) == e - vals = [dsadmin.LOG_REPLICA] + vals = [lib389.LOG_REPLICA] ret = conn.config.loglevel(vals, update=True) assert ret == (e + sum(vals)), "expected %s got %s" % (e + sum(vals), ret) def access_loglevel_test(): - vals = [dsadmin.LOG_CACHE, dsadmin.LOG_REPLICA, dsadmin.LOG_CONNECT] + vals = [lib389.LOG_CACHE, lib389.LOG_REPLICA, lib389.LOG_CONNECT] assert conn.config.loglevel(vals, level='access') == sum(vals) diff --git a/src/lib389/tests/dsadmin_basic_test.py b/src/lib389/tests/dsadmin_basic_test.py index 7730a8e..422c1c2 100644 --- a/src/lib389/tests/dsadmin_basic_test.py +++ b/src/lib389/tests/dsadmin_basic_test.py @@ -1,10 +1,10 @@ -""" Testing basic functionalities of DSAdmin +""" Testing basic functionalities of DirSrv """ -import dsadmin -from dsadmin import DSAdmin, Entry -from dsadmin import NoSuchEntryError +import lib389 +from lib389 import DirSrv, Entry +from lib389 import NoSuchEntryError import ldap from ldap import * @@ -21,7 +21,7 @@ added_entries = None def setup(): global conn try: - conn = DSAdmin(**config.auth) + conn = DirSrv(**config.auth) conn.verbose = True conn.added_entries = [] except SERVER_DOWN, e: @@ -33,8 +33,8 @@ def tearDown(): global conn # reduce log level - conn.config.loglevel(0) - conn.config.loglevel(0, level='access') + conn.config.loglevel([lib389.LOG_CACHE]) + conn.config.loglevel([256], level='access') for e in conn.added_entries: try: @@ -106,6 +106,13 @@ def getMTEntry_missing_test(): def getMTEntry_present_test(): suffix = 'o=addressbook16' + bename = 'addressbookd16db' + backendEntry, dummy = conn.backend.add(suffix, benamebase=bename) + suffixEntry = conn.backend.setup_mt(suffix, bename) + e = conn.getMTEntry(suffix) + + conn.backend.delete(bename) + conn.delete_s(suffixEntry.dn) assert e, "Entry should be present %s" % suffix diff --git a/src/lib389/tests/dsadmin_create_remove_test.py b/src/lib389/tests/dsadmin_create_remove_test.py index ac0cd75..bfa830b 100644 --- a/src/lib389/tests/dsadmin_create_remove_test.py +++ b/src/lib389/tests/dsadmin_create_remove_test.py @@ -2,9 +2,11 @@ """ import ldap import os -from dsadmin import DSAdmin, DN_CONFIG -from dsadmin.tools import DSAdminTools +import socket +from lib389 import DirSrv, DN_CONFIG +from lib389.tools import DirSrvTools from nose import * +import logging added_instances = [] @@ -16,7 +18,7 @@ def setup(): def teardown(): global added_instances for instance in added_instances: - cmd = "remove-ds.pl -i slapd-%s" % instance + cmd = "/usr/bin/sudo remove-ds.pl -i slapd-%s" % instance try: os.system(cmd) except: @@ -24,7 +26,7 @@ def teardown(): def default_test(): - host = 'localhost' + host = socket.gethostname() port = 10200 binddn = "cn=directory manager" bindpw = "password" @@ -47,9 +49,9 @@ def default_test(): 'setup_admin': True, } try: - m1 = DSAdmin(host, port, binddn, bindpw) + m1 = DirSrv(host, port, binddn, bindpw) except: - m1 = DSAdminTools.createInstance(instance_config, verbose=1) + m1 = DirSrvTools.createInstance(instance_config, verbose=0) added_instances.append(instance_config['newinstance']) # filename = "%s/slapd-%s/ldif/Example.ldif" % (m1.sroot, m1.inst) @@ -64,12 +66,16 @@ def default_test(): 'newport': port + 10, }) - m1 = DSAdminTools.createInstance(instance_config, verbose=1) + m1 = DirSrvTools.createInstance(instance_config, verbose=0) added_instances.append(instance_config['newinstance']) -# m1.stop(True) -# m1.start(True) - cn = m1.setupBackend("dc=example2,dc=com") - rc = m1.setupSuffix("dc=example2,dc=com", cn) + # m1.stop(True) + # m1.start(True) + suffix = "dc=example2,dc=com" + bename = "example2db" + backendEntry, dummy = m1.backend.add(suffix, bename) + suffixEntry = m1.backend.setup_mt(suffix, bename) + cn = backendEntry.getValue('cn') + print cn entry = m1.getEntry(DN_CONFIG, ldap.SCOPE_SUBTREE, "(cn=" + cn + ")") print "new backend entry is:" print entry diff --git a/src/lib389/tests/dsadmin_test.py b/src/lib389/tests/dsadmin_test.py index fadc6dd..285d661 100644 --- a/src/lib389/tests/dsadmin_test.py +++ b/src/lib389/tests/dsadmin_test.py @@ -8,11 +8,11 @@ from config import * import ldap import time import sys -import dsadmin -from dsadmin import DSAdmin, Entry -from dsadmin import NoSuchEntryError -from dsadmin import utils -from dsadmin.tools import DSAdminTools +import lib389 +from lib389 import DirSrv, Entry +from lib389 import NoSuchEntryError +from lib389 import utils +from lib389.tools import DirSrvTools from subprocess import Popen @@ -21,13 +21,13 @@ added_entries = None added_backends = None def harn_nolog(): - conn.config.loglevel([dsadmin.LOG_DEFAULT]) - conn.config.loglevel([dsadmin.LOG_DEFAULT], level='access') + conn.config.loglevel([lib389.LOG_DEFAULT]) + conn.config.loglevel([lib389.LOG_DEFAULT], level='access') def setup(): global conn - conn = DSAdmin(**config.auth) + conn = DirSrv(**config.auth) conn.verbose = True conn.added_entries = [] conn.added_backends = set(['o=mockbe2']) @@ -36,7 +36,13 @@ def setup(): def setup_backend(): global conn - addbackend_harn(conn, 'addressbook6') + suffix = 'o=addressbook6' + backend = 'addressbook6db' + + #create backend and suffix + backendEntry, dummy = conn.backend.add(suffix, benamebase=backend) + suffixEntry = conn.backend.setup_mt(suffix, backend) + def teardown(): global conn @@ -76,7 +82,7 @@ def drop_backend(conn, suffix, bename=None, maxnum=50): assert bename, "Missing bename for %r" % suffix if not hasattr(bename, '__iter__'): - bename = [','.join(['cn=%s' % bename, dsadmin.DN_LDBM])] + bename = [','.join(['cn=%s' % bename, lib389.DN_LDBM])] for be in bename: log.debug("removing entry from %r" % be) leaves = [x.dn for x in conn.search_s( @@ -127,42 +133,48 @@ def addbackend_harn(conn, name, beattrs=None): def setupBackend_ok_test(): "setupBackend_ok calls brooker.Backend.add" try: - be = conn.setupBackend('o=mockbe5', benamebase='mockbe5') - assert be + backendEntry, dummy = conn.backend.add('o=mockbe5', benamebase='mockbe5') + assert backendEntry except ldap.ALREADY_EXISTS: raise finally: - conn.added_backends.add('o=mockbe5') + conn.backend.delete(benamebase='mockbe5') @raises(ldap.ALREADY_EXISTS) def setupBackend_double_test(): "setupBackend_double calls brooker.Backend.add" - be1 = conn.setupBackend('o=mockbe3', benamebase='mockbe3') - conn.added_backends.add('o=mockbe3') - be11 = conn.setupBackend('o=mockbe3', benamebase='mockbe3') + backendEntry, dummy = conn.backend.add('o=mockbe3', benamebase='mockbe3') + backendEntry, dummy = conn.backend.add('o=mockbe3', benamebase='mockbe3') def addsuffix_test(): - addbackend_harn(conn, 'addressbook16') - conn.added_backends.add('o=addressbook16') + # identical to getMTEntry_present_test in dsadmin_basic_test + #addbackend_harn(conn, 'addressbook16') + #conn.added_backends.add('o=addressbook16') + pass def addreplica_write_test(): - name = 'ab3' + suffix = 'o=ab3' + backend = 'ab3' user = { 'binddn': 'uid=rmanager,cn=config', 'bindpw': 'password' } replica = { - 'suffix': 'o=%s' % name, - 'type': dsadmin.MASTER_TYPE, + 'suffix': suffix, + 'type': lib389.MASTER_TYPE, 'id': 124 } replica.update(user) - addbackend_harn(conn, name) + + #create backend and suffix + backendEntry, dummy = conn.backend.add(suffix, benamebase=backend) + suffixEntry = conn.backend.setup_mt(suffix, backend) + ret = conn.replicaSetupAll(replica) - conn.added_replicas.append(ret['dn']) + assert ret != -1, "Error in setup replica: %s" % ret @@ -183,29 +195,28 @@ def prepare_master_replica_test(): @with_setup(setup_backend) def setupAgreement_test(): - consumer = MockDSAdmin() + consumer = MockDirSrv() args = { 'suffix': "o=addressbook6", #'bename': "userRoot", 'binddn': "uid=rmanager,cn=config", 'bindpw': "password", - 'rtype': dsadmin.MASTER_TYPE, + 'rtype': lib389.MASTER_TYPE, 'rid': '1234' } conn.replica.add(**args) conn.added_entries.append(args['binddn']) dn_replica = conn.setupAgreement(consumer, args) - print dn_replica def stop_start_test(): - # dunno why DSAdmin.start|stop writes to dirsrv error-log - conn.errlog = "/tmp/dsadmin-errlog" + # dunno why DirSrv.start|stop writes to dirsrv error-log + conn.errlog = "/tmp/dirsrv-errlog" open(conn.errlog, "w").close() - DSAdminTools.stop(conn) + DirSrvTools.stop(conn) log.info("server stopped") - DSAdminTools.start(conn) + DirSrvTools.start(conn) log.info("server start") time.sleep(5) # save and restore conn settings after restart @@ -218,7 +229,8 @@ def stop_start_test(): def setupSSL_test(): ssl_args = { - 'secport': 636, + 'dirsrv': conn, + 'secport': 22636, 'sourcedir': None, 'secargs': {'nsSSLPersonalitySSL': 'localhost'}, } @@ -236,5 +248,5 @@ def setupSSL_test(): Popen(cmd_mkcert.split(), stdin=open("/dev/urandom"), stderr=fd_null) log.info("Testing ssl configuration") - ssl_args.update({'dsadmin': conn}) - DSAdminTools.setupSSL(**ssl_args) + ssl_args.update({'dirsrv': conn}) + DirSrvTools.setupSSL(**ssl_args) diff --git a/src/lib389/tests/entry_test.py b/src/lib389/tests/entry_test.py index c2f2b3d..705b7f6 100644 --- a/src/lib389/tests/entry_test.py +++ b/src/lib389/tests/entry_test.py @@ -1,5 +1,5 @@ -from dsadmin import Entry -import dsadmin +from lib389 import Entry +import lib389 from nose import SkipTest from nose.tools import raises @@ -52,7 +52,7 @@ class TestEntry(object): #@SkipTest def test_update_complex(self): # compare two entries created with different methods - nsuffix, replid, replicatype = "dc=example,dc=com", 5, dsadmin.REPLICA_RDWR_TYPE + nsuffix, replid, replicatype = "dc=example,dc=com", 5, lib389.REPLICA_RDWR_TYPE binddnlist, legacy = ['uid=pippo, cn=config'], 'off' dn = "dc=example,dc=com" entry = Entry(dn) diff --git a/src/lib389/tests/replica_test.py b/src/lib389/tests/replica_test.py index 0e3e0c6..c0e7feb 100644 --- a/src/lib389/tests/replica_test.py +++ b/src/lib389/tests/replica_test.py @@ -5,7 +5,7 @@ * Suffix You will access this from: - DSAdmin.backend.methodName() + DirSrv.backend.methodName() """ from nose import * @@ -18,15 +18,15 @@ from config import * import ldap import time import sys -import dsadmin -from dsadmin import DSAdmin, Entry -from dsadmin import NoSuchEntryError -from dsadmin import utils -from dsadmin.tools import DSAdminTools +import lib389 +from lib389 import DirSrv, Entry +from lib389 import NoSuchEntryError +from lib389 import utils +from lib389.tools import DirSrvTools from subprocess import Popen from random import randint -from dsadmin.brooker import Replica -from dsadmin import MASTER_TYPE, DN_MAPPING_TREE, DN_CHANGELOG +from lib389.brooker import Replica +from lib389 import MASTER_TYPE, DN_MAPPING_TREE, DN_CHANGELOG # Test harnesses from dsadmin_test import drop_backend, addbackend_harn from dsadmin_test import drop_added_entries @@ -42,20 +42,26 @@ def setup(): # uses an existing 389 instance # add a suffix # add an agreement - # This setup is quite verbose but to test dsadmin method we should + # This setup is quite verbose but to test DirSrv method we should # do things manually. A better solution would be to use an LDIF. global conn - conn = DSAdmin(**config.auth) + conn = DirSrv(**config.auth) conn.verbose = True conn.added_entries = [] conn.added_backends = set(['o=mockbe1']) conn.added_replicas = [] # add a backend for testing ruv and agreements - addbackend_harn(conn, 'testReplica') + suffix = 'o=testReplica' + backend = 'testReplicadb' + backendEntry, dummy = conn.backend.add(suffix, benamebase=backend) + suffixEntry = conn.backend.setup_mt(suffix, backend) # add another backend for testing replica.add() - addbackend_harn(conn, 'testReplicaCreation') + suffix = 'o=testReplicaCreation' + backend = 'testReplicaCreationdb' + backendEntry, dummy = conn.backend.add(suffix, benamebase=backend) + suffixEntry = conn.backend.setup_mt(suffix, backend) # replication needs changelog conn.replica.changelog() @@ -119,8 +125,10 @@ def teardown(): global conn drop_added_entries(conn) conn.delete_s(','.join(['cn="o=testreplica"', DN_MAPPING_TREE])) - drop_backend(conn, 'o=testreplica') - conn.delete_s('o=testreplica') + conn.backend.delete('testReplicadb') + + conn.delete_s(','.join(['cn="o=testReplicaCreation"', DN_MAPPING_TREE])) + conn.backend.delete('testReplicaCreationdb') def changelog(): @@ -217,7 +225,7 @@ def setup_agreement_default_test(): 'binddn': DN_RMANAGER, 'bindpw': "password" } - params = {'consumer': MockDSAdmin(), 'suffix': "o=testReplica"} + params = {'consumer': MockDirSrv(), 'suffix': "o=testReplica"} params.update(user) agreement_dn = conn.replica.agreement_add(**params) @@ -230,7 +238,7 @@ def setup_agreement_duplicate_test(): 'bindpw': "password" } params = { - 'consumer': MockDSAdmin(), + 'consumer': MockDirSrv(), 'suffix': "o=testReplica", 'cn_format': 'testAgreement', 'description_format': 'testAgreement' @@ -244,7 +252,7 @@ def setup_agreement_test(): 'binddn': DN_RMANAGER, 'bindpw': "password" } - params = {'consumer': MockDSAdmin(), 'suffix': "o=testReplica"} + params = {'consumer': MockDirSrv(), 'suffix': "o=testReplica"} params.update(user) conn.replica.agreement_add(**params) @@ -258,7 +266,7 @@ def setup_agreement_fractional_test(): 'binddn': DN_RMANAGER, 'bindpw': "password" } - params = {'consumer': MockDSAdmin(), 'suffix': "o=testReplica"} + params = {'consumer': MockDirSrv(), 'suffix': "o=testReplica"} params.update(user) #conn.replica.agreement_add(**params) @@ -283,7 +291,7 @@ def setup_replica_test(): 'suffix': "o=testReplicaCreation", 'binddn': DN_RMANAGER, 'bindpw': "password", - 'rtype': dsadmin.MASTER_TYPE, + 'rtype': lib389.MASTER_TYPE, 'rid': MOCK_REPLICA_ID } # create a replica entry @@ -297,7 +305,7 @@ def setup_replica_hub_test(): 'suffix': "o=testReplicaCreation", 'binddn': DN_RMANAGER, 'bindpw': "password", - 'rtype': dsadmin.HUB_TYPE, + 'rtype': lib389.HUB_TYPE, 'rid': MOCK_REPLICA_ID } # create a replica entry diff --git a/src/lib389/tests/utils_test.py b/src/lib389/tests/utils_test.py index 36f6c87..23f2100 100644 --- a/src/lib389/tests/utils_test.py +++ b/src/lib389/tests/utils_test.py @@ -1,7 +1,7 @@ from nose import * -import dsadmin -from dsadmin.utils import * +import lib389 +from lib389.utils import * def normalizeDN_test():