예제 #1
0
def topology_m1h1c1(request):
    """Create Replication Deployment with one master, one consumer and one hub"""

    topo_roles = {ReplicaRole.MASTER: 1, ReplicaRole.HUB: 1, ReplicaRole.CONSUMER: 1}
    topology = _create_instances(topo_roles, DEFAULT_SUFFIX)
    master = topology.ms["master1"]
    hub = topology.hs["hub1"]
    consumer = topology.cs["consumer1"]

    # Start with the master, and create it "first".
    log.info("Creating replication topology.")
    # Now get the first master ready.
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.create_first_master(master)
    # Finish the topology creation
    repl.join_hub(master, hub)
    repl.join_consumer(hub, consumer)

    repl.test_replication(master, consumer)

    # Clear out the tmp dir
    for instance in topology:
        instance.clearTmpDir(__file__)

    def fin():
        if DEBUGGING:
            [inst.stop() for inst in topology]
        else:
            assert _remove_ssca_db(topology)
            [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]
    request.addfinalizer(fin)

    topology.logcap = LogCapture()
    return topology
예제 #2
0
def restore_supplier4(topology_m4):
    """In our tests will always be removing supplier 4, so we need a common
    way to restore it for another test
    """

    # Restart the remaining suppliers to allow rid 4 to be reused.
    for inst in topology_m4.ms.values():
        inst.restart()

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.join_supplier(topology_m4.ms["supplier1"],
                       topology_m4.ms["supplier4"])

    # Add the 2,3 -> 4 agmt.
    repl.ensure_agreement(topology_m4.ms["supplier2"],
                          topology_m4.ms["supplier4"])
    repl.ensure_agreement(topology_m4.ms["supplier3"],
                          topology_m4.ms["supplier4"])
    # And in reverse ...
    repl.ensure_agreement(topology_m4.ms["supplier4"],
                          topology_m4.ms["supplier2"])
    repl.ensure_agreement(topology_m4.ms["supplier4"],
                          topology_m4.ms["supplier3"])

    log.info('Supplier 4 has been successfully restored.')
def test_deleting_twice(topo_m2):
    """Deleting entry twice crashed a server

    :id: 94045560-a64c-11ea-93d6-8c16451d917b
    :setup: MMR with 2 masters
    :steps:
        1. Adding entry
        2. Deleting the same entry from s1
        3. Deleting the same entry from s2 after some seconds
    :expected results:
        1. Should succeeds
        2. Should succeeds
        3. Should succeeds
    """
    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]
    # Adding entry
    user1 = UserAccounts(m1, DEFAULT_SUFFIX, rdn=None).create_test_user(uid=1,
                                                                        gid=1)
    repl_manager = ReplicationManager(DEFAULT_SUFFIX)
    repl_manager.wait_for_replication(m1, m2, timeout=100)
    user2 = UserAccount(m2, f'uid=test_user_1,{DEFAULT_SUFFIX}')
    assert user2.status()
    # Deleting the same entry from s1
    user1.delete()
    repl_manager.wait_for_replication(m1, m2, timeout=100)
    # Deleting the same entry from s2 after some seconds
    with pytest.raises(ldap.NO_SUCH_OBJECT):
        user2.delete()
    assert m1.status()
    assert m2.status()
예제 #4
0
def test_double_delete(topo_m2, test_entry):
    """Check that double delete of the entry doesn't crash server

    :id: 3496c82d-636a-48c9-973c-2455b12164cc
    :setup: Two masters replication setup, a test entry
    :steps:
        1. Delete the entry on the first master
        2. Delete the entry on the second master
        3. Check that server is alive
    :expectedresults:
        1. Entry should be successfully deleted from first master
        2. Entry should be successfully deleted from second aster
        3. Server should me alive
    """

    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.disable_to_master(m1, [m2])
    repl.disable_to_master(m2, [m1])

    log.info('Deleting entry {} from master1'.format(test_entry.dn))
    topo_m2.ms["master1"].delete_s(test_entry.dn)

    log.info('Deleting entry {} from master2'.format(test_entry.dn))
    topo_m2.ms["master2"].delete_s(test_entry.dn)

    repl.enable_to_master(m2, [m1])
    repl.enable_to_master(m1, [m2])

    repl.test_replication(m1, m2)
    repl.test_replication(m2, m1)
예제 #5
0
def test_ticket50232_normal(topology_st):
    """
    The fix for ticket 50232


    The test sequence is:
    - create suffix
    - add suffix entry and some child entries
    - "normally" done after populating suffix: enable replication
    - get RUV and database generation
    - export -r
    - import
    - get RUV and database generation
    - assert database generation has not changed
    """

    log.info('Testing Ticket 50232 - export creates not imprtable ldif file, normal creation order')

    topology_st.standalone.backend.create(NORMAL_SUFFIX, {BACKEND_NAME: NORMAL_BACKEND_NAME})
    topology_st.standalone.mappingtree.create(NORMAL_SUFFIX, bename=NORMAL_BACKEND_NAME, parent=None)

    _populate_suffix(topology_st.standalone, NORMAL_BACKEND_NAME)

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl._ensure_changelog(topology_st.standalone)
    replicas = Replicas(topology_st.standalone)
    replicas.create(properties={
        'cn': 'replica',
        'nsDS5ReplicaRoot': NORMAL_SUFFIX,
        'nsDS5ReplicaId': '1',
        'nsDS5Flags': '1',
        'nsDS5ReplicaType': '3'
        })

    _test_export_import(topology_st.standalone, NORMAL_SUFFIX, NORMAL_BACKEND_NAME)
예제 #6
0
def m4rid(request, topology_m4):
    log.debug("-------------- BEGIN RESET of m4 -----------------")
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.test_replication_topology(topology_m4.ms.values())
    # What is master4's rid?
    m4rid = repl.get_rid(topology_m4.ms["master4"])

    def fin():
        try:
            cruv_task = CleanAllRUVTask(topology_m4.ms["master1"])
            cruv_task.create(properties={
                'replica-id': m4rid,
                'replica-base-dn': DEFAULT_SUFFIX
            })
            cruv_task.wait()
        except ldap.UNWILLING_TO_PERFORM:
            # In some casse we already cleaned rid4, so if we fail, it's okay
            pass
        restore_master4(topology_m4)
        # Make sure everything works.
        repl.test_replication_topology(topology_m4.ms.values())

    request.addfinalizer(fin)
    log.debug("-------------- FINISH RESET of m4 -----------------")
    return m4rid
예제 #7
0
def test_ticket50232_reverse(topology_st):
    """
    The fix for ticket 50232


    The test sequence is:
    - create suffix
    - enable replication before suffix enztry is added
    - add suffix entry and some child entries
    - get RUV and database generation
    - export -r
    - import
    - get RUV and database generation
    - assert database generation has not changed
    """

    log.info('Testing Ticket 50232 - export creates not imprtable ldif file, normal creation order')

    #
    # Setup Replication
    #
    log.info('Setting up replication...')
    repl = ReplicationManager(DEFAULT_SUFFIX)
    # repl.create_first_supplier(topology_st.standalone)
    #
    # enable dynamic plugins, memberof and retro cl plugin
    #
    topology_st.standalone.backend.create(REVERSE_SUFFIX, {BACKEND_NAME: REVERSE_BACKEND_NAME})
    topology_st.standalone.mappingtree.create(REVERSE_SUFFIX, bename=REVERSE_BACKEND_NAME, parent=None)

    _enable_replica(topology_st.standalone, REVERSE_SUFFIX)

    _populate_suffix(topology_st.standalone, REVERSE_BACKEND_NAME)

    _test_export_import(topology_st.standalone, REVERSE_SUFFIX, REVERSE_BACKEND_NAME)
def test_userpassword_attribute(topo_m2, _delete_after):
    """Modifications of userpassword attribute in an MMR environment were successful
        however a error message was displayed in the error logs which was curious.

    :id: bdcf0464-a947-11ea-9f0d-8c16451d917b
    :setup: MMR with 2 masters
    :steps:
        1. Add the test user to S1
        2. Check that user's  has been propogated to Supplier 2
        3. modify user's userpassword attribute on supplier 2
        4. check the error logs on suppler 1 to make sure the error message is not there
    :expected results:
        1. Should succeeds
        2. Should succeeds
        3. Should succeeds
        4. Should succeeds
    """
    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]
    # Add the test user to S1
    user1 = UserAccounts(m1, DEFAULT_SUFFIX, rdn=None).create_test_user(uid=1,
                                                                        gid=1)
    repl_manager = ReplicationManager(DEFAULT_SUFFIX)
    repl_manager.wait_for_replication(m1, m2, timeout=100)
    # Check that user's  has been propogated to Supplier 2
    user2 = UserAccount(m2, user1.dn)
    assert user2.status()
    # modify user's userpassword attribute on supplier 2
    user2.replace('userpassword', 'fred1')
    repl_manager.wait_for_replication(m1, m2, timeout=100)
    assert user1.get_attr_val_utf8('userpassword')
    # check the error logs on suppler 1 to make sure the error message is not there
    assert not m1.searchErrorsLog("can\'t add a change for uid=")
예제 #9
0
def m4rid(request, topology_m4):
    log.debug(
        "Wait a bit before the reset - it is required for the slow machines")
    time.sleep(5)
    log.debug("-------------- BEGIN RESET of m4 -----------------")
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.test_replication_topology(topology_m4.ms.values())
    # What is master4's rid?
    m4rid = repl.get_rid(topology_m4.ms["master4"])

    def fin():
        try:
            # Restart the masters and rerun cleanallruv
            for inst in topology_m4.ms.values():
                inst.restart()

            cruv_task = CleanAllRUVTask(topology_m4.ms["master1"])
            cruv_task.create(
                properties={
                    'replica-id': m4rid,
                    'replica-base-dn': DEFAULT_SUFFIX,
                    'replica-force-cleaning': 'no',
                })
            cruv_task.wait()
        except ldap.UNWILLING_TO_PERFORM:
            # In some casse we already cleaned rid4, so if we fail, it's okay
            pass
        restore_master4(topology_m4)
        # Make sure everything works.
        repl.test_replication_topology(topology_m4.ms.values())

    request.addfinalizer(fin)
    log.debug("-------------- FINISH RESET of m4 -----------------")
    return m4rid
예제 #10
0
def test_extract_pemfiles(tls_client_auth):
    """Test TLS client authentication between two masters operates
    as expected with 'on' and 'off' options of nsslapd-extract-pemfiles

    :id: 922d16f8-662a-4915-a39e-0aecd7c8e6e1
    :setup: Two master replication, enabled TLS client auth
    :steps:
        1. Check that nsslapd-extract-pemfiles default value is right
        2. Check that replication works with both 'on' and 'off' values
    :expectedresults:
        1. Success
        2. Replication works
    """

    m1 = tls_client_auth.ms['master1']
    m2 = tls_client_auth.ms['master2']
    repl = ReplicationManager(DEFAULT_SUFFIX)

    if ds_is_older('1.3.7'):
        default_val = 'off'
    else:
        default_val = 'on'
    attr_val = m1.config.get_attr_val_utf8('nsslapd-extract-pemfiles')
    log.info("Check that nsslapd-extract-pemfiles is {}".format(default_val))
    assert attr_val == default_val

    for extract_pemfiles in ('on', 'off'):
        log.info(
            "Set nsslapd-extract-pemfiles = '{}' and check replication works)")
        m1.config.set('nsslapd-extract-pemfiles', extract_pemfiles)
        m2.config.set('nsslapd-extract-pemfiles', extract_pemfiles)
        repl.test_replication_topology(tls_client_auth)
예제 #11
0
def test_new_suffix(topo_m4, new_suffix):
    """Check that we can enable replication on a new suffix

    :id: d44a9ed4-26b0-4189-b0d0-b2b336ddccbd
    :setup: Four masters replication setup, a new suffix
    :steps:
        1. Enable replication on the new suffix
        2. Check if replication works
        3. Disable replication on the new suffix
    :expectedresults:
        1. Replication on the new suffix should be enabled
        2. Replication should work
        3. Replication on the new suffix should be disabled
    """
    m1 = topo_m4.ms["master1"]
    m2 = topo_m4.ms["master2"]

    repl = ReplicationManager(NEW_SUFFIX)

    repl.create_first_master(m1)

    repl.join_master(m1, m2)

    repl.test_replication(m1, m2)
    repl.test_replication(m2, m1)

    repl.remove_master(m1)
    repl.remove_master(m2)
예제 #12
0
def restore_supplier4(topology_m4):
    """In our tests will always be removing supplier 4, so we need a common
    way to restore it for another test
    """

    log.info('Restoring supplier 4...')

    # Enable replication on supplier 4
    M4 = topology_m4.ms["supplier4"]
    M1 = topology_m4.ms["supplier1"]
    repl = ReplicationManager(SUFFIX)
    repl.join_supplier(M1, M4)
    repl.ensure_agreement(M4, M1)
    repl.ensure_agreement(M1, M4)

    # Test Replication is working
    for num in range(2, 5):
        if topology_m4.ms["supplier1"].testReplication(DEFAULT_SUFFIX, topology_m4.ms["supplier{}".format(num)]):
            log.info('Replication is working m1 -> m{}.'.format(num))
        else:
            log.fatal('restore_supplier4: Replication is not working from m1 -> m{}.'.format(num))
            assert False
        time.sleep(1)

    # Check replication is working from supplier 4 to supplier1...
    if topology_m4.ms["supplier4"].testReplication(DEFAULT_SUFFIX, topology_m4.ms["supplier1"]):
        log.info('Replication is working m4 -> m1.')
    else:
        log.fatal('restore_supplier4: Replication is not working from m4 -> 1.')
        assert False
    time.sleep(5)

    log.info('Supplier 4 has been successfully restored.')
예제 #13
0
def test_ticket48266_fractional(topology_m2, entries):
    ents = topology_m2.ms["supplier1"].agreement.list(suffix=SUFFIX)
    assert len(ents) == 1

    mod = [(ldap.MOD_REPLACE, 'nsDS5ReplicatedAttributeList',
            [b'(objectclass=*) $ EXCLUDE telephonenumber']),
           (ldap.MOD_REPLACE, 'nsds5ReplicaStripAttrs',
            [b'modifiersname modifytimestamp'])]
    ents = topology_m2.ms["supplier1"].agreement.list(suffix=SUFFIX)
    assert len(ents) == 1
    m1_m2_agmt = ents[0].dn
    topology_m2.ms["supplier1"].modify_s(ents[0].dn, mod)

    ents = topology_m2.ms["supplier2"].agreement.list(suffix=SUFFIX)
    assert len(ents) == 1
    topology_m2.ms["supplier2"].modify_s(ents[0].dn, mod)

    topology_m2.ms["supplier1"].restart()
    topology_m2.ms["supplier2"].restart()

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.ensure_agreement(topology_m2.ms["supplier1"],
                          topology_m2.ms["supplier2"])
    repl.test_replication(topology_m2.ms["supplier1"],
                          topology_m2.ms["supplier2"])
예제 #14
0
def check_all_replicated():
    """
    Will check replication status
    """
    for supplier in [SUPPLIER2, CONSUMER1, CONSUMER2]:
        ReplicationManager(DEFAULT_SUFFIX).wait_for_replication(SUPPLIER1,
                                                                supplier,
                                                                timeout=100)
예제 #15
0
def test_online_reinit_may_hang(topo_with_sigkill):
    """Online reinitialization may hang when the first
       entry of the DB is RUV entry instead of the suffix

    :id: cded6afa-66c0-4c65-9651-993ba3f7a49c
    :setup: 2 Supplier Instances
    :steps:
        1. Export the database
        2. Move RUV entry to the top in the ldif file
        3. Import the ldif file
        4. Check that replication is still working
        5. Online replica initializaton
    :expectedresults:
        1. Ldif file should be created successfully
        2. RUV entry should be on top in the ldif file
        3. Import should be successful
        4. Replication should work
        5. Server should not hang and consume 100% CPU
    """
    M1 = topo_with_sigkill.ms["supplier1"]
    M2 = topo_with_sigkill.ms["supplier2"]
    M1.stop()
    ldif_file = '%s/supplier1.ldif' % M1.get_ldif_dir()
    M1.db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX],
               excludeSuffixes=None, repl_data=True,
               outputfile=ldif_file, encrypt=False)
    _move_ruv(ldif_file)
    M1.ldif2db(DEFAULT_BENAME, None, None, None, ldif_file)
    M1.start()
    # After this server may hang
    # Exporting idle server with replication data and reimporting
    # should not break replication (Unless we hit issue 5098)
    # So let check that replication is still working.
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.test_replication_topology(topo_with_sigkill)
    agmt = Agreements(M1).list()[0]
    agmt.begin_reinit()
    (done, error) = agmt.wait_reinit()
    assert done is True
    assert error is False
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.test_replication_topology(topo_with_sigkill)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
예제 #16
0
def check_all_replicated():
    """
    Will check replication status
    """
    for master in [MASTER2, CONSUMER1, CONSUMER2]:
        ReplicationManager(DEFAULT_SUFFIX).wait_for_replication(MASTER1,
                                                                master,
                                                                timeout=100)
예제 #17
0
def topology_with_tls(topology_m2):
    """Enable TLS on all suppliers"""

    [i.enable_tls() for i in topology_m2]

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.test_replication(topology_m2.ms['supplier1'], topology_m2.ms['supplier2'])

    return topology_m2
예제 #18
0
def remove_supplier4_agmts(msg, topology_m4):
    """Remove all the repl agmts to supplier4. """

    log.info('%s: remove all the agreements to supplier 4...' % msg)
    repl = ReplicationManager(DEFAULT_SUFFIX)
    # This will delete m4 frm the topo *and* remove all incoming agreements
    # to m4.
    repl.remove_supplier(topology_m4.ms["supplier4"],
        [topology_m4.ms["supplier1"], topology_m4.ms["supplier2"], topology_m4.ms["supplier3"]])
예제 #19
0
def fractional_server_to_replica(server, replica):
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.ensure_agreement(server, replica)
    replica_server = Replicas(server).get(DEFAULT_SUFFIX)
    agmt_server = replica_server.get_agreements().list()[0]
    agmt_server.replace_many(
        ('nsDS5ReplicatedAttributeListTotal', '(objectclass=*) $ EXCLUDE telephoneNumber'),
        ('nsDS5ReplicatedAttributeList', '(objectclass=*) $ EXCLUDE telephoneNumber'),
        ('nsds5ReplicaStripAttrs', 'modifiersname modifytimestamp'),
    )
예제 #20
0
def test_invalid_agmt(topo_m2):
    """Test adding that an invalid agreement is properly rejected and does not crash the server

    :id: 6c3b2a7e-edcd-4327-a003-6bd878ff722b
    :setup: Four masters replication setup
    :steps:
        1. Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
        2. Verify the server is still running
    :expectedresults:
        1. Invalid repl agreement should be rejected
        2. Server should be still running
    """

    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]

    repl = ReplicationManager(DEFAULT_SUFFIX)

    replicas = Replicas(m1)
    replica = replicas.get(DEFAULT_SUFFIX)
    agmts = replica.get_agreements()

    # Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
    with pytest.raises(ldap.UNWILLING_TO_PERFORM):
        agmts.create(
            properties={
                'cn': 'whatever',
                'nsDS5ReplicaRoot': DEFAULT_SUFFIX,
                'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config',
                'nsDS5ReplicaBindMethod': 'simple',
                'nsDS5ReplicaTransportInfo': 'LDAP',
                'nsds5replicaTimeout': '5',
                'description': "test agreement",
                'nsDS5ReplicaHost': m2.host,
                'nsDS5ReplicaPort': str(m2.port),
                'nsDS5ReplicaCredentials': 'whatever',
                'nsds5ReplicaEnabled': 'YEAH MATE, LETS REPLICATE'
            })

    # Verify the server is still running
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.test_replication(m1, m2)
    repl.test_replication(m2, m1)
예제 #21
0
def test_healthcheck_replication_replica_not_reachable(topology_m2):
    """Check if HealthCheck returns DSREPLLE0005 code

    :id: d452a564-7b82-4c1a-b331-a71abbd82a10
    :setup: Replicated topology
    :steps:
        1. Create a replicated topology
        2. On M1, set nsds5replicaport for the replication agreement to an unreachable port on the replica
        3. Use HealthCheck without --json option
        4. Use HealthCheck with --json option
        5. On M1, set nsds5replicaport for the replication agreement to a reachable port number
        6. Use HealthCheck without --json option
        7. Use HealthCheck with --json option
    :expectedresults:
        1. Success
        2. Success
        3. Healthcheck reports DSREPLLE0005 code and related details
        4. Healthcheck reports DSREPLLE0005 code and related details
        5. Success
        6. Healthcheck reports no issue found
        7. Healthcheck reports no issue found
    """

    RET_CODE = 'DSREPLLE0005'

    M1 = topology_m2.ms['supplier1']
    M2 = topology_m2.ms['supplier2']

    set_changelog_trimming(M1)

    log.info(
        'Set nsds5replicaport for the replication agreement to an unreachable port'
    )
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.wait_for_replication(M1, M2)

    replica_m1 = Replicas(M1).get(DEFAULT_SUFFIX)
    agmt_m1 = replica_m1.get_agreements().list()[0]
    agmt_m1.replace('nsds5replicaport', '4389')
    # Should generates updates here to insure that we starts a new replication session
    # and really try to connect to the consumer
    with suppress(Exception):
        repl.wait_for_replication(M1, M2, timeout=5)

    run_healthcheck_and_flush_log(topology_m2, M1, RET_CODE, json=False)
    run_healthcheck_and_flush_log(topology_m2, M1, RET_CODE, json=True)

    log.info(
        'Set nsds5replicaport for the replication agreement to a reachable port'
    )
    agmt_m1.replace('nsDS5ReplicaPort', '{}'.format(M2.port))
    repl.wait_for_replication(M1, M2)

    run_healthcheck_and_flush_log(topology_m2, M1, CMD_OUTPUT, json=False)
    run_healthcheck_and_flush_log(topology_m2, M1, JSON_OUTPUT, json=True)
예제 #22
0
def test_lastupdate_attr_before_init(topo_nr):
    """Check that LastUpdate replica attributes show right values

    :id: bc8ce431-ff65-41f5-9331-605cbcaaa887
    :customerscenario: True
    :setup: Replication setup with supplier and consumer instances
            without initialization
    :steps:
        1. Check nsds5replicaLastUpdateStart value
        2. Check nsds5replicaLastUpdateEnd value
        3. Check nsds5replicaLastUpdateStatus value
        4. Check nsds5replicaLastUpdateStatusJSON is parsable
    :expectedresults:
        1. nsds5replicaLastUpdateStart should be equal to 0
        2. nsds5replicaLastUpdateEnd should be equal to 0
        3. nsds5replicaLastUpdateStatus should not be equal
           to "Replica acquired successfully: Incremental update started"
        4. Success
    """

    supplier = topo_nr.ins["standalone1"]
    consumer = topo_nr.ins["standalone2"]

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.create_first_supplier(supplier)

    # Manually create an un-synced consumer.

    consumer_replicas = Replicas(consumer)
    consumer_replicas.create(
        properties={
            'cn': 'replica',
            'nsDS5ReplicaRoot': DEFAULT_SUFFIX,
            'nsDS5ReplicaId': '65535',
            'nsDS5Flags': '0',
            'nsDS5ReplicaType': '2',
        })

    agmt = repl.ensure_agreement(supplier, consumer)
    with pytest.raises(Exception):
        repl.wait_for_replication(supplier, consumer, timeout=5)

    assert agmt.get_attr_val_utf8(
        'nsds5replicaLastUpdateStart') == "19700101000000Z"
    assert agmt.get_attr_val_utf8(
        "nsds5replicaLastUpdateEnd") == "19700101000000Z"
    assert "replica acquired successfully" not in agmt.get_attr_val_utf8_l(
        "nsds5replicaLastUpdateStatus")

    # make sure the JSON attribute is parsable
    json_status = agmt.get_attr_val_utf8("nsds5replicaLastUpdateStatusJSON")
    if json_status is not None:
        json_obj = json.loads(json_status)
        log.debug("JSON status message: {}".format(json_obj))
예제 #23
0
def delete_users_and_wait(topo_m4, automem_scope):
    """
    Deletes entries after test and waits for replication.
    """
    for user in nsAdminGroups(topo_m4.ms['master1'], automem_scope,
                              rdn=None).list():
        user.delete()
    for master in [
            topo_m4.ms['master2'], topo_m4.ms['master3'], topo_m4.ms['master4']
    ]:
        ReplicationManager(DEFAULT_SUFFIX).wait_for_replication(
            topo_m4.ms['master1'], master, timeout=30000)
def test_deletions_are_not_replicated(topo_m2):
    """usn + mmr = deletions are not replicated

    :id: aa4f67ce-a64c-11ea-a6fd-8c16451d917b
    :setup: MMR with 2 masters
    :steps:
        1. Enable USN plugin on both servers
        2. Enable USN plugin on Supplier 2
        3. Add user
        4. Check that user propagated to Supplier 2
        5. Check user`s USN on Supplier 1
        6. Check user`s USN on Supplier 2
        7. Delete user
        8. Check that deletion of user propagated to Supplier 1
    :expected results:
        1. Should succeeds
        2. Should succeeds
        3. Should succeeds
        4. Should succeeds
        5. Should succeeds
        6. Should succeeds
        7. Should succeeds
        8. Should succeeds
    """
    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]
    # Enable USN plugin on both servers
    usn1 = USNPlugin(m1)
    usn2 = USNPlugin(m2)
    for usn_usn in [usn1, usn2]:
        usn_usn.enable()
    for instance in [m1, m2]:
        instance.restart()
    # Add user
    user = UserAccounts(m1, DEFAULT_SUFFIX, rdn=None).create_test_user(uid=1,
                                                                       gid=1)
    repl_manager = ReplicationManager(DEFAULT_SUFFIX)
    repl_manager.wait_for_replication(m1, m2, timeout=100)
    # Check that user propagated to Supplier 2
    assert user.dn in [
        i.dn for i in UserAccounts(m2, DEFAULT_SUFFIX, rdn=None).list()
    ]
    user2 = UserAccount(m2, f'uid=test_user_1,{DEFAULT_SUFFIX}')
    # Check user`s USN on Supplier 1
    assert user.get_attr_val_utf8('entryusn')
    # Check user`s USN on Supplier 2
    assert user2.get_attr_val_utf8('entryusn')
    # Delete user
    user2.delete()
    repl_manager.wait_for_replication(m1, m2, timeout=100)
    # Check that deletion of user propagated to Supplier 1
    with pytest.raises(ldap.NO_SUCH_OBJECT):
        user.status()
예제 #25
0
def _enable_replica(instance, suffix):

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl._ensure_changelog(instance)
    replicas = Replicas(instance)
    replicas.create(properties={
        'cn': 'replica',
        'nsDS5ReplicaRoot': suffix,
        'nsDS5ReplicaId': '1',
        'nsDS5Flags': '1',
        'nsDS5ReplicaType': '3'
        })
예제 #26
0
def test_entryuuid_with_replication(topo_m2):
    """ Check that entryuuid works with replication

    :id: a5f15bf9-7f63-473a-840c-b9037b787024

    :setup: two node mmr

    :steps:
        1. Create an entry on one server
        2. Wait for replication
        3. Assert it is on the second

    :expectedresults:
        1. Success
        1. Success
        1. Success
    """

    server_a = topo_m2.ms["supplier1"]
    server_b = topo_m2.ms["supplier2"]
    server_a.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.TRACE))
    server_b.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.TRACE))

    repl = ReplicationManager(DEFAULT_SUFFIX)

    account_a = nsUserAccounts(server_a,
                               DEFAULT_SUFFIX).create_test_user(uid=2000)
    euuid_a = account_a.get_attr_vals_utf8('entryUUID')
    print("🧩 %s" % euuid_a)
    assert (euuid_a is not None)
    assert (len(euuid_a) == 1)

    repl.wait_for_replication(server_a, server_b)

    account_b = nsUserAccounts(server_b, DEFAULT_SUFFIX).get("test_user_2000")
    euuid_b = account_b.get_attr_vals_utf8('entryUUID')
    print("🧩 %s" % euuid_b)

    server_a.config.loglevel(vals=(ErrorLog.DEFAULT, ))
    server_b.config.loglevel(vals=(ErrorLog.DEFAULT, ))

    assert (euuid_b is not None)
    assert (len(euuid_b) == 1)
    assert (euuid_b == euuid_a)

    account_b.set("description", "update")
    repl.wait_for_replication(server_b, server_a)

    euuid_c = account_a.get_attr_vals_utf8('entryUUID')
    print("🧩 %s" % euuid_c)
    assert (euuid_c is not None)
    assert (len(euuid_c) == 1)
    assert (euuid_c == euuid_a)
예제 #27
0
def test_ssl_transport(tls_client_auth):
    """Test different combinations for nsDS5ReplicaTransportInfo values

    :id: 922d16f8-662a-4915-a39e-0aecd7c8e6e2
    :setup: Two master replication, enabled TLS client auth
    :steps:
        1. Set nsDS5ReplicaTransportInfoCheck: SSL or StartTLS or TLS
        2. Restart the instance
        3. Check that replication works
        4. Set nsDS5ReplicaTransportInfoCheck: LDAPS back
    :expectedresults:
        1. Success
        2. Success
        3. Replication works
        4. Success
    """

    m1 = tls_client_auth.ms['master1']
    m2 = tls_client_auth.ms['master2']
    repl = ReplicationManager(DEFAULT_SUFFIX)
    replica_m1 = Replicas(m1).get(DEFAULT_SUFFIX)
    replica_m2 = Replicas(m2).get(DEFAULT_SUFFIX)
    agmt_m1 = replica_m1.get_agreements().list()[0]
    agmt_m2 = replica_m2.get_agreements().list()[0]

    if ds_is_older('1.4.0.6'):
        check_list = (('TLS', False), )
    else:
        check_list = (('SSL', True), ('StartTLS', False), ('TLS', False))

    for transport, secure_port in check_list:
        agmt_m1.replace_many(
            ('nsDS5ReplicaTransportInfo', transport),
            ('nsDS5ReplicaPort',
             '{}'.format(m2.port if not secure_port else m2.sslport)))
        agmt_m2.replace_many(
            ('nsDS5ReplicaTransportInfo', transport),
            ('nsDS5ReplicaPort',
             '{}'.format(m1.port if not secure_port else m1.sslport)))
        repl.test_replication_topology(tls_client_auth)

    if ds_is_older('1.4.0.6'):
        agmt_m1.replace_many(('nsDS5ReplicaTransportInfo', 'SSL'),
                             ('nsDS5ReplicaPort', str(m2.sslport)))
        agmt_m2.replace_many(('nsDS5ReplicaTransportInfo', 'SSL'),
                             ('nsDS5ReplicaPort', str(m1.sslport)))
    else:
        agmt_m1.replace_many(('nsDS5ReplicaTransportInfo', 'LDAPS'),
                             ('nsDS5ReplicaPort', str(m2.sslport)))
        agmt_m2.replace_many(('nsDS5ReplicaTransportInfo', 'LDAPS'),
                             ('nsDS5ReplicaPort', str(m1.sslport)))
    repl.test_replication_topology(tls_client_auth)
예제 #28
0
def test_special_symbol_replica_agreement(topo_i2):
    """ Check if agreement starts with "cn=->..." then
    after upgrade does it get removed.
    
    :id: 68aa0072-4dd4-4e33-b107-cb383a439125
    :setup: two standalone instance
    :steps:
        1. Create and Enable Replication on standalone2 and role as consumer
        2. Create and Enable Replication on standalone1 and role as master
        3. Create a Replication agreement starts with "cn=->..."
        4. Perform an upgrade operation over the master
        5. Check if the agreement is still present or not.
    :expectedresults:
        1. It should be successful
        2. It should be successful
        3. It should be successful
        4. It should be successful
        5. It should be successful
    """

    master = topo_i2.ins["standalone1"]
    consumer = topo_i2.ins["standalone2"]
    consumer.replica.enableReplication(suffix=DEFAULT_SUFFIX,
                                       role=ReplicaRole.CONSUMER,
                                       replicaId=CONSUMER_REPLICAID)
    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.create_first_master(master)

    properties = {
        RA_NAME: '-\\3meTo_{}:{}'.format(consumer.host, str(consumer.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]
    }

    master.agreement.create(suffix=SUFFIX,
                            host=consumer.host,
                            port=consumer.port,
                            properties=properties)

    master.agreement.init(SUFFIX, consumer.host, consumer.port)

    replica_server = Replicas(master).get(DEFAULT_SUFFIX)

    master.upgrade('online')

    agmt = replica_server.get_agreements().list()[0]

    assert agmt.get_attr_val_utf8('cn') == '-\\3meTo_{}:{}'.format(
        consumer.host, str(consumer.port))
예제 #29
0
def test_promote_demote(topo):
    """Test promoting and demoting a replica

    :id: 75edff64-f987-4ed5-a03d-9bee73c0fbf0
    :setup: 2 Supplier Instances
    :steps:
        1. Promote Hub to a Supplier
        2. Test replication works
        3. Demote the supplier to a consumer
        4. Test replication works
        5. Promote consumer to supplier
        6. Test replication works
    :expectedresults:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
    """

    supplier = topo.ms["supplier1"]
    supplier_replica = Replicas(supplier).get(DEFAULT_SUFFIX)
    bind_dn = supplier_replica.get_attr_val_utf8('nsDS5ReplicaBindDN')
    hub = topo.hs["hub1"]
    hub_replica = Replicas(hub).get(DEFAULT_SUFFIX)
    consumer = topo.cs["consumer1"]

    repl = ReplicationManager(DEFAULT_SUFFIX)

    # promote replica
    hub_replica.promote(ReplicaRole.SUPPLIER, binddn=bind_dn, rid='55')
    repl.test_replication(supplier, consumer)

    # Demote the replica
    hub_replica.demote(ReplicaRole.CONSUMER)
    repl.test_replication(supplier, hub)

    # promote replica and init it
    hub_replica.promote(ReplicaRole.SUPPLIER, binddn=bind_dn, rid='56')
    agmt = Agreements(supplier).list()[0]
    agmt.begin_reinit()
    agmt.wait_reinit()

    # init consumer
    agmt = Agreements(hub).list()[0]
    agmt.begin_reinit()
    agmt.wait_reinit()
    repl.test_replication(supplier, consumer)
예제 #30
0
def test_password_repl_error(topo_m2, test_entry):
    """Check that error about userpassword replication is properly logged

    :id: 714130ff-e4f0-4633-9def-c1f4b24abfef
    :setup: Four masters replication setup, a test entry
    :steps:
        1. Change userpassword on the first master
        2. Restart the servers to flush the logs
        3. Check the error log for an replication error
    :expectedresults:
        1. Password should be successfully changed
        2. Server should be successfully restarted
        3. There should be no replication errors in the error log
    """

    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]
    TEST_ENTRY_NEW_PASS = '******'

    log.info('Clean the error log')
    m2.deleteErrorLogs()

    log.info('Set replication loglevel')
    m2.config.loglevel((ErrorLog.REPLICA, ))

    log.info('Modifying entry {} - change userpassword on master 1'.format(
        test_entry.dn))

    test_entry.set('userpassword', TEST_ENTRY_NEW_PASS)

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.wait_for_replication(m1, m2)

    log.info('Restart the servers to flush the logs')
    for num in range(1, 3):
        topo_m2.ms["master{}".format(num)].restart()

    try:
        log.info('Check that password works on master 2')
        test_entry_m2 = UserAccount(m2, test_entry.dn)
        test_entry_m2.bind(TEST_ENTRY_NEW_PASS)

        log.info('Check the error log for the error with {}'.format(
            test_entry.dn))
        assert not m2.ds_error_log.match(
            '.*can.t add a change for {}.*'.format(test_entry.dn))
    finally:
        log.info('Set the default loglevel')
        m2.config.loglevel((ErrorLog.DEFAULT, ))