From 7a24286f12ced0576c49c3e92ffccea9e2437e6d Mon Sep 17 00:00:00 2001 From: Akshay Adhikari Date: Aug 13 2019 13:17:31 +0000 Subject: Issue 50462 - Fix CI tests Description: Explicitly changed strings to bytes in upgrade-script(tools.py) Also Added ds_version check in order it won't break in 1.4. Added a new replication agreement, and a replication manager. Replication is not working with service accounts. related: https://pagure.io/389-ds-base/issue/50462 Reviewed by: Firstyear, vashirov (Thanks!) --- diff --git a/dirsrvtests/tests/tickets/ticket47462_test.py b/dirsrvtests/tests/tickets/ticket47462_test.py index 1c26ec7..021fe09 100644 --- a/dirsrvtests/tests/tickets/ticket47462_test.py +++ b/dirsrvtests/tests/tickets/ticket47462_test.py @@ -15,8 +15,13 @@ from lib389 import Entry from lib389._constants import * from lib389.properties import * from lib389.topologies import topology_m2 +from lib389.utils import * +from lib389.replica import BootstrapReplicationManager +from lib389.plugins import * + +pytestmark = [pytest.mark.tier2, + pytest.mark.skipif(ds_is_newer('1.4.0'), reason="Upgrade scripts are supported only on versions < 1.4.x")] -pytestmark = pytest.mark.tier2 logging.getLogger(__name__).setLevel(logging.DEBUG) log = logging.getLogger(__name__) @@ -44,76 +49,43 @@ def test_ticket47462(topology_m2): # # Add an extra attribute to the DES plugin args # - try: - topology_m2.ms["master1"].modify_s(DES_PLUGIN, - [(ldap.MOD_REPLACE, 'nsslapd-pluginEnabled', 'on')]) - except ldap.LDAPError as e: - log.fatal('Failed to enable DES plugin, error: ' + - e.message['desc']) - assert False - - try: - topology_m2.ms["master1"].modify_s(DES_PLUGIN, - [(ldap.MOD_ADD, 'nsslapd-pluginarg2', 'description')]) - except ldap.LDAPError as e: - log.fatal('Failed to reset DES plugin, error: ' + - e.message['desc']) - assert False - - try: - topology_m2.ms["master1"].modify_s(MMR_PLUGIN, - [(ldap.MOD_DELETE, - 'nsslapd-plugin-depends-on-named', - 'AES')]) - - except ldap.NO_SUCH_ATTRIBUTE: - pass - except ldap.LDAPError as e: - log.fatal('Failed to reset MMR plugin, error: ' + - e.message['desc']) - assert False + plugin_des = Plugin(topology_m2.ms["master1"], DES_PLUGIN) + plugin_des.set('nsslapd-pluginEnabled', 'on') + plugin_des.set('nsslapd-pluginarg2', 'description') + plugin_mmr = Plugin(topology_m2.ms["master1"], MMR_PLUGIN) + plugin_mmr.remove('nsslapd-plugin-depends-on-named', 'AES') # # Delete the AES plugin # - try: - topology_m2.ms["master1"].delete_s(AES_PLUGIN) - except ldap.NO_SUCH_OBJECT: - pass - except ldap.LDAPError as e: - log.fatal('Failed to delete AES plugin, error: ' + - e.message['desc']) - assert False - + topology_m2.ms["master1"].delete_s(AES_PLUGIN) # restart the server so we must use DES plugin topology_m2.ms["master1"].restart(timeout=10) - # - # Get the agmt dn, and set the password - # - try: - entry = topology_m2.ms["master1"].search_s('cn=config', ldap.SCOPE_SUBTREE, - 'objectclass=nsDS5ReplicationAgreement') - if entry: - agmt_dn = entry[0].dn - log.info('Found agmt dn (%s)' % agmt_dn) - else: - log.fatal('No replication agreements!') - assert False - except ldap.LDAPError as e: - log.fatal('Failed to search for replica credentials: ' + - e.message['desc']) - assert False + manager = BootstrapReplicationManager(topology_m2.ms["master2"]) - try: - properties = {RA_BINDPW: "password"} - topology_m2.ms["master1"].agreement.setProperties(None, agmt_dn, None, - properties) - log.info('Successfully modified replication agreement') - except ValueError: - log.error('Failed to update replica agreement: ' + AGMT_DN) - assert False + manager.create(properties={ + 'cn': 'replication manager', + 'userPassword': 'password' + }) + + DN = topology_m2.ms["master2"].replica._get_mt_entry(DEFAULT_SUFFIX) + + topology_m2.ms["master2"].modify_s(DN, [(ldap.MOD_REPLACE, + 'nsDS5ReplicaBindDN', ensure_bytes(defaultProperties[REPLICATION_BIND_DN]))]) + # + # Create repl agreement from the newly promoted master to master1 + properties = {RA_NAME: 'meTo_{}:{}'.format(topology_m2.ms["master2"].host, + str(topology_m2.ms["master2"].port)), + RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], + RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], + RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], + RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} + topology_m2.ms["master1"].agreement.create(suffix=SUFFIX, + host=topology_m2.ms["master2"].host, + port=topology_m2.ms["master2"].port, + properties=properties) # # Check replication works with the new DES password # @@ -139,7 +111,7 @@ def test_ticket47462(topology_m2): else: log.info('Replication test passed') except ldap.LDAPError as e: - log.fatal('Failed to add test user: ' + e.message['desc']) + log.fatal('Failed to add test user: ' + e.args[0]['desc']) assert False # @@ -148,13 +120,15 @@ def test_ticket47462(topology_m2): try: topology_m2.ms["master1"].backend.create("o=empty", {BACKEND_NAME: "empty"}) except ldap.LDAPError as e: - log.fatal('Failed to create extra/empty backend: ' + e.message['desc']) + log.fatal('Failed to create extra/empty backend: ' + e.args[0]['desc']) assert False # # Run the upgrade... # - topology_m2.ms["master1"].upgrade('online') + topology_m2.ms["master1"].stop() + topology_m2.ms["master2"].stop() + topology_m2.ms["master1"].upgrade('offline') topology_m2.ms["master1"].restart() topology_m2.ms["master2"].restart() @@ -166,7 +140,7 @@ def test_ticket47462(topology_m2): 'nsDS5ReplicaCredentials=*') if entry: val = entry[0].getValue('nsDS5ReplicaCredentials') - if val.startswith('{AES-'): + if val.startswith(b'{AES-'): log.info('The DES credentials have been converted to AES') else: log.fatal('Failed to convert credentials from DES to AES!') @@ -176,7 +150,7 @@ def test_ticket47462(topology_m2): assert False except ldap.LDAPError as e: log.fatal('Failed to search for replica credentials: ' + - e.message['desc']) + e.args[0]['desc']) assert False # @@ -196,7 +170,7 @@ def test_ticket47462(topology_m2): else: log.info('The AES plugin was correctly setup') except ldap.LDAPError as e: - log.fatal('Failed to find AES plugin: ' + e.message['desc']) + log.fatal('Failed to find AES plugin: ' + e.args[0]['desc']) assert False # @@ -211,7 +185,7 @@ def test_ticket47462(topology_m2): else: log.info('The MMR plugin was correctly updated') except ldap.LDAPError as e: - log.fatal('Failed to find AES plugin: ' + e.message['desc']) + log.fatal('Failed to find AES plugin: ' + e.args[0]['desc']) assert False # @@ -226,7 +200,7 @@ def test_ticket47462(topology_m2): else: log.info('The DES plugin was correctly updated') except ldap.LDAPError as e: - log.fatal('Failed to find AES plugin: ' + e.message['desc']) + log.fatal('Failed to find AES plugin: ' + e.args[0]['desc']) assert False # @@ -253,7 +227,7 @@ def test_ticket47462(topology_m2): else: log.info('Replication test passed') except ldap.LDAPError as e: - log.fatal('Failed to add test user: ' + e.message['desc']) + log.fatal('Failed to add test user: ' + e.args[0]['desc']) assert False # Check the entry @@ -269,7 +243,7 @@ def test_ticket47462(topology_m2): assert False except ldap.LDAPError as e: log.fatal('Failed to search for entries: ' + - e.message['desc']) + e.args[0]['desc']) assert False # @@ -282,7 +256,7 @@ def test_ticket47462(topology_m2): 'suffix': DEFAULT_SUFFIX, 'cn': 'convert'}))) except ldap.LDAPError as e: - log.fatal('Failed to add task entry: ' + e.message['desc']) + log.fatal('Failed to add task entry: ' + e.args[0]['desc']) assert False # Wait for task @@ -300,7 +274,7 @@ def test_ticket47462(topology_m2): if entry: val = entry[0].getValue('description') print(str(entry[0])) - if val.startswith('{AES-'): + if val.startswith(b'{AES-'): log.info('Task: DES credentials have been converted to AES') else: log.fatal('Task: Failed to convert credentials from DES to ' + @@ -311,7 +285,7 @@ def test_ticket47462(topology_m2): assert False except ldap.LDAPError as e: log.fatal('Failed to search for entries: ' + - e.message['desc']) + e.args[0]['desc']) assert False diff --git a/dirsrvtests/tests/tickets/ticket48194_test.py b/dirsrvtests/tests/tickets/ticket48194_test.py index bd069b7..4431ebd 100644 --- a/dirsrvtests/tests/tickets/ticket48194_test.py +++ b/dirsrvtests/tests/tickets/ticket48194_test.py @@ -66,11 +66,12 @@ def test_init(topology_st): (ldap.MOD_REPLACE, 'nsslapd-ssl-check-hostname', b'off'), (ldap.MOD_REPLACE, 'nsslapd-secureport', ensure_bytes(LDAPSPORT))]) - topology_st.standalone.add_s(Entry((RSA_DN, {'objectclass': "top nsEncryptionModule".split(), - 'cn': RSA, - 'nsSSLPersonalitySSL': SERVERCERT, - 'nsSSLToken': 'internal (software)', - 'nsSSLActivation': 'on'}))) + if ds_is_older('1.4.0'): + topology_st.standalone.add_s(Entry((RSA_DN, {'objectclass': "top nsEncryptionModule".split(), + 'cn': RSA, + 'nsSSLPersonalitySSL': SERVERCERT, + 'nsSSLToken': 'internal (software)', + 'nsSSLActivation': 'on'}))) def connectWithOpenssl(topology_st, cipher, expect): @@ -87,7 +88,7 @@ def connectWithOpenssl(topology_st, cipher, expect): myurl = 'localhost:%s' % LDAPSPORT cmdline = ['/usr/bin/openssl', 's_client', '-connect', myurl, '-cipher', cipher] - strcmdline = '/usr/bin/openssl s_client -connect localhost:%s -cipher %s' % (LDAPSPORT, cipher) + strcmdline = " ".join(cmdline) log.info("Running cmdline: %s", strcmdline) try: diff --git a/src/lib389/lib389/tools.py b/src/lib389/lib389/tools.py index 919dc85..89423b4 100644 --- a/src/lib389/lib389/tools.py +++ b/src/lib389/lib389/tools.py @@ -52,7 +52,8 @@ from lib389.utils import ( getdefaultsuffix, ensure_bytes, ensure_str, - socket_check_open,) + socket_check_open, + ds_is_older,) from lib389.passwd import password_hash, password_generate @@ -862,7 +863,7 @@ class DirSrvTools(object): # We just want to make sure it's in there somewhere if expectedHost in words: return True - except AssertionError: + except AssertionError: raise AssertionError( "Error: %s should contain '%s' host for %s" % ('/etc/hosts', expectedHost, ipPattern)) @@ -903,53 +904,55 @@ class DirSrvTools(object): /prefix/lib[64]/dirsrv/slapd-INSTANCE/ ''' - - libdir = os.path.join(_ds_paths.lib_dir, 'dirsrv') - - # Gather all the instances so we can adjust the permissions, otherwise - servers = [] - path = os.path.join(_ds_paths.sysconf_dir, 'dirsrv') - for files in os.listdir(path): - if files.startswith('slapd-') and not files.endswith('.removed'): - servers.append(os.path.join(libdir, files)) - - if len(servers) == 0: - # This should not happen - log.fatal('runUpgrade: no servers found!') - assert False - - ''' - The setup script calls things like /lib/dirsrv/slapd-instance/db2bak, - etc, and when we run the setup perl script it gets permission denied - as the default permissions are 750. Adjust the permissions to 755. - ''' - for instance in servers: - for files in os.listdir(instance): - os.chmod(os.path.join(instance, files), 755) - - # Run the "upgrade" - try: - prog = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS) - process = subprocess.Popen([prog, '--update'], shell=False, + if ds_is_older('1.4.0'): + libdir = os.path.join(_ds_paths.lib_dir, 'dirsrv') + + # Gather all the instances so we can adjust the permissions, otherwise + servers = [] + path = os.path.join(_ds_paths.sysconf_dir, 'dirsrv') + for files in os.listdir(path): + if files.startswith('slapd-') and not files.endswith('.removed'): + servers.append(os.path.join(libdir, files)) + + if len(servers) == 0: + # This should not happen + log.fatal('runUpgrade: no servers found!') + assert False + + ''' + The setup script calls things like /lib/dirsrv/slapd-instance/db2bak, + etc, and when we run the setup perl script it gets permission denied + as the default permissions are 750. Adjust the permissions to 755. + ''' + for instance in servers: + for files in os.listdir(instance): + os.chmod(os.path.join(instance, files), 755) + + # Run the "upgrade" + try: + prog = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS) + process = subprocess.Popen([prog, '--update'], shell=False, stdin=subprocess.PIPE) - # Answer the interactive questions, as "--update" currently does - # not work with INF files - process.stdin.write('yes\n') - if(online): - process.stdin.write('online\n') - for x in servers: - process.stdin.write(DN_DM + '\n') - process.stdin.write(PW_DM + '\n') - else: - process.stdin.write('offline\n') - process.stdin.close() - process.wait() - if process.returncode != 0: - log.fatal('runUpgrade failed! Error: %s ' % process.returncode) - assert(False) - except: - log.fatal('runUpgrade failed!') - raise + # Answer the interactive questions, as "--update" currently does + # not work with INF files + process.stdin.write(b'yes\n') + if(online): + process.stdin.write(b'online\n') + for x in servers: + process.stdin.write(ensure_bytes(DN_DM + '\n')) + process.stdin.write(ensure_bytes(PW_DM + '\n')) + else: + process.stdin.write(b'offline\n') + process.stdin.close() + process.wait() + if process.returncode != 0: + log.fatal('runUpgrade failed! Error: %s ' % process.returncode) + assert(False) + except: + log.fatal('runUpgrade failed!') + raise + else: + pass @staticmethod def searchFile(filename, pattern):