Beispiel #1
0
def health_check_run(inst, log, args):
    """Connect to the local server using LDAPI, and perform various health checks
    """

    if args.list_errors:
        _list_errors(log)
        return

    # update the args for connect_instance()
    args.basedn = None
    args.binddn = None
    args.bindpw = None
    args.starttls = None
    args.pwdfile = None
    args.prompt = False
    dsrc_inst = dsrc_to_ldap(DSRC_HOME, args.instance, log.getChild('dsrc'))
    dsrc_inst = dsrc_arg_concat(args, dsrc_inst)
    try:
        inst = connect_instance(dsrc_inst=dsrc_inst,
                                verbose=args.verbose,
                                args=args)
    except Exception as e:
        raise ValueError('Failed to connect to Directory Server instance: ' +
                         str(e))

    checks = args.check or dict(_list_targets(inst)).keys()

    if args.list_checks or args.dry_run:
        _print_checks(inst, log, checks)
        return

    _run(inst, log, args, _list_checks(inst, checks))

    disconnect_instance(inst)
Beispiel #2
0
def test_retrocl_exclude_attr_add(topology_st):
    """ Test exclude attribute feature of the retrocl plugin for add operation

    :id: 3481650f-2070-45ef-9600-2500cfc51559

    :setup: Standalone instance

    :steps:
        1. Enable dynamic plugins
        2. Confige retro changelog plugin
        3. Add an entry
        4. Ensure entry attrs are in the changelog
        5. Exclude an attr
        6. Add another entry
        7. Ensure excluded attr is not in the changelog

    :expectedresults:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
    """

    st = topology_st.standalone

    log.info('Configure retrocl plugin')
    rcl = RetroChangelogPlugin(st)
    rcl.disable()
    rcl.enable()
    rcl.replace('nsslapd-attribute', 'nsuniqueid:targetUniqueId')

    log.info('Restarting instance')
    try:
        st.restart()
    except ldap.LDAPError as e:
        ldap.error('Failed to restart instance ' + e.args[0]['desc'])
        assert False

    users = UserAccounts(st, DEFAULT_SUFFIX)

    log.info('Adding user1')
    try:
        users.create(
            properties={
                'sn': '1',
                'cn': 'user 1',
                'uid': 'user1',
                'uidNumber': '11',
                'gidNumber': '111',
                'givenname': 'user1',
                'homePhone': '0861234567',
                'carLicense': '131D16674',
                'mail': '*****@*****.**',
                'homeDirectory': '/home/user1',
                'userpassword': USER_PW
            })
    except ldap.ALREADY_EXISTS:
        pass
    except ldap.LDAPError as e:
        log.error("Failed to add user1: " + str(e))

    log.info(
        'Verify homePhone and carLicense attrs are in the changelog changestring'
    )
    try:
        retro_changelog_suffix = DSLdapObjects(st, basedn=RETROCL_SUFFIX)
        cllist = retro_changelog_suffix.filter(f'(targetDn={USER1_DN})')
    except ldap.LDAPError as e:
        log.fatal("Changelog search failed, error: " + str(e))
        assert False
    assert len(cllist) > 0
    if cllist[0].present('changes'):
        clstr = str(cllist[0].get_attr_vals_utf8('changes'))
        assert ATTR_HOMEPHONE in clstr
        assert ATTR_CARLICENSE in clstr

    log.info('Excluding attribute ' + ATTR_HOMEPHONE)
    args = FakeArgs()
    args.connections = [
        st.host + ':' + str(st.port) + ':' + DN_DM + ':' + PW_DM
    ]
    args.instance = 'standalone1'
    args.basedn = None
    args.binddn = None
    args.starttls = False
    args.pwdfile = None
    args.bindpw = None
    args.prompt = False
    args.exclude_attrs = ATTR_HOMEPHONE
    args.func = retrochangelog_add
    dsrc_inst = dsrc_arg_concat(args, None)
    inst = connect_instance(dsrc_inst, False, args)
    result = args.func(inst, None, log, args)
    disconnect_instance(inst)
    assert result is None

    log.info('Restarting instance')
    try:
        st.restart()
    except ldap.LDAPError as e:
        ldap.error('Failed to restart instance ' + e.args[0]['desc'])
        assert False

    log.info('Adding user2')
    try:
        users.create(
            properties={
                'sn': '2',
                'cn': 'user 2',
                'uid': 'user2',
                'uidNumber': '22',
                'gidNumber': '222',
                'givenname': 'user2',
                'homePhone': '0879088363',
                'carLicense': '04WX11038',
                'mail': '*****@*****.**',
                'homeDirectory': '/home/user2',
                'userpassword': USER_PW
            })
    except ldap.ALREADY_EXISTS:
        pass
    except ldap.LDAPError as e:
        log.error("Failed to add user2: " + str(e))

    log.info('Verify homePhone attr is not in the changelog changestring')
    try:
        cllist = retro_changelog_suffix.filter(f'(targetDn={USER2_DN})')
        assert len(cllist) > 0
        if cllist[0].present('changes'):
            clstr = str(cllist[0].get_attr_vals_utf8('changes'))
            assert ATTR_HOMEPHONE not in clstr
            assert ATTR_CARLICENSE in clstr
    except ldap.LDAPError as e:
        log.fatal("Changelog search failed, error: " + str(e))
        assert False
Beispiel #3
0
def test_retrocl_exclude_attr_mod(topology_st):
    """ Test exclude attribute feature of the retrocl plugin for mod operation

    :id: f6bef689-685b-4f86-a98d-f7e6b1fcada3

    :setup: Standalone instance

    :steps:
        1. Enable dynamic plugins
        2. Confige retro changelog plugin
        3. Add user1 entry
        4. Ensure entry attrs are in the changelog
        5. Exclude an attr
        6. Modify user1 entry
        7. Ensure excluded attr is not in the changelog

    :expectedresults:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
    """

    st = topology_st.standalone

    log.info('Configure retrocl plugin')
    rcl = RetroChangelogPlugin(st)
    rcl.disable()
    rcl.enable()
    rcl.replace('nsslapd-attribute', 'nsuniqueid:targetUniqueId')

    log.info('Restarting instance')
    try:
        st.restart()
    except ldap.LDAPError as e:
        ldap.error('Failed to restart instance ' + e.args[0]['desc'])
        assert False

    users = UserAccounts(st, DEFAULT_SUFFIX)

    log.info('Adding user1')
    try:
        user1 = users.create(
            properties={
                'sn': '1',
                'cn': 'user 1',
                'uid': 'user1',
                'uidNumber': '11',
                'gidNumber': '111',
                'givenname': 'user1',
                'homePhone': '0861234567',
                'carLicense': '131D16674',
                'mail': '*****@*****.**',
                'homeDirectory': '/home/user1',
                'userpassword': USER_PW
            })
    except ldap.ALREADY_EXISTS:
        user1 = UserAccount(st, dn=USER1_DN)
    except ldap.LDAPError as e:
        log.error("Failed to add user1: " + str(e))

    log.info(
        'Verify homePhone and carLicense attrs are in the changelog changestring'
    )
    try:
        retro_changelog_suffix = DSLdapObjects(st, basedn=RETROCL_SUFFIX)
        cllist = retro_changelog_suffix.filter(f'(targetDn={USER1_DN})')
    except ldap.LDAPError as e:
        log.fatal("Changelog search failed, error: " + str(e))
        assert False
    assert len(cllist) > 0
    if cllist[0].present('changes'):
        clstr = str(cllist[0].get_attr_vals_utf8('changes'))
        assert ATTR_HOMEPHONE in clstr
        assert ATTR_CARLICENSE in clstr

    log.info('Excluding attribute ' + ATTR_CARLICENSE)
    args = FakeArgs()
    args.connections = [
        st.host + ':' + str(st.port) + ':' + DN_DM + ':' + PW_DM
    ]
    args.instance = 'standalone1'
    args.basedn = None
    args.binddn = None
    args.starttls = False
    args.pwdfile = None
    args.bindpw = None
    args.prompt = False
    args.exclude_attrs = ATTR_CARLICENSE
    args.func = retrochangelog_add
    dsrc_inst = dsrc_arg_concat(args, None)
    inst = connect_instance(dsrc_inst, False, args)
    result = args.func(inst, None, log, args)
    disconnect_instance(inst)
    assert result is None

    log.info('Restarting instance')
    try:
        st.restart()
    except ldap.LDAPError as e:
        ldap.error('Failed to restart instance ' + e.args[0]['desc'])
        assert False

    log.info('Modify user1 carLicense attribute')
    try:
        user1.replace(ATTR_CARLICENSE, "123WX321")
    except ldap.LDAPError as e:
        log.fatal(
            'test_retrocl_exclude_attr_mod: Failed to update user1 attribute: error '
            + e.message['desc'])
        assert False

    log.info('Verify carLicense attr is not in the changelog changestring')
    try:
        cllist = retro_changelog_suffix.filter(f'(targetDn={USER1_DN})')
        assert len(cllist) > 0
        # There will be 2 entries in the changelog for this user, we are only
        #interested in the second one, the modify operation.
        if cllist[1].present('changes'):
            clstr = str(cllist[1].get_attr_vals_utf8('changes'))
            assert ATTR_CARLICENSE not in clstr
    except ldap.LDAPError as e:
        log.fatal("Changelog search failed, error: " + str(e))
        assert False
Beispiel #4
0
def test_dsconf_replication_monitor(topology_m2, set_log_file):
    """Test replication monitor that was ported from legacy tools

    :id: ce48020d-7c30-41b7-8f68-144c9cd757f6
    :setup: 2 MM topology
    :steps:
         1. Create DS instance
         2. Run replication monitor with connections option
         3. Run replication monitor with aliases option
         4. Run replication monitor with --json option
         5. Run replication monitor with .dsrc file created
         6. Run replication monitor with connections option as if using dsconf CLI
    :expectedresults:
         1. Success
         2. Success
         3. Success
         4. Success
         5. Success
         6. Success
    """

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

    # Enable ldapi if not already done.
    for inst in [topology_m2.ms["master1"], topology_m2.ms["master2"]]:
        if not inst.can_autobind():
            # Update ns-slapd instance
            inst.config.set('nsslapd-ldapilisten', 'on')
            inst.config.set('nsslapd-ldapiautobind', 'on')
            inst.restart()
    # Ensure that updates have been sent both ways.
    replicas = Replicas(m1)
    replica = replicas.get(DEFAULT_SUFFIX)
    replica.test_replication([m2])
    replicas = Replicas(m2)
    replica = replicas.get(DEFAULT_SUFFIX)
    replica.test_replication([m1])

    alias_content = [
        'Supplier: M1 (' + m1.host + ':' + str(m1.port) + ')',
        'Supplier: M2 (' + m2.host + ':' + str(m2.port) + ')'
    ]

    connection_content = 'Supplier: ' + m1.host + ':' + str(m1.port)
    content_list = [
        'Replica Root: dc=example,dc=com', 'Replica ID: 1',
        'Replica Status: Available', 'Max CSN',
        'Status For Agreement: "002" (' + m2.host + ':' + str(m2.port) + ')',
        'Replica Enabled: on', 'Update In Progress: FALSE',
        'Last Update Start:', 'Last Update End:', 'Number Of Changes Sent:',
        'Number Of Changes Skipped: None',
        'Last Update Status: Error (0) Replica acquired successfully: Incremental update succeeded',
        'Last Init Start:', 'Last Init End:', 'Last Init Status:',
        'Reap Active: 0', 'Replication Status: In Synchronization',
        'Replication Lag Time:', 'Supplier: ', m2.host + ':' + str(m2.port),
        'Replica Root: dc=example,dc=com', 'Replica ID: 2',
        'Status For Agreement: "001" (' + m1.host + ':' + str(m1.port) + ')'
    ]

    error_list = [
        'consumer (Unavailable)',
        'Failed to retrieve database RUV entry from consumer'
    ]

    json_list = [
        'type', 'list', 'items', 'name', m1.host + ':' + str(m1.port), 'data',
        '"replica_id": "1"', '"replica_root": "dc=example,dc=com"',
        '"replica_status": "Available"', 'maxcsn', 'agmts_status', 'agmt-name',
        '002', 'replica', m2.host + ':' + str(m2.port), 'replica-enabled',
        'update-in-progress', 'last-update-start', 'last-update-end',
        'number-changes-sent', 'number-changes-skipped', 'last-update-status',
        'Error (0) Replica acquired successfully: Incremental update succeeded',
        'last-init-start', 'last-init-end', 'last-init-status', 'reap-active',
        'replication-status', 'In Synchronization', 'replication-lag-time',
        '"replica_id": "2"', '001', m1.host + ':' + str(m1.port)
    ]

    connections = [
        m1.host + ':' + str(m1.port) + ':' + DN_DM + ':' + PW_DM,
        m2.host + ':' + str(m2.port) + ':' + DN_DM + ':' + PW_DM
    ]

    args = FakeArgs()
    args.connections = connections
    args.aliases = None
    args.json = False

    log.info('Run replication monitor with connections option')
    get_repl_monitor_info(m1, DEFAULT_SUFFIX, log, args)
    (host_m1, host_m2) = get_hostnames_from_log(m1.port, m2.port)
    check_value_in_log_and_reset(content_list,
                                 connection_content,
                                 error_list=error_list)

    # Prepare the data for next tests
    aliases = [
        'M1=' + host_m1 + ':' + str(m1.port),
        'M2=' + host_m2 + ':' + str(m2.port)
    ]

    alias_content = [
        'Supplier: M1 (' + host_m1 + ':' + str(m1.port) + ')',
        'Supplier: M2 (' + host_m2 + ':' + str(m2.port) + ')'
    ]

    dsrc_content = '[repl-monitor-connections]\n' \
                   'connection1 = ' + m1.host + ':' + str(m1.port) + ':' + DN_DM + ':' + PW_DM + '\n' \
                   'connection2 = ' + m2.host + ':' + str(m2.port) + ':' + DN_DM + ':' + PW_DM + '\n' \
                   '\n' \
                   '[repl-monitor-aliases]\n' \
                   'M1 = ' + host_m1 + ':' + str(m1.port) + '\n' \
                   'M2 = ' + host_m2 + ':' + str(m2.port)

    log.info('Run replication monitor with aliases option')
    args.aliases = aliases
    get_repl_monitor_info(m1, DEFAULT_SUFFIX, log, args)
    check_value_in_log_and_reset(content_list, alias_content)

    log.info('Run replication monitor with --json option')
    args.aliases = None
    args.json = True
    get_repl_monitor_info(m1, DEFAULT_SUFFIX, log, args)
    check_value_in_log_and_reset(json_list)

    with open(os.path.expanduser(DSRC_HOME), 'w+') as f:
        f.write(dsrc_content)

    args.connections = None
    args.aliases = None
    args.json = False

    log.info('Run replication monitor when .dsrc file is present with content')
    get_repl_monitor_info(m1, DEFAULT_SUFFIX, log, args)
    check_value_in_log_and_reset(content_list, alias_content)
    os.remove(os.path.expanduser(DSRC_HOME))

    log.info(
        'Run replication monitor with connections option as if using dsconf CLI'
    )
    # Perform same test than steps 2 test but without using directly the topology instance.
    # but with an instance similar to those than dsconf cli generates:
    # step 2 args
    args.connections = connections
    args.aliases = None
    args.json = False
    # args needed to generate an instance with dsrc_arg_concat
    args.instance = 'master1'
    args.basedn = None
    args.binddn = None
    args.bindpw = None
    args.pwdfile = None
    args.prompt = False
    args.starttls = False
    dsrc_inst = dsrc_arg_concat(args, None)
    inst = connect_instance(dsrc_inst, True, args)
    get_repl_monitor_info(inst, DEFAULT_SUFFIX, log, args)
    check_value_in_log_and_reset(content_list,
                                 connection_content,
                                 error_list=error_list)