#49626 Issue 49581 - Fix dynamic plugins test suite
Closed 3 years ago by spichugi. Opened 6 years ago by spichugi.
spichugi/389-ds-base dynamic_plugins  into  master

@@ -16,78 +16,83 @@ 

  import ldap.sasl

  import pytest

  from lib389.tasks import *

- from lib389 import DirSrv

- from lib389.properties import *

- import plugin_tests

- import stress_tests

- from lib389.topologies import topology_st

- from lib389._constants import (DN_CONFIG, DEFAULT_SUFFIX, DN_LDBM, defaultProperties,

-                                PLUGIN_MEMBER_OF, PLUGIN_LINKED_ATTRS, PLUGIN_REFER_INTEGRITY,

-                                ReplicaRole, REPLICATION_BIND_DN, REPLICATION_BIND_PW,

-                                REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT,

-                                LOCALHOST, REPLICA_RUV_FILTER, args_instance,

-                                RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD, RA_TRANSPORT_PROT)

+ from lib389.replica import ReplicationManager

+ from lib389.config import LDBMConfig

+ from lib389._constants import *

+ from lib389.topologies import topology_m2

+ from ..plugins import acceptance_test

+ from . import stress_tests

  

  log = logging.getLogger(__name__)

  

  

- def repl_fail(replica):

-     """Remove replica instance, and assert failure"""

+ def check_replicas(topology_m2):

+     """Check that replication is in sync and working"""

  

-     replica.delete()

-     assert False

+     m1 = topology_m2.ms["master1"]

+     m2 = topology_m2.ms["master2"]

  

+     log.info('Checking if replication is in sync...')

+     repl = ReplicationManager(DEFAULT_SUFFIX)

+     repl.test_replication_topology(topology_m2)

+     #

+     # Verify the databases are identical. There should not be any "user, entry, employee" entries

+     #

+     log.info('Checking if the data is the same between the replicas...')

  

- def test_dynamic_plugins(topology_st):

-     """

-         Test Dynamic Plugins - exercise each plugin and its main features, while

-         changing the configuration without restarting the server.

- 

-         Need to test: functionality, stability, and stress.  These tests need to run

-                       with replication disabled, and with replication setup with a

-                       second instance.  Then test if replication is working, and we have

-                       same entries on each side.

- 

-         Functionality - Make sure that as configuration changes are made they take

-                         effect immediately.  Cross plugin interaction (e.g. automember/memberOf)

-                         needs to tested, as well as plugin tasks.  Need to test plugin

-                         config validation(dependencies, etc).

- 

-         Memory Corruption - Restart the plugins many times, and in different orders and test

-                             functionality, and stability.  This will excerise the internal

-                             plugin linked lists, dse callbacks, and task handlers.

- 

-         Stress - Put the server under load that will trigger multiple plugins(MO, RI, DNA, etc)

-                  Restart various plugins while these operations are going on.  Perform this test

-                  5 times(stress_max_run).

+     # Check the master

+     try:

+         entries = m1.search_s(DEFAULT_SUFFIX,

+                               ldap.SCOPE_SUBTREE,

+                               "(|(uid=person*)(uid=entry*)(uid=employee*))")

+         if len(entries) > 0:

+             log.error('Master database has incorrect data set!\n')

+             assert False

+     except ldap.LDAPError as e:

+         log.fatal('Unable to search db on master: ' + e.message['desc'])

+         assert False

+ 

+     # Check the consumer

+     try:

+         entries = m2.search_s(DEFAULT_SUFFIX,

+                               ldap.SCOPE_SUBTREE,

+                               "(|(uid=person*)(uid=entry*)(uid=employee*))")

+         if len(entries) > 0:

+             log.error('Consumer database in not consistent with master database')

+             assert False

+     except ldap.LDAPError as e:

+         log.fatal('Unable to search db on consumer: ' + e.message['desc'])

+         assert False

+ 

+     log.info('Data is consistent across the replicas.\n')

+ 

+ 

+ def test_acceptance(topology_m2):

+     """Exercise each plugin and its main features, while

+     changing the configuration without restarting the server.

+ 

+     Make sure that as configuration changes are made they take

+     effect immediately.  Cross plugin interaction (e.g. automember/memberOf)

+     needs to tested, as well as plugin tasks.  Need to test plugin

+     config validation(dependencies, etc).

      """

  

-     REPLICA_PORT = 33334

-     RUV_FILTER = REPLICA_RUV_FILTER

-     master_maxcsn = 0

-     replica_maxcsn = 0

+     m1 = topology_m2.ms["master1"]

      msg = ' (no replication)'

      replication_run = False

-     stress_max_runs = 5

+ 

+     # First part of the test should be without replication

+     topology_m2.pause_all_replicas()

  

      # First enable dynamic plugins

-     try:

-         topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])

-     except ldap.LDAPError as e:

-         log.fatal('Failed to enable dynamic plugin!' + e.message['desc'])

-         assert False

+     m1.config.replace('nsslapd-dynamic-plugins', 'on')

  

      # Test that critical plugins can be updated even though the change might not be applied

-     try:

-         topology_st.standalone.modify_s(DN_LDBM, [(ldap.MOD_REPLACE, 'description', 'test')])

-     except ldap.LDAPError as e:

-         log.fatal('Failed to apply change to critical plugin' + e.message['desc'])

-         assert False

+     ldbm_config = LDBMConfig(m1)

+     ldbm_config.replace('description', 'test')

  

-     while 1:

-         #

+     while True:

          # First run the tests with replication disabled, then rerun them with replication set up

-         #

  

          ############################################################################

          #  Test plugin functionality
@@ -97,12 +102,53 @@ 

          log.info('Testing Dynamic Plugins Functionality' + msg + '...')

          log.info('####################################################################\n')

  

-         plugin_tests.test_all_plugins(topology_st.standalone)

+         acceptance_test.check_all_plugins(topology_m2)

  

          log.info('####################################################################')

          log.info('Successfully Tested Dynamic Plugins Functionality' + msg + '.')

          log.info('####################################################################\n')

  

+         if replication_run:

+             # We're done.

+             break

+         else:

+             log.info('Resume replication and run everything one more time')

+             topology_m2.resume_all_replicas()

+ 

+             replication_run = True

+             msg = ' (replication enabled)'

+             time.sleep(1)

+ 

+     ############################################################################

+     # Check replication, and data are in sync

+     ############################################################################

+     check_replicas(topology_m2)

+ 

+ 

+ def test_memory_corruption(topology_m2):

+     """Memory Corruption - Restart the plugins many times, and in different orders and test

+     functionality, and stability.  This will excerise the internal

+     plugin linked lists, dse callbacks, and task handlers.

+     """

+ 

+ 

+     m1 = topology_m2.ms["master1"]

+     msg = ' (no replication)'

+     replication_run = False

+ 

+     # First part of the test should be without replication

+     topology_m2.pause_all_replicas()

+ 

+     # First enable dynamic plugins

+     m1.config.replace('nsslapd-dynamic-plugins', 'on')

+ 

+     # Test that critical plugins can be updated even though the change might not be applied

+     ldbm_config = LDBMConfig(m1)

+     ldbm_config.replace('description', 'test')

+ 

+     while True:

+         # First run the tests with replication disabled, then rerun them with replication set up

+ 

          ############################################################################

          # Test the stability by exercising the internal lists, callabcks, and task handlers

          ############################################################################
@@ -113,24 +159,24 @@ 

          prev_plugin_test = None

          prev_prev_plugin_test = None

  

-         for plugin_test in plugin_tests.func_tests:

+         for plugin_test in acceptance_test.func_tests:

              #

              # Restart the plugin several times (and prev plugins) - work that linked list

              #

-             plugin_test(topology_st.standalone, "restart")

+             plugin_test(topology_m2, "restart")

  

              if prev_prev_plugin_test:

-                 prev_prev_plugin_test(topology_st.standalone, "restart")

+                 prev_prev_plugin_test(topology_m2, "restart")

  

-             plugin_test(topology_st.standalone, "restart")

+             plugin_test(topology_m2, "restart")

  

              if prev_plugin_test:

-                 prev_plugin_test(topology_st.standalone, "restart")

+                 prev_plugin_test(topology_m2, "restart")

  

-             plugin_test(topology_st.standalone, "restart")

+             plugin_test(topology_m2, "restart")

  

              # Now run the functional test

-             plugin_test(topology_st.standalone)

+             plugin_test(topology_m2, "dynamic")

  

              # Set the previous tests

              if prev_plugin_test:
@@ -141,17 +187,58 @@ 

          log.info('Successfully Tested Dynamic Plugins for Memory Corruption' + msg + '.')

          log.info('####################################################################\n')

  

-         ############################################################################

-         # Stress two plugins while restarting it, and while restarting other plugins.

-         # The goal is to not crash, and have the plugins work after stressing them.

-         ############################################################################

+         if replication_run:

+             # We're done.

+             break

+         else:

+             log.info('Resume replication and run everything one more time')

+             topology_m2.resume_all_replicas()

+ 

+             replication_run = True

+             msg = ' (replication enabled)'

+             time.sleep(1)

+ 

+     ############################################################################

+     # Check replication, and data are in sync

+     ############################################################################

+     check_replicas(topology_m2)

+ 

+ 

+ def test_stress(topology_m2):

+     """Test dynamic plugins got

+ 

+     Stress - Put the server under load that will trigger multiple plugins(MO, RI, DNA, etc)

+     Restart various plugins while these operations are going on.  Perform this test

+     5 times(stress_max_run).

+     """

+ 

+     m1 = topology_m2.ms["master1"]

+     msg = ' (no replication)'

+     replication_run = False

+     stress_max_runs = 5

+ 

+     # First part of the test should be without replication

+     topology_m2.pause_all_replicas()

+ 

+     # First enable dynamic plugins

+     m1.config.replace('nsslapd-dynamic-plugins', 'on')

+ 

+     # Test that critical plugins can be updated even though the change might not be applied

+     ldbm_config = LDBMConfig(m1)

+     ldbm_config.replace('description', 'test')

+ 

+     while True:

+         # First run the tests with replication disabled, then rerun them with replication set up

+ 

+         log.info('Do one run through all tests ' + msg + '...')

+         acceptance_test.check_all_plugins(topology_m2)

  

          log.info('####################################################################')

          log.info('Stressing Dynamic Plugins' + msg + '...')

          log.info('####################################################################\n')

  

-         stress_tests.configureMO(topology_st.standalone)

-         stress_tests.configureRI(topology_st.standalone)

+         stress_tests.configureMO(m1)

+         stress_tests.configureRI(m1)

  

          stress_count = 0

          while stress_count < stress_max_runs:
@@ -159,100 +246,94 @@ 

              log.info('Running stress test' + msg + '.  Run (%d/%d)...' % (stress_count + 1, stress_max_runs))

              log.info('####################################################################\n')

  

-             try:

-                 # Launch three new threads to add a bunch of users

-                 add_users = stress_tests.AddUsers(topology_st.standalone, 'employee', True)

-                 add_users.start()

-                 add_users2 = stress_tests.AddUsers(topology_st.standalone, 'entry', True)

-                 add_users2.start()

-                 add_users3 = stress_tests.AddUsers(topology_st.standalone, 'person', True)

-                 add_users3.start()

-                 time.sleep(1)

- 

-                 # While we are adding users restart the MO plugin and an idle plugin

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(2)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

- 

-                 # Wait for the 'adding' threads to complete

-                 add_users.join()

-                 add_users2.join()

-                 add_users3.join()

- 

-                 # Now launch three threads to delete the users

-                 del_users = stress_tests.DelUsers(topology_st.standalone, 'employee')

-                 del_users.start()

-                 del_users2 = stress_tests.DelUsers(topology_st.standalone, 'entry')

-                 del_users2.start()

-                 del_users3 = stress_tests.DelUsers(topology_st.standalone, 'person')

-                 del_users3.start()

-                 time.sleep(1)

- 

-                 # Restart both the MO, RI plugins during these deletes, and an idle plugin

-                 topology_st.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

-                 time.sleep(2)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)

-                 time.sleep(1)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

-                 topology_st.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)

-                 topology_st.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)

- 

-                 # Wait for the 'deleting' threads to complete

-                 del_users.join()

-                 del_users2.join()

-                 del_users3.join()

- 

-                 # Now make sure both the MO and RI plugins still work correctly

-                 plugin_tests.func_tests[8](topology_st.standalone)  # RI plugin

-                 plugin_tests.func_tests[5](topology_st.standalone)  # MO plugin

- 

-                 # Cleanup the stress tests

-                 stress_tests.cleanup(topology_st.standalone)

- 

-             except:

-                 log.info('Stress test failed!')

-                 if replication_run:

-                     repl_fail(replica_inst)

+             # Launch three new threads to add a bunch of users

+             add_users = stress_tests.AddUsers(m1, 'employee', True)

+             add_users.start()

+             add_users2 = stress_tests.AddUsers(m1, 'entry', True)

+             add_users2.start()

+             add_users3 = stress_tests.AddUsers(m1, 'person', True)

+             add_users3.start()

+             time.sleep(1)

+ 

+             # While we are adding users restart the MO plugin and an idle plugin

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.disable(name=PLUGIN_LINKED_ATTRS)

+             m1.plugins.enable(name=PLUGIN_LINKED_ATTRS)

+             time.sleep(1)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             time.sleep(2)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.disable(name=PLUGIN_LINKED_ATTRS)

+             m1.plugins.enable(name=PLUGIN_LINKED_ATTRS)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+ 

+             # Wait for the 'adding' threads to complete

+             add_users.join()

+             add_users2.join()

+             add_users3.join()

+ 

+             # Now launch three threads to delete the users

+             del_users = stress_tests.DelUsers(m1, 'employee')

+             del_users.start()

+             del_users2 = stress_tests.DelUsers(m1, 'entry')

+             del_users2.start()

+             del_users3 = stress_tests.DelUsers(m1, 'person')

+             del_users3.start()

+             time.sleep(1)

+ 

+             # Restart both the MO, RI plugins during these deletes, and an idle plugin

+             m1.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

+             time.sleep(1)

+             m1.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

+             time.sleep(1)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

+             m1.plugins.disable(name=PLUGIN_LINKED_ATTRS)

+             m1.plugins.enable(name=PLUGIN_LINKED_ATTRS)

+             m1.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             m1.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

+             time.sleep(2)

+             m1.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

+             time.sleep(1)

+             m1.plugins.disable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_MEMBER_OF)

+             time.sleep(1)

+             m1.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

+             m1.plugins.disable(name=PLUGIN_LINKED_ATTRS)

+             m1.plugins.enable(name=PLUGIN_LINKED_ATTRS)

+ 

+             # Wait for the 'deleting' threads to complete

+             del_users.join()

+             del_users2.join()

+             del_users3.join()

+ 

+             # Now make sure both the MO and RI plugins still work correctly

+             acceptance_test.func_tests[8](topology_m2, "dynamic")  # RI plugin

+             acceptance_test.func_tests[5](topology_m2, "dynamic")  # MO plugin

+ 

+             # Cleanup the stress tests

+             stress_tests.cleanup(m1)

  

              stress_count += 1

              log.info('####################################################################')
@@ -264,166 +345,17 @@ 

              # We're done.

              break

          else:

-             #

-             # Enable replication and run everything one more time

-             #

-             log.info('Setting up replication, and rerunning the tests...\n')

- 

-             # Create replica instance

-             replica_inst = DirSrv(verbose=False)

-             args_instance[SER_HOST] = LOCALHOST

-             args_instance[SER_PORT] = REPLICA_PORT

-             args_instance[SER_SERVERID_PROP] = 'replica'

-             args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX

- 

-             args_replica_inst = args_instance.copy()

-             replica_inst.allocate(args_replica_inst)

-             replica_inst.create()

-             replica_inst.open()

- 

-             try:

-                 topology_st.standalone.replica.enableReplication(suffix=DEFAULT_SUFFIX,

-                                                                  role=ReplicaRole.MASTER,

-                                                                  replicaId=1)

-                 replica_inst.replica.enableReplication(suffix=DEFAULT_SUFFIX,

-                                                        role=ReplicaRole.CONSUMER,

-                                                        replicaId=65535)

-                 properties = {RA_NAME: r'to_replica',

-                               RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],

-                               RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],

-                               RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],

-                               RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}

-                 repl_agreement = topology_st.standalone.agreement.create(suffix=DEFAULT_SUFFIX,

-                                                                          host=LOCALHOST,

-                                                                          port=REPLICA_PORT,

-                                                                          properties=properties)

- 

-                 if not repl_agreement:

-                     log.fatal("Fail to create a replica agreement")

-                     repl_fail(replica_inst)

-                 topology_st.standalone.agreement.init(DEFAULT_SUFFIX, LOCALHOST, REPLICA_PORT)

-                 topology_st.standalone.waitForReplInit(repl_agreement)

-             except:

-                 log.info('Failed to setup replication!')

-                 repl_fail(replica_inst)

+             log.info('Resume replication and run everything one more time')

+             topology_m2.resume_all_replicas()

  

              replication_run = True

              msg = ' (replication enabled)'

              time.sleep(1)

  

      ############################################################################

-     # Check replication, and data are in sync, and remove the instance

-     ############################################################################

- 

-     log.info('Checking if replication is in sync...')

- 

-     try:

-         # Grab master's max CSN

-         entry = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, RUV_FILTER)

-         if not entry:

-             log.error('Failed to find db tombstone entry from master')

-             repl_fail(replica_inst)

-         elements = entry[0].getValues('nsds50ruv')

-         for ruv in elements:

-             if 'replica 1' in ruv:

-                 parts = ruv.split()

-                 if len(parts) == 5:

-                     master_maxcsn = parts[4]

-                     break

-                 else:

-                     log.error('RUV is incomplete')

-                     repl_fail(replica_inst)

-         if master_maxcsn == 0:

-             log.error('Failed to find maxcsn on master')

-             repl_fail(replica_inst)

- 

-     except ldap.LDAPError as e:

-         log.fatal('Unable to search masterfor db tombstone: ' + e.message['desc'])

-         repl_fail(replica_inst)

- 

-     # Loop on the consumer - waiting for it to catch up

-     count = 0

-     insync = False

-     while count < 60:

-         try:

-             # Grab master's max CSN

-             entry = replica_inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, RUV_FILTER)

-             if not entry:

-                 log.error('Failed to find db tombstone entry on consumer')

-                 repl_fail(replica_inst)

-             elements = entry[0].getValues('nsds50ruv')

-             for ruv in elements:

-                 if 'replica 1' in ruv:

-                     parts = ruv.split()

-                     if len(parts) == 5:

-                         replica_maxcsn = parts[4]

-                         break

-             if replica_maxcsn == 0:

-                 log.error('Failed to find maxcsn on consumer')

-                 repl_fail(replica_inst)

-         except ldap.LDAPError as e:

-             log.fatal('Unable to search for db tombstone on consumer: ' + e.message['desc'])

-             repl_fail(replica_inst)

- 

-         if master_maxcsn == replica_maxcsn:

-             insync = True

-             log.info('Replication is in sync.\n')

-             break

-         count += 1

-         time.sleep(1)

- 

-     # Report on replication status

-     if not insync:

-         log.error('Consumer not in sync with master!')

-         repl_fail(replica_inst)

- 

-     #

-     # Verify the databases are identical. There should not be any "user, entry, employee" entries

-     #

-     log.info('Checking if the data is the same between the replicas...')

- 

-     # Check the master

-     try:

-         entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,

-                                                   ldap.SCOPE_SUBTREE,

-                                                   "(|(uid=person*)(uid=entry*)(uid=employee*))")

-         if len(entries) > 0:

-             log.error('Master database has incorrect data set!\n')

-             repl_fail(replica_inst)

-     except ldap.LDAPError as e:

-         log.fatal('Unable to search db on master: ' + e.message['desc'])

-         repl_fail(replica_inst)

- 

-     # Check the consumer

-     try:

-         entries = replica_inst.search_s(DEFAULT_SUFFIX,

-                                         ldap.SCOPE_SUBTREE,

-                                         "(|(uid=person*)(uid=entry*)(uid=employee*))")

-         if len(entries) > 0:

-             log.error('Consumer database in not consistent with master database')

-             repl_fail(replica_inst)

-     except ldap.LDAPError as e:

-         log.fatal('Unable to search db on consumer: ' + e.message['desc'])

-         repl_fail(replica_inst)

- 

-     log.info('Data is consistent across the replicas.\n')

- 

-     log.info('####################################################################')

-     log.info('Replication consistency test passed')

-     log.info('####################################################################\n')

- 

-     # Remove the replica instance

-     replica_inst.delete()

- 

-     ############################################################################

-     # We made it to the end!

+     # Check replication, and data are in sync

      ############################################################################

- 

-     log.info('#####################################################')

-     log.info('#####################################################')

-     log.info("Dynamic Plugins Testsuite: Completed Successfully!")

-     log.info('#####################################################')

-     log.info('#####################################################\n')

+     check_replicas(topology_m2)

  

  

  if __name__ == '__main__':

@@ -1,2485 +0,0 @@ 

- # --- BEGIN COPYRIGHT BLOCK ---

- # Copyright (C) 2016 Red Hat, Inc.

- # All rights reserved.

- #

- # License: GPL (version 3 or any later version).

- # See LICENSE for details.

- # --- END COPYRIGHT BLOCK ---

- #

- '''

- Created on Dec 09, 2014

- 

- @author: mreynolds

- '''

- import logging

- from lib389 import DirSrv

- from lib389.tasks import *

- from lib389.properties import *

- from lib389._constants import (DEFAULT_SUFFIX, PLUGIN_ACCT_USABILITY, PLUGIN_ACCT_POLICY,

-                               PLUGIN_ATTR_UNIQUENESS, PLUGIN_AUTOMEMBER, PLUGIN_DNA,

-                               PLUGIN_LINKED_ATTRS, PLUGIN_MEMBER_OF, DN_CONFIG,

-                               PLUGIN_MANAGED_ENTRY, PLUGIN_PASSTHRU, PLUGIN_REFER_INTEGRITY,

-                               PLUGIN_RETRO_CHANGELOG, PLUGIN_ROOTDN_ACCESS, DN_DM, PASSWORD,

-                               LOCALHOST, RETROCL_SUFFIX, args_instance)

- 

- log = logging.getLogger(__name__)

- 

- USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX

- USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX

- USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX

- BUSER1_DN = 'uid=user1,ou=branch1,' + DEFAULT_SUFFIX

- BUSER2_DN = 'uid=user2,ou=branch2,' + DEFAULT_SUFFIX

- BUSER3_DN = 'uid=user3,ou=branch2,' + DEFAULT_SUFFIX

- BRANCH1_DN = 'ou=branch1,' + DEFAULT_SUFFIX

- BRANCH2_DN = 'ou=branch2,' + DEFAULT_SUFFIX

- GROUP_OU = 'ou=groups,' + DEFAULT_SUFFIX

- PEOPLE_OU = 'ou=people,' + DEFAULT_SUFFIX

- GROUP_DN = 'cn=group,' + DEFAULT_SUFFIX

- CONFIG_AREA = 'nsslapd-pluginConfigArea'

- 

- '''

-    Functional tests for each plugin

- 

-    Test:

-          plugin restarts (test when on and off)

-          plugin config validation

-          plugin dependencies

-          plugin functionality (including plugin tasks)

- '''

- 

- 

- ################################################################################

- #

- # Test Plugin Dependency

- #

- ################################################################################

- def test_dependency(inst, plugin):

-     """

-     Set the "account usabilty" plugin to depend on this plugin.  This plugin

-     is generic, always enabled, and perfect for our testing

-     """

- 

-     try:

-         inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',

-                       [(ldap.MOD_REPLACE, 'nsslapd-plugin-depends-on-named', plugin)])

- 

-     except ldap.LDAPError as e:

-         log.fatal('test_dependency: Failed to modify ' + PLUGIN_ACCT_USABILITY + ': error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.modify_s('cn=' + plugin + ',cn=plugins,cn=config',

-                       [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'off')])

- 

-     except ldap.UNWILLING_TO_PERFORM:

-         # failed as expected

-         pass

-     else:

-         # Incorrectly succeeded

-         log.fatal('test_dependency: Plugin dependency check failed (%s)' % plugin)

-         assert False

- 

-     # Now undo the change

-     try:

-         inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',

-                       [(ldap.MOD_DELETE, 'nsslapd-plugin-depends-on-named', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_dependency: Failed to reset ' + plugin + ': error ' + e.message['desc'])

-         assert False

- 

- 

- ################################################################################

- #

- # Wait for task to complete

- #

- ################################################################################

- def wait_for_task(conn, task_dn):

-     finished = False

-     exitcode = 0

-     count = 0

-     while count < 60:

-         try:

-             task_entry = conn.search_s(task_dn, ldap.SCOPE_BASE, 'objectclass=*')

-             if not task_entry:

-                 log.fatal('wait_for_task: Search failed to find task: ' + task_dn)

-                 assert False

-             if task_entry[0].hasAttr('nstaskexitcode'):

-                 # task is done

-                 exitcode = task_entry[0].nsTaskExitCode

-                 finished = True

-                 break

-         except ldap.LDAPError as e:

-             log.fatal('wait_for_task: Search failed: ' + e.message['desc'])

-             assert False

- 

-         time.sleep(1)

-         count += 1

-     if not finished:

-         log.fatal('wait_for_task: Task (%s) did not complete!' % task_dn)

-         assert False

- 

-     return exitcode

- 

- 

- ################################################################################

- #

- # Test Account Policy Plugin (0)

- #

- ################################################################################

- def test_acctpolicy(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_ACCT_POLICY)

-     inst.plugins.enable(name=PLUGIN_ACCT_POLICY)

- 

-     if args == "restart":

-         return True

- 

-     CONFIG_DN = 'cn=config,cn=Account Policy Plugin,cn=plugins,cn=config'

- 

-     log.info('Testing ' + PLUGIN_ACCT_POLICY + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     # Add the config entry

-     try:

-         inst.add_s(Entry((CONFIG_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'cn': 'config',

-             'alwaysrecordlogin': 'yes',

-             'stateattrname': 'lastLoginTime'

-         })))

-     except ldap.ALREADY_EXISTS:

-         try:

-             inst.modify_s(CONFIG_DN,

-                           [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),

-                            (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime')])

-         except ldap.LDAPError as e:

-             log.fatal('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to add config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add an entry

-     time.sleep(1)

-     try:

-         inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '1',

-                                      'cn': 'user 1',

-                                      'uid': 'user1',

-                                      'userpassword': 'password'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])

-         assert False

- 

-     # bind as user

-     try:

-         inst.simple_bind_s(USER1_DN, "password")

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to bind as user1: ' + e.message['desc'])

-         assert False

- 

-     # Bind as Root DN

-     time.sleep(1)

-     try:

-         inst.simple_bind_s(DN_DM, PASSWORD)

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])

-         assert False

- 

-     # Check lastLoginTime of USER1

-     try:

-         entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'lastLoginTime=*')

-         if not entries:

-             log.fatal('test_acctpolicy: Search failed to find an entry with lastLoginTime.')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change config - change the stateAttrName to a new attribute

-     ############################################################################

- 

-     try:

-         inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'stateattrname', 'testLastLoginTime')])

- 

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     time.sleep(1)

-     # login as user

-     try:

-         inst.simple_bind_s(USER1_DN, "password")

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to bind(2nd) as user1: ' + e.message['desc'])

-         assert False

- 

-     time.sleep(1)

-     # Bind as Root DN

-     try:

-         inst.simple_bind_s(DN_DM, PASSWORD)

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])

-         assert False

- 

-     # Check testLastLoginTime was added to USER1

-     try:

-         entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(testLastLoginTime=*)')

-         if not entries:

-             log.fatal('test_acctpolicy: Search failed to find an entry with testLastLoginTime.')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_ACCT_POLICY)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_acctpolicy: Failed to delete test entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_acctpolicy: PASS\n')

- 

-     return

- 

- 

- ################################################################################

- #

- # Test Attribute Uniqueness Plugin (1)

- #

- ################################################################################

- def test_attruniq(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_ATTR_UNIQUENESS)

-     inst.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS)

- 

-     if args == "restart":

-         return

- 

-     log.info('Testing ' + PLUGIN_ATTR_UNIQUENESS + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',

-                       [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'uid')])

- 

-     except ldap.LDAPError as e:

-         log.fatal('test_attruniq: Failed to configure plugin for "uid": error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add an entry

-     try:

-         inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '1',

-                                      'cn': 'user 1',

-                                      'uid': 'user1',

-                                      'mail': 'user1@example.com',

-                                      'mailAlternateAddress': 'user1@alt.example.com',

-                                      'userpassword': 'password'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_attruniq: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])

-         assert False

- 

-     # Add an entry with a duplicate "uid"

-     try:

-         inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '2',

-                                      'cn': 'user 2',

-                                      'uid': 'user2',

-                                      'uid': 'user1',

-                                      'userpassword': 'password'})))

- 

-     except ldap.CONSTRAINT_VIOLATION:

-         pass

-     else:

-         log.fatal('test_attruniq: Adding of 2nd entry(uid) incorrectly succeeded')

-         assert False

- 

-     ############################################################################

-     # Change config to use "mail" instead of "uid"

-     ############################################################################

- 

-     try:

-         inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',

-                       [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail')])

- 

-     except ldap.LDAPError as e:

-         log.fatal('test_attruniq: Failed to configure plugin for "mail": error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin - Add an entry, that has a duplicate "mail" value

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '2',

-                                      'cn': 'user 2',

-                                      'uid': 'user2',

-                                      'mail': 'user1@example.com',

-                                      'userpassword': 'password'})))

-     except ldap.CONSTRAINT_VIOLATION:

-         pass

-     else:

-         log.fatal('test_attruniq: Adding of 2nd entry(mail) incorrectly succeeded')

-         assert False

- 

-     ############################################################################

-     # Reconfigure plugin for mail and mailAlternateAddress

-     ############################################################################

- 

-     try:

-         inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',

-                       [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail'),

-                        (ldap.MOD_ADD, 'uniqueness-attribute-name',

-                         'mailAlternateAddress')])

- 

-     except ldap.LDAPError as e:

-         log.error(

-             'test_attruniq: Failed to reconfigure plugin for "mail mailAlternateAddress": error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin - Add an entry, that has a duplicate "mail" value

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '2',

-                                      'cn': 'user 2',

-                                      'uid': 'user2',

-                                      'mail': 'user1@example.com',

-                                      'userpassword': 'password'})))

-     except ldap.CONSTRAINT_VIOLATION:

-         pass

-     else:

-         log.error('test_attruniq: Adding of 3rd entry(mail) incorrectly succeeded')

-         assert False

- 

-     ############################################################################

-     # Test plugin - Add an entry, that has a duplicate "mailAlternateAddress" value

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '2',

-                                      'cn': 'user 2',

-                                      'uid': 'user2',

-                                      'mailAlternateAddress': 'user1@alt.example.com',

-                                      'userpassword': 'password'})))

-     except ldap.CONSTRAINT_VIOLATION:

-         pass

-     else:

-         log.error('test_attruniq: Adding of 4th entry(mailAlternateAddress) incorrectly succeeded')

-         assert False

- 

-     ############################################################################

-     # Test plugin - Add an entry, that has a duplicate "mail" value conflicting mailAlternateAddress

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '2',

-                                      'cn': 'user 2',

-                                      'uid': 'user2',

-                                      'mail': 'user1@alt.example.com',

-                                      'userpassword': 'password'})))

-     except ldap.CONSTRAINT_VIOLATION:

-         pass

-     else:

-         log.error('test_attruniq: Adding of 5th entry(mailAlternateAddress) incorrectly succeeded')

-         assert False

- 

-     ############################################################################

-     # Test plugin - Add an entry, that has a duplicate "mailAlternateAddress" conflicting mail

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),

-                                      'sn': '2',

-                                      'cn': 'user 2',

-                                      'uid': 'user2',

-                                      'mailAlternateAddress': 'user1@example.com',

-                                      'userpassword': 'password'})))

-     except ldap.CONSTRAINT_VIOLATION:

-         pass

-     else:

-         log.error('test_attruniq: Adding of 6th entry(mail) incorrectly succeeded')

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_ATTR_UNIQUENESS)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_attruniq: Failed to delete test entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_attruniq: PASS\n')

-     return

- 

- 

- ################################################################################

- #

- # Test Auto Membership Plugin (2)

- #

- ################################################################################

- def test_automember(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_AUTOMEMBER)

-     inst.plugins.enable(name=PLUGIN_AUTOMEMBER)

- 

-     if args == "restart":

-         return

- 

-     CONFIG_DN = 'cn=config,cn=' + PLUGIN_AUTOMEMBER + ',cn=plugins,cn=config'

- 

-     log.info('Testing ' + PLUGIN_AUTOMEMBER + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     # Add the automember group

-     try:

-         inst.add_s(Entry((GROUP_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'cn': 'group'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to add group: error ' + e.message['desc'])

-         assert False

- 

-     # Add ou=branch1

-     try:

-         inst.add_s(Entry((BRANCH1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'ou': 'branch1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to add branch1: error ' + e.message['desc'])

-         assert False

- 

-     # Add ou=branch2

-     try:

-         inst.add_s(Entry((BRANCH2_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'ou': 'branch2'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to add branch2: error ' + e.message['desc'])

-         assert False

- 

-     # Add the automember config entry

-     try:

-         inst.add_s(Entry((CONFIG_DN, {

-             'objectclass': 'top autoMemberDefinition'.split(),

-             'cn': 'config',

-             'autoMemberScope': 'ou=branch1,' + DEFAULT_SUFFIX,

-             'autoMemberFilter': 'objectclass=top',

-             'autoMemberDefaultGroup': 'cn=group,' + DEFAULT_SUFFIX,

-             'autoMemberGroupingAttr': 'member:dn'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to add config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test the plugin

-     ############################################################################

- 

-     # Add a user that should get added to the group

-     try:

-         inst.add_s(Entry((BUSER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to add user: error ' + e.message['desc'])

-         assert False

- 

-     # Check the group

-     try:

-         entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,

-                                 '(member=' + BUSER1_DN + ')')

-         if not entries:

-             log.fatal('test_automember: Search failed to find member user1')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Search failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change config

-     ############################################################################

- 

-     try:

-         inst.modify_s(CONFIG_DN,

-                       [(ldap.MOD_REPLACE, 'autoMemberGroupingAttr', 'uniquemember:dn'),

-                        (ldap.MOD_REPLACE, 'autoMemberScope', 'ou=branch2,' + DEFAULT_SUFFIX)])

- 

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to modify config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add a user that should get added to the group

-     try:

-         inst.add_s(Entry((BUSER2_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user2'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to user to branch2: error ' + e.message['desc'])

-         assert False

- 

-     # Check the group

-     try:

-         entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,

-                                 '(uniquemember=' + BUSER2_DN + ')')

-         if not entries:

-             log.fatal('test_automember: Search failed to find uniquemember user2')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Search failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test Task

-     ############################################################################

- 

-     # Disable plugin

-     inst.plugins.disable(name=PLUGIN_AUTOMEMBER)

- 

-     # Add an entry that should be picked up by automember - verify it is not(yet)

-     try:

-         inst.add_s(Entry((BUSER3_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user3'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to user3 to branch2: error ' + e.message['desc'])

-         assert False

- 

-     # Check the group - uniquemember should not exist

-     try:

-         entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,

-                                 '(uniquemember=' + BUSER3_DN + ')')

-         if entries:

-             log.fatal('test_automember: user3 was incorrectly added to the group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Search failed: ' + e.message['desc'])

-         assert False

- 

-     # Enable plugin

-     inst.plugins.enable(name=PLUGIN_AUTOMEMBER)

- 

-     TASK_DN = 'cn=task-' + str(int(time.time())) + ',cn=automember rebuild membership,cn=tasks,cn=config'

-     # Add the task

-     try:

-         inst.add_s(Entry((TASK_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'basedn': 'ou=branch2,' + DEFAULT_SUFFIX,

-             'filter': 'objectclass=top'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to add task: error ' + e.message['desc'])

-         assert False

- 

-     wait_for_task(inst, TASK_DN)

- 

-     # Verify the fixup task worked

-     try:

-         entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,

-                                 '(uniquemember=' + BUSER3_DN + ')')

-         if not entries:

-             log.fatal('test_automember: user3 was not added to the group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Search failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_AUTOMEMBER)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(BUSER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete test entry1: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(BUSER2_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete test entry2: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(BUSER3_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete test entry3: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(BRANCH1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete branch1: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(BRANCH2_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete test branch2: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(GROUP_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete test group: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(CONFIG_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_automember: Failed to delete plugin config entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_automember: PASS\n')

-     return

- 

- 

- ################################################################################

- #

- # Test DNA Plugin (3)

- #

- ################################################################################

- def test_dna(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_DNA)

-     inst.plugins.enable(name=PLUGIN_DNA)

- 

-     if args == "restart":

-         return

- 

-     CONFIG_DN = 'cn=config,cn=' + PLUGIN_DNA + ',cn=plugins,cn=config'

- 

-     log.info('Testing ' + PLUGIN_DNA + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((CONFIG_DN, {

-             'objectclass': 'top dnaPluginConfig'.split(),

-             'cn': 'config',

-             'dnatype': 'uidNumber',

-             'dnafilter': '(objectclass=top)',

-             'dnascope': DEFAULT_SUFFIX,

-             'dnaMagicRegen': '-1',

-             'dnaMaxValue': '50000',

-             'dnaNextValue': '1'

-         })))

-     except ldap.ALREADY_EXISTS:

-         try:

-             inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaNextValue', '1'),

-                                       (ldap.MOD_REPLACE, 'dnaMagicRegen', '-1')])

-         except ldap.LDAPError as e:

-             log.fatal('test_dna: Failed to set the DNA plugin: error ' + e.message['desc'])

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Failed to add config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Failed to user1: error ' + e.message['desc'])

-         assert False

- 

-     # See if the entry now has the new uidNumber assignment - uidNumber=1

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=1)')

-         if not entries:

-             log.fatal('test_dna: user1 was not updated - (looking for uidNumber: 1)')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Test the magic regen value

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-1')])

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])

-         assert False

- 

-     # See if the entry now has the new uidNumber assignment - uidNumber=2

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=2)')

-         if not entries:

-             log.fatal('test_dna: user1 was not updated (looking for uidNumber: 2)')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ################################################################################

-     # Change the config

-     ################################################################################

- 

-     try:

-         inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaMagicRegen', '-2')])

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Failed to set the magic reg value to -2: error ' + e.message['desc'])

-         assert False

- 

-     ################################################################################

-     # Test plugin

-     ################################################################################

- 

-     # Test the magic regen value

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-2')])

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])

-         assert False

- 

-     # See if the entry now has the new uidNumber assignment - uidNumber=3

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=3)')

-         if not entries:

-             log.fatal('test_dna: user1 was not updated (looking for uidNumber: 3)')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_AUTOMEMBER)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_dna: Failed to delete test entry1: ' + e.message['desc'])

-         assert False

- 

-     inst.plugins.disable(name=PLUGIN_DNA)

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_dna: PASS\n')

- 

-     return

- 

- 

- ################################################################################

- #

- # Test Linked Attrs Plugin (4)

- #

- ################################################################################

- def test_linkedattrs(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)

-     inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)

- 

-     if args == "restart":

-         return

- 

-     CONFIG_DN = 'cn=config,cn=' + PLUGIN_LINKED_ATTRS + ',cn=plugins,cn=config'

- 

-     log.info('Testing ' + PLUGIN_LINKED_ATTRS + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     # Add test entries

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to user1: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user2'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to user1: error ' + e.message['desc'])

-         assert False

- 

-     # Add the linked attrs config entry

-     try:

-         inst.add_s(Entry((CONFIG_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'cn': 'config',

-             'linkType': 'directReport',

-             'managedType': 'manager'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to add config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Set "directReport" should add "manager" to the other entry

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])

-         assert False

- 

-     # See if manager was added to the other entry

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if not entries:

-             log.fatal('test_linkedattrs: user2 missing "manager" attribute')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "directReport" should remove "manager" to the other entry

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'directReport', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])

-         assert False

- 

-     # See if manager was removed

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if entries:

-             log.fatal('test_linkedattrs: user2 "manager" attribute not removed')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change the config - using linkType "indirectReport" now

-     ############################################################################

- 

-     try:

-         inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'linkType', 'indirectReport')])

-     except ldap.LDAPError as e:

-         log.error('test_linkedattrs: Failed to set linkTypee: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Make sure the old linkType(directManager) is not working

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])

-         assert False

- 

-     # See if manager was added to the other entry, better not be...

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if entries:

-             log.fatal('test_linkedattrs: user2 had "manager" added unexpectedly')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])

-         assert False

- 

-     # Now, set the new linkType "indirectReport", which should add "manager" to the other entry

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])

-         assert False

- 

-     # See if manager was added to the other entry, better not be

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if not entries:

-             log.fatal('test_linkedattrs: user2 missing "manager"')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "indirectReport" should remove "manager" to the other entry

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'indirectReport', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])

-         assert False

- 

-     # See if manager was removed

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if entries:

-             log.fatal('test_linkedattrs: user2 "manager" attribute not removed')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test Fixup Task

-     ############################################################################

- 

-     # Disable plugin and make some updates that would of triggered the plugin

-     inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)

- 

-     try:

-         inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])

-         assert False

- 

-     # The entry should not have a manager attribute

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if entries:

-             log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Enable the plugin and rerun the task entry

-     inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)

- 

-     # Add the task again

-     TASK_DN = 'cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config'

-     try:

-         inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {

-             'objectclass': 'top extensibleObject'.split(),

-             'basedn': DEFAULT_SUFFIX,

-             'filter': 'objectclass=top'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to add task: error ' + e.message['desc'])

-         assert False

- 

-     wait_for_task(inst, TASK_DN)

- 

-     # Check if user2 now has a manager attribute now

-     try:

-         entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')

-         if not entries:

-             log.fatal('test_linkedattrs: task failed: user2 missing "manager" attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_LINKED_ATTRS)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to delete test entry1: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(USER2_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to delete test entry2: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(CONFIG_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_linkedattrs: Failed to delete plugin config entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_linkedattrs: PASS\n')

-     return

- 

- 

- ################################################################################

- #

- # Test MemberOf Plugin (5)

- #

- ################################################################################

- def test_memberof(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_MEMBER_OF)

-     inst.plugins.enable(name=PLUGIN_MEMBER_OF)

- 

-     if args == "restart":

-         return

- 

-     PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'

-     SHARED_CONFIG_DN = 'cn=memberOf Config,' + DEFAULT_SUFFIX

- 

-     log.info('Testing ' + PLUGIN_MEMBER_OF + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to update config(member): error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add our test entries

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((GROUP_DN, {

-             'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),

-             'cn': 'group',

-             'member': USER1_DN

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add group: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((SHARED_CONFIG_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'memberofgroupattr': 'member',

-             'memberofattr': 'memberof'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to shared config entry: error ' + e.message['desc'])

-         assert False

- 

-     # Check if the user now has a "memberOf" attribute

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if not entries:

-             log.fatal('test_memberof: user1 missing memberOf')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "member" should remove "memberOf" from the entry

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete member: error ' + e.message['desc'])

-         assert False

- 

-     # Check that "memberOf" was removed

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if entries:

-             log.fatal('test_memberof: user1 incorrectly has memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change the config

-     ############################################################################

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     # Check if the user now has a "memberOf" attribute

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if not entries:

-             log.fatal('test_memberof: user1 missing memberOf')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "uniquemember" should remove "memberOf" from the entry

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'uniquemember', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete member: error ' + e.message['desc'])

-         assert False

- 

-     # Check that "memberOf" was removed

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if entries:

-             log.fatal('test_memberof: user1 incorrectly has memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Set the shared config entry and test the plugin

-     ############################################################################

- 

-     # The shared config entry uses "member" - the above test uses "uniquemember"

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, CONFIG_AREA, SHARED_CONFIG_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to set plugin area: error ' + e.message['desc'])

-         assert False

- 

-     # Delete the test entries then readd them to start with a clean slate

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete test entry1: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(GROUP_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete test group: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((GROUP_DN, {

-             'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),

-             'cn': 'group',

-             'member': USER1_DN

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add group: error ' + e.message['desc'])

-         assert False

- 

-     # Test the shared config

-     # Check if the user now has a "memberOf" attribute

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if not entries:

-             log.fatal('test_memberof: user1 missing memberOf')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "member" should remove "memberOf" from the entry

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete member: error ' + e.message['desc'])

-         assert False

- 

-     # Check that "memberOf" was removed

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if entries:

-             log.fatal('test_memberof: user1 incorrectly has memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change the shared config entry to use 'uniquemember' and test the plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s(SHARED_CONFIG_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to set shared plugin entry(uniquemember): error '

-                   + e.message['desc'])

-         assert False

- 

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     # Check if the user now has a "memberOf" attribute

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if not entries:

-             log.fatal('test_memberof: user1 missing memberOf')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "uniquemember" should remove "memberOf" from the entry

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'uniquemember', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete member: error ' + e.message['desc'])

-         assert False

- 

-     # Check that "memberOf" was removed

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if entries:

-             log.fatal('test_memberof: user1 incorrectly has memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Remove shared config from plugin, and retest

-     ############################################################################

- 

-     # First change the plugin to use member before we move the shared config that uses uniquemember

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc'])

-         assert False

- 

-     # Remove shared config from plugin

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, CONFIG_AREA, None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'member', USER1_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     # Check if the user now has a "memberOf" attribute

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if not entries:

-             log.fatal('test_memberof: user1 missing memberOf')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Remove "uniquemember" should remove "memberOf" from the entry

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete member: error ' + e.message['desc'])

-         assert False

- 

-     # Check that "memberOf" was removed

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if entries:

-             log.fatal('test_memberof: user1 incorrectly has memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test Fixup Task

-     ############################################################################

- 

-     inst.plugins.disable(name=PLUGIN_MEMBER_OF)

- 

-     # First change the plugin to use uniquemember

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc'])

-         assert False

- 

-     # Add uniquemember, should not update USER1

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     # Check for "memberOf"

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if entries:

-             log.fatal('test_memberof: user1 incorrect has memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     # Enable memberof plugin

-     inst.plugins.enable(name=PLUGIN_MEMBER_OF)

- 

-     #############################################################

-     # Test memberOf fixup arg validation:  Test the DN and filter

-     #############################################################

- 

-     #

-     # Test bad/nonexistant DN

-     #

-     TASK_DN = 'cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK

-     try:

-         inst.add_s(Entry((TASK_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'basedn': DEFAULT_SUFFIX + "bad",

-             'filter': 'objectclass=top'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add task(bad dn): error ' +

-                   e.message['desc'])

-         assert False

- 

-     exitcode = wait_for_task(inst, TASK_DN)

-     if exitcode == "0":

-         # We should an error

-         log.fatal('test_memberof: Task with invalid DN still reported success')

-         assert False

- 

-     #

-     # Test invalid DN syntax

-     #

-     TASK_DN = 'cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK

-     try:

-         inst.add_s(Entry((TASK_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'basedn': "bad",

-             'filter': 'objectclass=top'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add task(invalid dn syntax): ' +

-                   e.message['desc'])

-         assert False

- 

-     exitcode = wait_for_task(inst, TASK_DN)

-     if exitcode == "0":

-         # We should an error

-         log.fatal('test_memberof: Task with invalid DN syntax still reported' +

-                   ' success')

-         assert False

- 

-     #

-     # Test bad filter (missing closing parenthesis)

-     #

-     TASK_DN = 'cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK

-     try:

-         inst.add_s(Entry((TASK_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'basedn': DEFAULT_SUFFIX,

-             'filter': '(objectclass=top'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add task(bad filter: error ' +

-                   e.message['desc'])

-         assert False

- 

-     exitcode = wait_for_task(inst, TASK_DN)

-     if exitcode == "0":

-         # We should an error

-         log.fatal('test_memberof: Task with invalid filter still reported ' +

-                   'success')

-         assert False

- 

-     ####################################################

-     # Test fixup works

-     ####################################################

- 

-     #

-     # Run the task and validate that it worked

-     #

-     TASK_DN = 'cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK

-     try:

-         inst.add_s(Entry((TASK_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'basedn': DEFAULT_SUFFIX,

-             'filter': 'objectclass=top'})))

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to add task: error ' + e.message['desc'])

-         assert False

- 

-     wait_for_task(inst, TASK_DN)

- 

-     # Check for "memberOf"

-     try:

-         entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')

-         if not entries:

-             log.fatal('test_memberof: user1 missing memberOf attr')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_MEMBER_OF)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete test entry1: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(GROUP_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete test group: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(SHARED_CONFIG_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_memberof: Failed to delete shared config entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_memberof: PASS\n')

- 

-     return

- 

- 

- ################################################################################

- #

- # Test Managed Entry Plugin (6)

- #

- ################################################################################

- def test_mep(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)

-     inst.plugins.enable(name=PLUGIN_MANAGED_ENTRY)

- 

-     if args == "restart":

-         return

- 

-     USER_DN = 'uid=user1,ou=people,' + DEFAULT_SUFFIX

-     MEP_USER_DN = 'cn=user1,ou=groups,' + DEFAULT_SUFFIX

-     USER_DN2 = 'uid=user 1,ou=people,' + DEFAULT_SUFFIX

-     MEP_USER_DN2 = 'uid=user 1,ou=groups,' + DEFAULT_SUFFIX

-     CONFIG_DN = 'cn=config,cn=' + PLUGIN_MANAGED_ENTRY + ',cn=plugins,cn=config'

-     TEMPLATE_DN = 'cn=MEP Template,' + DEFAULT_SUFFIX

-     TEMPLATE_DN2 = 'cn=MEP Template2,' + DEFAULT_SUFFIX

- 

-     log.info('Testing ' + PLUGIN_MANAGED_ENTRY + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     # Add our org units

-     try:

-         inst.add_s(Entry((PEOPLE_OU, {

-             'objectclass': 'top extensibleObject'.split(),

-             'ou': 'people'})))

-     except ldap.ALREADY_EXISTS:

-         pass

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to add people org unit: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((GROUP_OU, {

-             'objectclass': 'top extensibleObject'.split(),

-             'ou': 'people'})))

-     except ldap.ALREADY_EXISTS:

-         pass

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to add people org unit: error ' + e.message['desc'])

-         assert False

- 

-     # Add the template entry

-     try:

-         inst.add_s(Entry((TEMPLATE_DN, {

-             'objectclass': 'top mepTemplateEntry extensibleObject'.split(),

-             'cn': 'MEP Template',

-             'mepRDNAttr': 'cn',

-             'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),

-             'mepMappedAttr': 'cn: $cn|uid: $cn|gidNumber: $uidNumber'.split('|')

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to add template entry: error ' + e.message['desc'])

-         assert False

- 

-     # Add the config entry

-     try:

-         inst.add_s(Entry((CONFIG_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'cn': 'config',

-             'originScope': PEOPLE_OU,

-             'originFilter': 'objectclass=posixAccount',

-             'managedBase': GROUP_OU,

-             'managedTemplate': TEMPLATE_DN

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to add config entry: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add an entry that meets the MEP scope

-     try:

-         inst.add_s(Entry((USER_DN, {

-             'objectclass': 'top posixAccount extensibleObject'.split(),

-             'uid': 'user1',

-             'cn': 'user1',

-             'uidNumber': '1',

-             'gidNumber': '1',

-             'homeDirectory': '/home/user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to user1: error ' + e.message['desc'])

-         assert False

- 

-     # Check if a managed group entry was created

-     try:

-         inst.search_s(MEP_USER_DN, ldap.SCOPE_BASE, '(objectclass=top)')

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Unable to find MEP entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change the config

-     ############################################################################

- 

-     # Add a new template entry

-     try:

-         inst.add_s(Entry((TEMPLATE_DN2, {

-             'objectclass': 'top mepTemplateEntry extensibleObject'.split(),

-             'cn': 'MEP Template2',

-             'mepRDNAttr': 'uid',

-             'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),

-             'mepMappedAttr': 'cn: $uid|uid: $cn|gidNumber: $gidNumber'.split('|')

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to add template entry2: error ' + e.message['desc'])

-         assert False

- 

-     # Set the new template dn

-     try:

-         inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'managedTemplate', TEMPLATE_DN2)])

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to set mep plugin config: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add an entry that meets the MEP scope

-     try:

-         inst.add_s(Entry((USER_DN2, {

-             'objectclass': 'top posixAccount extensibleObject'.split(),

-             'uid': 'user 1',

-             'cn': 'user 1',

-             'uidNumber': '1',

-             'gidNumber': '1',

-             'homeDirectory': '/home/user2'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to user2: error ' + e.message['desc'])

-         assert False

- 

-     # Check if a managed group entry was created

-     try:

-         inst.search_s(MEP_USER_DN2, ldap.SCOPE_BASE, '(objectclass=top)')

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Unable to find MEP entry2: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_MANAGED_ENTRY)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to delete test user1: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(USER_DN2)

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to delete test user 2: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(TEMPLATE_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to delete template1: ' + e.message['desc'])

-         assert False

- 

-     inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)

- 

-     try:

-         inst.delete_s(TEMPLATE_DN2)

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to delete template2: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(CONFIG_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_mep: Failed to delete config: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_mep: PASS\n')

-     return

- 

- 

- ################################################################################

- #

- # Test Passthru Plugin (7)

- #

- ################################################################################

- def test_passthru(inst, args=None):

-     # Passthru is a bit picky about the state of the entry - we can't just restart it

-     if args == "restart":

-         return

- 

-     # stop the plugin

-     inst.plugins.disable(name=PLUGIN_PASSTHRU)

- 

-     PLUGIN_DN = 'cn=' + PLUGIN_PASSTHRU + ',cn=plugins,cn=config'

-     PASSTHRU_DN = 'uid=admin,dc=pass,dc=thru'

-     PASSTHRU_DN2 = 'uid=admin2,dc=pass2,dc=thru'

-     PASS_SUFFIX1 = 'dc=pass,dc=thru'

-     PASS_SUFFIX2 = 'dc=pass2,dc=thru'

-     PASS_BE2 = 'PASS2'

- 

-     log.info('Testing ' + PLUGIN_PASSTHRU + '...')

- 

-     ############################################################################

-     # Add a new "remote" instance, and a user for auth

-     ############################################################################

- 

-     # Create second instance

-     passthru_inst = DirSrv(verbose=False)

- 

-     # Args for the instance

-     args_instance[SER_HOST] = LOCALHOST

-     args_instance[SER_PORT] = 33333

-     args_instance[SER_SERVERID_PROP] = 'passthru'

-     args_instance[SER_CREATION_SUFFIX] = PASS_SUFFIX1

-     args_passthru_inst = args_instance.copy()

-     passthru_inst.allocate(args_passthru_inst)

-     if passthru_inst.exists():

-         passthru_inst.delete()

-     passthru_inst.create()

-     passthru_inst.open()

- 

-     # Create a second backend

-     passthru_inst.backends.create(None, properties={

-         BACKEND_NAME: PASS_BE2,

-         'suffix': PASS_SUFFIX2,

-         })

- 

-     # Create the top of the tree

-     try:

-         passthru_inst.add_s(Entry((PASS_SUFFIX2, {

-             'objectclass': 'top domain'.split(),

-             'dc': 'pass2'})))

-     except ldap.ALREADY_EXISTS:

-         pass

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: Failed to create suffix entry: error ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     # Add user to suffix1

-     try:

-         passthru_inst.add_s(Entry((PASSTHRU_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'admin',

-             'userpassword': 'password'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: Failed to admin1: error ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     # Add user to suffix 2

-     try:

-         passthru_inst.add_s(Entry((PASSTHRU_DN2, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'admin2',

-             'userpassword': 'password'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: Failed to admin2 : error ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     ############################################################################

-     # Configure and start plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on'),

-                                   (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass,dc=thru')])

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # login as user

-     try:

-         inst.simple_bind_s(PASSTHRU_DN, "password")

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: pass through bind failed: ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     ############################################################################

-     # Change the config

-     ############################################################################

- 

-     # login as root DN

-     try:

-         inst.simple_bind_s(DN_DM, PASSWORD)

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: pass through bind failed: ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass2,dc=thru')])

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # login as user

-     try:

-         inst.simple_bind_s(PASSTHRU_DN2, "password")

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: pass through bind failed: ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     # login as root DN

-     try:

-         inst.simple_bind_s(DN_DM, PASSWORD)

-     except ldap.LDAPError as e:

-         log.fatal('test_passthru: pass through bind failed: ' + e.message['desc'])

-         passthru_inst.delete()

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_PASSTHRU)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     # remove the passthru instance

-     passthru_inst.delete()

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_passthru: PASS\n')

- 

-     return

- 

- 

- ################################################################################

- #

- # Test Referential Integrity Plugin (8)

- #

- ################################################################################

- def test_referint(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_REFER_INTEGRITY)

-     inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

- 

-     if args == "restart":

-         return

- 

-     log.info('Testing ' + PLUGIN_REFER_INTEGRITY + '...')

-     PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'

-     SHARED_CONFIG_DN = 'cn=RI Config,' + DEFAULT_SUFFIX

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'member')])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add some users and a group

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user2'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add user2: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((GROUP_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'cn': 'group',

-             'member': USER1_DN,

-             'uniquemember': USER2_DN

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add group: error ' + e.message['desc'])

-         assert False

- 

-     # Grab the referint log file from the plugin

- 

-     try:

-         entries = inst.search_s(PLUGIN_DN, ldap.SCOPE_BASE, '(objectclass=top)')

-         REFERINT_LOGFILE = entries[0].getValue('referint-logfile')

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Unable to search plugin entry: ' + e.message['desc'])

-         assert False

- 

-     # Add shared config entry

-     try:

-         inst.add_s(Entry((SHARED_CONFIG_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'referint-membership-attr': 'member',

-             'referint-update-delay': '0',

-             'referint-logfile': REFERINT_LOGFILE,

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to shared config entry: error ' + e.message['desc'])

-         assert False

- 

-     # Delete a user

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     # Check for integrity

-     try:

-         entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')')

-         if entry:

-             log.fatal('test_referint: user1 was not removed from group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Unable to search group: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change the config

-     ############################################################################

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Delete a user

-     try:

-         inst.delete_s(USER2_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     # Check for integrity

-     try:

-         entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(uniquemember=' + USER2_DN + ')')

-         if entry:

-             log.fatal('test_referint: user2 was not removed from group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Unable to search group: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Set the shared config entry and test the plugin

-     ############################################################################

- 

-     # The shared config entry uses "member" - the above test used "uniquemember"

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, CONFIG_AREA, SHARED_CONFIG_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to set plugin area: error ' + e.message['desc'])

-         assert False

- 

-     # Delete the group, and readd everything

-     try:

-         inst.delete_s(GROUP_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete group: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((USER2_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user2'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add user2: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.add_s(Entry((GROUP_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'cn': 'group',

-             'member': USER1_DN,

-             'uniquemember': USER2_DN

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add group: error ' + e.message['desc'])

-         assert False

- 

-     # Delete a user

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     # Check for integrity

-     try:

-         entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')')

-         if entry:

-             log.fatal('test_referint: user1 was not removed from group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Unable to search group: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Change the shared config entry to use 'uniquemember' and test the plugin

-     ############################################################################

- 

-     try:

-         inst.modify_s(SHARED_CONFIG_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to set shared plugin entry(uniquemember): error '

-                   + e.message['desc'])

-         assert False

- 

-     # Delete a user

-     try:

-         inst.delete_s(USER2_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     # Check for integrity

-     try:

-         entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(uniquemember=' + USER2_DN + ')')

-         if entry:

-             log.fatal('test_referint: user2 was not removed from group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Unable to search group: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Remove shared config from plugin, and retest

-     ############################################################################

- 

-     # First change the plugin to use member before we move the shared config that uses uniquemember

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'member')])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to update config(uniquemember): error ' + e.message['desc'])

-         assert False

- 

-     # Remove shared config from plugin

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, CONFIG_AREA, None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     # Add test user

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     # Add user to group

-     try:

-         inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'member', USER1_DN)])

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to add uniquemember: error ' + e.message['desc'])

-         assert False

- 

-     # Delete a user

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     # Check for integrity

-     try:

-         entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')')

-         if entry:

-             log.fatal('test_referint: user1 was not removed from group')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Unable to search group: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_REFER_INTEGRITY)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     try:

-         inst.delete_s(GROUP_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete group: ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(SHARED_CONFIG_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_referint: Failed to delete shared config entry: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_referint: PASS\n')

- 

-     return

- 

- 

- ################################################################################

- #

- # Test Retro Changelog Plugin (9)

- #

- ################################################################################

- def test_retrocl(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)

-     inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)

- 

-     if args == "restart":

-         return

- 

-     log.info('Testing ' + PLUGIN_RETRO_CHANGELOG + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     # Gather the current change count (it's not 1 once we start the stabilty tests)

-     try:

-         entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')

-     except ldap.LDAPError as e:

-         log.fatal('test_retrocl: Failed to get the count: error ' + e.message['desc'])

-         assert False

- 

-     entry_count = len(entry)

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Add a user

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_retrocl: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     # Check we logged this in the retro cl

-     try:

-         entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')

-         if not entry or len(entry) == entry_count:

-             log.fatal('test_retrocl: changelog not updated')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_retrocl: Unable to search group: ' + e.message['desc'])

-         assert False

- 

-     entry_count += 1

- 

-     ############################################################################

-     # Change the config - disable plugin

-     ############################################################################

- 

-     inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_retrocl: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     # Check we didn't logged this in the retro cl

-     try:

-         entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')

-         if len(entry) != entry_count:

-             log.fatal('test_retrocl: changelog incorrectly updated - change count: '

-                       + str(len(entry)) + ' - expected 1')

-             assert False

-     except ldap.LDAPError as e:

-         log.fatal('test_retrocl: Unable to search retro changelog: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)

-     test_dependency(inst, PLUGIN_RETRO_CHANGELOG)

- 

-     ############################################################################

-     # Cleanup

-     ############################################################################

- 

-     # None

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_retrocl: PASS\n')

- 

-     return

- 

- 

- ################################################################################

- #

- # Test Root DN Access Control Plugin (10)

- #

- ################################################################################

- def test_rootdn(inst, args=None):

-     # stop the plugin, and start it

-     inst.plugins.disable(name=PLUGIN_ROOTDN_ACCESS)

-     inst.plugins.enable(name=PLUGIN_ROOTDN_ACCESS)

- 

-     if args == "restart":

-         return

- 

-     PLUGIN_DN = 'cn=' + PLUGIN_ROOTDN_ACCESS + ',cn=plugins,cn=config'

- 

-     log.info('Testing ' + PLUGIN_ROOTDN_ACCESS + '...')

- 

-     ############################################################################

-     # Configure plugin

-     ############################################################################

- 

-     # Add an user and aci to open up cn=config

-     try:

-         inst.add_s(Entry((USER1_DN, {

-             'objectclass': 'top extensibleObject'.split(),

-             'uid': 'user1',

-             'userpassword': 'password'

-         })))

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: Failed to add user1: error ' + e.message['desc'])

-         assert False

- 

-     # Set an aci so we can modify the plugin after ew deny the root dn

-     ACI = ('(target ="ldap:///cn=config")(targetattr = "*")(version 3.0;acl ' +

-            '"all access";allow (all)(userdn="ldap:///anyone");)')

-     try:

-         inst.modify_s(DN_CONFIG, [(ldap.MOD_ADD, 'aci', ACI)])

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])

-         assert False

- 

-     # Set allowed IP to an unknown host - blocks root dn

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-allow-ip', '10.10.10.10')])

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Bind as Root DN

-     failed = False

-     try:

-         inst.simple_bind_s(DN_DM, PASSWORD)

-     except ldap.LDAPError as e:

-         failed = True

- 

-     if not failed:

-         log.fatal('test_rootdn: Root DN was incorrectly able to bind')

-         assert False

- 

-     ############################################################################

-     # Change the config

-     ############################################################################

- 

-     # Bind as the user who can make updates to the config

-     try:

-         inst.simple_bind_s(USER1_DN, 'password')

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: failed to bind as user1')

-         assert False

- 

-     # First, test that invalid plugin changes are rejected

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-deny-ip', '12.12.ZZZ.12')])

-         log.fatal('test_rootdn: Incorrectly allowed to add invalid "rootdn-deny-ip: 12.12.ZZZ.12"')

-         assert False

-     except ldap.LDAPError:

-         pass

- 

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-allow-host', 'host._.com')])

-         log.fatal('test_rootdn: Incorrectly allowed to add invalid "rootdn-allow-host: host._.com"')

-         assert False

-     except ldap.LDAPError:

-         pass

- 

-     # Remove the restriction

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, 'rootdn-allow-ip', None)])

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test plugin

-     ############################################################################

- 

-     # Bind as Root DN

-     failed = False

-     try:

-         inst.simple_bind_s(DN_DM, PASSWORD)

-     except ldap.LDAPError as e:

-         failed = True

- 

-     if failed:

-         log.fatal('test_rootdn: Root DN was not able to bind')

-         assert False

- 

-     ############################################################################

-     # Test plugin dependency

-     ############################################################################

- 

-     test_dependency(inst, PLUGIN_ROOTDN_ACCESS)

- 

-     ############################################################################

-     # Cleanup - remove ACI from cn=config and test user

-     ############################################################################

- 

-     try:

-         inst.modify_s(DN_CONFIG, [(ldap.MOD_DELETE, 'aci', ACI)])

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])

-         assert False

- 

-     try:

-         inst.delete_s(USER1_DN)

-     except ldap.LDAPError as e:

-         log.fatal('test_rootdn: Failed to delete user1: ' + e.message['desc'])

-         assert False

- 

-     ############################################################################

-     # Test passed

-     ############################################################################

- 

-     log.info('test_rootdn: PASS\n')

- 

-     return

- 

- 

- # Array of test functions

- func_tests = [test_acctpolicy, test_attruniq, test_automember, test_dna,

-               test_linkedattrs, test_memberof, test_mep, test_passthru,

-               test_referint, test_retrocl, test_rootdn]

- 

- 

- def test_all_plugins(inst, args=None):

-     for func in func_tests:

-         func(inst, args)

- 

-     return

@@ -18,6 +18,9 @@ 

  from lib389 import DirSrv, Entry

  from lib389._constants import *

  from lib389.properties import *

+ from lib389.plugins import ReferentialIntegrityPlugin, MemberOfPlugin

+ from lib389.utils import *

+ from lib389.idm.directorymanager import *

  

  log = logging.getLogger(__name__)

  
@@ -25,39 +28,18 @@ 

  GROUP_DN = 'cn=stress-group,' + DEFAULT_SUFFIX

  

  

- def openConnection(inst):

-     # Open a new connection to our LDAP server

-     server = DirSrv(verbose=False)

-     args_instance[SER_HOST] = HOST_STANDALONE

-     args_instance[SER_PORT] = PORT_STANDALONE

-     args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE

-     args_standalone = args_instance.copy()

-     server.allocate(args_standalone)

-     server.open()

- 

-     return server

- 

- 

  # Configure Referential Integrity Plugin for stress test

  def configureRI(inst):

-     inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)

-     PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('configureRI: Failed to configure RI plugin: error ' + e.message['desc'])

-         assert False

+     plugin = ReferentialIntegrityPlugin(inst)

+     plugin.enable()

+     plugin.replace('referint-membership-attr', 'uniquemember')

  

  

  # Configure MemberOf Plugin for stress test

  def configureMO(inst):

-     inst.plugins.enable(name=PLUGIN_MEMBER_OF)

-     PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'

-     try:

-         inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])

-     except ldap.LDAPError as e:

-         log.fatal('configureMO: Failed to update config(uniquemember): error ' + e.message['desc'])

-         assert False

+     plugin = MemberOfPlugin(inst)

+     plugin.enable()

+     plugin.replace('memberofgroupattr', 'uniquemember')

  

  

  def cleanup(conn):
@@ -76,7 +58,8 @@ 

          self.rdnval = rdnval

  

      def run(self):

-         conn = openConnection(self.inst)

+         dm = DirectoryManager(self.inst)

+         conn = dm.bind()

          idx = 0

          log.info('DelUsers - Deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')

          while idx < NUM_USERS:
@@ -104,17 +87,18 @@ 

  

      def run(self):

          # Start adding users

-         conn = openConnection(self.inst)

+         dm = DirectoryManager(self.inst)

+         conn = dm.bind()

          idx = 0

  

          if self.addToGroup:

              try:

                  conn.add_s(Entry((GROUP_DN,

-                                   {'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),

-                                    'uid': 'user' + str(idx)})))

+                                   {'objectclass': b'top groupOfNames groupOfUniqueNames'.split(),

+                                    'cn': 'stress-group'})))

              except ldap.LDAPError as e:

                  if e == ldap.UNAVAILABLE or e == ldap.SERVER_DOWN:

-                     log.fatal('AddUsers: failed to add group (' + USER_DN + ') error: ' + e.message['desc'])

+                     log.fatal('AddUsers: failed to add group (' + GROUP_DN + ') error: ' + e.message['desc'])

                      assert False

  

          log.info('AddUsers - Adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
@@ -122,8 +106,8 @@ 

          while idx < NUM_USERS:

              USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX

              try:

-                 conn.add_s(Entry((USER_DN, {'objectclass': 'top extensibleObject'.split(),

-                                             'uid': 'user' + str(idx)})))

+                 conn.add_s(Entry((USER_DN, {'objectclass': b'top nsOrgPerson'.split(),

+                                             'uid': ensure_bytes('user' + str(idx))})))

              except ldap.LDAPError as e:

                  if e == ldap.UNAVAILABLE or e == ldap.SERVER_DOWN:

                      log.fatal('AddUsers: failed to add (' + USER_DN + ') error: ' + e.message['desc'])
@@ -132,7 +116,7 @@ 

              if self.addToGroup:

                  # Add the user to the group

                  try:

-                     conn.modify_s(GROUP_DN, [(ldap.MOD_ADD, 'uniquemember', USER_DN)])

+                     conn.modify_s(GROUP_DN, [(ldap.MOD_ADD, 'uniquemember', ensure_bytes(USER_DN))])

                  except ldap.LDAPError as e:

                      if e == ldap.UNAVAILABLE or e == ldap.SERVER_DOWN:

                          log.fatal('AddUsers: Failed to add user' + USER_DN + ' to group: error ' + e.message['desc'])

The added file is too large to be shown here, see it at: dirsrvtests/tests/suites/plugins/acceptance_test.py
@@ -137,6 +137,8 @@ 

  DN_RESTORE_TASK = "cn=restore,%s" % DN_TASKS

  DN_MBO_TASK = "cn=memberOf task,%s" % DN_TASKS

  DN_TOMB_FIXUP_TASK = "cn=fixup tombstones,%s" % DN_TASKS

+ DN_FIXUP_LINKED_ATTIBUTES = "cn=fixup linked attributes,%s" % DN_TASKS

+ DN_AUTOMEMBER_REBUILD_TASK = "cn=automember rebuild membership,%s" % DN_TASKS

  

  # Script Constants

  LDIF2DB = 'ldif2db'

file modified
+9 -4
@@ -19,12 +19,17 @@ 

  

      def __init__(self, instance):

          self._instance = instance

+         self._contents = []

  

          ds_paths = Paths(self._instance.serverid, self._instance)

          self.path = os.path.join(ds_paths.config_dir, 'dse.ldif')

  

          with open(self.path, 'r') as file_dse:

-             self._contents = file_dse.readlines()

+             for line in file_dse.readlines():

+                 if line.startswith('dn'):

+                     self._contents.append(line.lower())

+                 else:

+                     self._contents.append(line)

  

      def _update(self):

          """Update the dse.ldif with a new contents"""
@@ -39,7 +44,7 @@ 

          relative attribute indexes and the attribute value

          """

  

-         entry_dn_i = self._contents.index("dn: {}\n".format(entry_dn))

+         entry_dn_i = self._contents.index("dn: {}\n".format(entry_dn.lower()))

          attr_data = {}

  

          # Find where the entry ends
@@ -58,7 +63,7 @@ 

                  attr_data.update({entry_slice.index(line): attr_value})

  

          if not attr_data:

-             raise ValueError("Attribute {} wasn't found under dn: {}".format(attr, entry_dn))

+             raise ValueError("Attribute {} wasn't found under dn: {}".format(attr, entry_dn.lower()))

  

          return entry_dn_i, attr_data

  
@@ -89,7 +94,7 @@ 

          :type value: str

          """

  

-         entry_dn_i = self._contents.index("dn: {}\n".format(entry_dn))

+         entry_dn_i = self._contents.index("dn: {}\n".format(entry_dn.lower()))

          self._contents.insert(entry_dn_i+1, "{}: {}\n".format(attr, value))

          self._update()

  

file modified
+843 -56
@@ -12,7 +12,6 @@ 

  

  from lib389 import tasks

  from lib389._mapped_object import DSLdapObjects, DSLdapObject

- from lib389.exceptions import Error

  from lib389.lint import DSRILE0001

  from lib389._constants import DN_PLUGIN

  from lib389.properties import (
@@ -20,7 +19,16 @@ 

          PLUGINS_ENABLE_ON_VALUE, PLUGINS_ENABLE_OFF_VALUE, PLUGIN_ENABLE

          )

  

+ 

  class Plugin(DSLdapObject):

+     """A single instance of a plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'nsslapd-pluginEnabled' : 'off'

      }
@@ -43,20 +51,44 @@ 

          self._protected = True

  

      def enable(self):

+         """Set nsslapd-pluginEnabled to on"""

+ 

          self.set('nsslapd-pluginEnabled', 'on')

  

      def disable(self):

+         """Set nsslapd-pluginEnabled to off"""

+ 

          self.set('nsslapd-pluginEnabled', 'off')

  

+     def restart(self):

+         """Disable and then enable the plugin"""

+ 

+         self.disable()

+         self.enable()

+ 

      def status(self):

+         """Check if the plugin is enabled"""

+ 

          return self.get_attr_val_utf8('nsslapd-pluginEnabled') == 'on'

  

      def create(self, rdn=None, properties=None, basedn=None):

-         # When we create plugins, we don't want people to have to consider all

-         # the little details. Plus, the server during creation needs to be able

-         # to create these from nothing.

-         # As a result, all the named plugins carry a default properties

-         # dictionary that can be used.

+         """Create a plugin entry

+ 

+         When we create plugins, we don't want people to have to consider all

+         the little details. Plus, the server during creation needs to be able

+         to create these from nothing.

+         As a result, all the named plugins carry a default properties

+         dictionary that can be used.

+ 

+         :param rdn: RDN of the new entry

+         :type rdn: str

+         :param properties: Attributes for the new entry

+         :type properties: dict

+         :param basedn: Base DN of the new entry

+         :type rdn: str

+ 

+         :returns: Plugin class instance of the created entry

+         """

  

          # Copy the plugin internal properties.

          internal_properties = copy.deepcopy(self._plugin_properties)
@@ -64,12 +96,30 @@ 

              internal_properties.update(properties)

          return super(Plugin, self).create(rdn, internal_properties, basedn)

  

+ 

  class AddnPlugin(Plugin):

+     """An instance of addn plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=addn,cn=plugins,cn=config"):

          super(AddnPlugin, self).__init__(instance, dn)

          # Need to add wrappers to add domains to this.

  

+ 

  class AttributeUniquenessPlugin(Plugin):

+     """An instance of attribute uniqueness plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=attribute uniqueness,cn=plugins,cn=config"):

          super(AttributeUniquenessPlugin, self).__init__(instance, dn)

  
@@ -78,24 +128,45 @@ 

      # of the plugin, rather than many configs.

  

      def add_unique_attribute(self, attr):

+         """Add a uniqueness-attribute-name attribute"""

+ 

          self.add('uniqueness-attribute-name', attr)

  

      def remove_unique_attribute(self, attr):

+         """Remove a uniqueness-attribute-name attribute"""

+ 

          self.remove('uniqueness-attribute-name', attr)

  

      def add_unique_subtree(self, basedn):

+         """Add a uniqueness-subtree attribute"""

+ 

          self.add('uniqueness-subtrees', basedn)

  

      def remove_unique_subtree(self, basedn):

+         """Remove a uniqueness-subtree attribute"""

+ 

          self.remove('uniqueness-subtrees', basedn)

  

      def enable_all_subtrees(self):

+         """Set uniqueness-across-all-subtrees to on"""

+ 

          self.set('uniqueness-across-all-subtrees', 'on')

  

      def disable_all_subtrees(self):

+         """Set uniqueness-across-all-subtrees to off"""

+ 

          self.set('uniqueness-across-all-subtrees', 'off')

  

+ 

  class LdapSSOTokenPlugin(Plugin):

+     """An instance of ldapssotoken plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'ldapssotoken',

          'nsslapd-pluginEnabled' : 'off',
@@ -111,14 +182,97 @@ 

      def __init__(self, instance, dn="cn=ldapssotoken,cn=plugins,cn=config"):

          super(LdapSSOTokenPlugin, self).__init__(instance, dn)

  

+ 

  class ManagedEntriesPlugin(Plugin):

+     """An instance of managed entries plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=managed entries,cn=plugins,cn=config"):

          super(ManagedEntriesPlugin, self).__init__(instance, dn)

  

-     # This will likely need to be a bit like both the DSLdapObjects AND the object.

-     # Because there are potentially many MEP configs.

+ 

+ class MEPConfig(DSLdapObject):

+     """A single instance of MEP config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn):

+         super(MEPConfig, self).__init__(instance, dn)

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn']

+         self._create_objectclasses = ['top', 'extensibleObject']

+         self._protected = False

+ 

+ 

+ class MEPConfigs(DSLdapObjects):

+     """A DSLdapObjects entity which represents MEP config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

+     """

+ 

+     def __init__(self, instance, basedn="cn=managed entries,cn=plugins,cn=config"):

+         super(MEPConfigs, self).__init__(instance)

+         self._objectclasses = ['top', 'extensibleObject']

+         self._filterattrs = ['cn']

+         self._childobject = MEPConfig

+         self._basedn = basedn

+ 

+ 

+ class MEPTemplate(DSLdapObject):

+     """A single instance of MEP template entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn=None):

+         super(MEPTemplate, self).__init__(instance, dn)

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn']

+         self._create_objectclasses = ['top', 'extensibleObject', 'mepTemplateEntry']

+         self._protected = False

+ 

+ 

+ class MEPTemplates(DSLdapObjects):

+     """A DSLdapObjects entity which represents MEP template entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

+     """

+ 

+     def __init__(self, instance, basedn):

+         super(MEPTemplates, self).__init__(instance)

+         self._objectclasses = ['top', 'extensibleObject']

+         self._filterattrs = ['cn']

+         self._childobject = MEPTemplate

+         self._basedn = basedn

+ 

  

  class ReferentialIntegrityPlugin(Plugin):

+     """An instance of referential integrity postoperation plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'referential integrity postoperation',

          'nsslapd-pluginEnabled': 'off',
@@ -146,6 +300,8 @@ 

          self._lint_functions = [self._lint_update_delay]

  

      def create(self, rdn=None, properties=None, basedn=None):

+         """Create an instance of the plugin"""

+ 

          referint_log = os.path.join(self._instance.ds_paths.log_dir, "referint")

          if properties is None:

              properties = {'referint-logfile': referint_log}
@@ -160,96 +316,240 @@ 

                  return DSRILE0001

  

      def get_update_delay(self):

+         """Get referint-update-delay attribute"""

+ 

          return self.get_attr_val_int('referint-update-delay')

  

      def get_update_delay_formatted(self):

+         """Display referint-update-delay attribute"""

+ 

          return self.display_attr('referint-update-delay')

  

      def set_update_delay(self, value):

+         """Set referint-update-delay attribute"""

+ 

          self.set('referint-update-delay', str(value))

  

      def get_membership_attr(self, formatted=False):

+         """Get referint-membership-attr attribute"""

+ 

          return self.get_attr_vals_utf8('referint-membership-attr')

  

      def get_membership_attr_formatted(self):

+         """Display referint-membership-attr attribute"""

+ 

          return self.display_attr('referint-membership-attr')

  

      def add_membership_attr(self, attr):

+         """Add referint-membership-attr attribute"""

+ 

          self.add('referint-membership-attr', attr)

  

      def remove_membership_attr(self, attr):

+         """Remove referint-membership-attr attribute"""

+ 

          self.remove('referint-membership-attr', attr)

  

      def get_entryscope(self, formatted=False):

+         """Get nsslapd-pluginentryscope attribute"""

+ 

          return self.get_attr_vals_utf8('nsslapd-pluginentryscope')

  

      def get_entryscope_formatted(self):

+         """Display nsslapd-pluginentryscope attribute"""

+ 

          return self.display_attr('nsslapd-pluginentryscope')

  

      def add_entryscope(self, attr):

+         """Add nsslapd-pluginentryscope attribute"""

+ 

          self.add('nsslapd-pluginentryscope', attr)

  

      def remove_entryscope(self, attr):

+         """Remove nsslapd-pluginentryscope attribute"""

+ 

          self.remove('nsslapd-pluginentryscope', attr)

  

      def remove_all_entryscope(self):

+         """Remove all nsslapd-pluginentryscope attributes"""

+ 

          self.remove_all('nsslapd-pluginentryscope')

  

      def get_excludescope(self):

+         """Get nsslapd-pluginexcludeentryscope attribute"""

+ 

          return self.get_attr_vals_ut8('nsslapd-pluginexcludeentryscope')

  

      def get_excludescope_formatted(self):

+         """Display nsslapd-pluginexcludeentryscope attribute"""

+ 

          return self.display_attr('nsslapd-pluginexcludeentryscope')

  

      def add_excludescope(self, attr):

+         """Add nsslapd-pluginexcludeentryscope attribute"""

+ 

          self.add('nsslapd-pluginexcludeentryscope', attr)

  

      def remove_excludescope(self, attr):

+         """Remove nsslapd-pluginexcludeentryscope attribute"""

+ 

          self.remove('nsslapd-pluginexcludeentryscope', attr)

  

      def remove_all_excludescope(self):

+         """Remove all nsslapd-pluginexcludeentryscope attributes"""

+ 

          self.remove_all('nsslapd-pluginexcludeentryscope')

  

      def get_container_scope(self):

+         """Get nsslapd-plugincontainerscope attribute"""

+ 

          return self.get_attr_vals_ut8('nsslapd-plugincontainerscope')

  

      def get_container_scope_formatted(self):

+         """Display nsslapd-plugincontainerscope attribute"""

+ 

          return self.display_attr('nsslapd-plugincontainerscope')

  

      def add_container_scope(self, attr):

+         """Add nsslapd-plugincontainerscope attribute"""

+ 

          self.add('nsslapd-plugincontainerscope', attr)

  

      def remove_container_scope(self, attr):

+         """Remove nsslapd-plugincontainerscope attribute"""

+ 

          self.remove('nsslapd-plugincontainerscope', attr)

  

      def remove_all_container_scope(self):

+         """Remove all nsslapd-plugincontainerscope attributes"""

+ 

          self.remove_all('nsslapd-plugincontainerscope')

  

+     def get_configarea(self):

+         """Get nsslapd-pluginConfigArea attribute"""

+ 

+         return self.get_attr_val_utf8_l('nsslapd-pluginConfigArea')

+ 

+     def set_configarea(self, attr):

+         """Set nsslapd-pluginConfigArea attribute"""

+ 

+         return self.set('nsslapd-pluginConfigArea', attr)

+ 

+     def remove_configarea(self):

+         """Remove all nsslapd-pluginConfigArea attributes"""

+ 

+         return self.remove_all('nsslapd-pluginConfigArea')

+ 

+ 

+ class ReferentialIntegrityConfig(DSLdapObject):

+     """An instance of Referential Integrity config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn):

+         super(ReferentialIntegrityConfig, self).__init__(instance, dn)

+         self._dn = dn

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn',

+                                  'referint-update-delay',

+                                  'referint-logfile',

+                                  'referint-membership-attr']

+         self._create_objectclasses = ['top', 'extensibleObject']

+         self._protected = False

+         self._exit_code = None

+ 

+ 

  class SyntaxValidationPlugin(Plugin):

+     """An instance of Syntax Validation Task plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Syntax Validation Task,cn=plugins,cn=config"):

          super(SyntaxValidationPlugin, self).__init__(instance, dn)

  

+ 

  class SchemaReloadPlugin(Plugin):

+     """An instance of Schema Reload plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Schema Reload,cn=plugins,cn=config"):

          super(SchemaReloadPlugin, self).__init__(instance, dn)

  

+ 

  class StateChangePlugin(Plugin):

+     """An instance of State Change plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=State Change Plugin,cn=plugins,cn=config"):

          super(StateChangePlugin, self).__init__(instance, dn)

  

+ 

  class ACLPlugin(Plugin):

+     """An instance of addn plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=ACL Plugin,cn=plugins,cn=config"):

          super(ACLPlugin, self).__init__(instance, dn)

  

+ 

  class ACLPreoperationPlugin(Plugin):

+     """An instance of ACL preoperation plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=ACL preoperation,cn=plugins,cn=config"):

          super(ACLPreoperationPlugin, self).__init__(instance, dn)

  

+ 

  class RolesPlugin(Plugin):

+     """An instance of Roles plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Roles Plugin,cn=plugins,cn=config"):

          super(RolesPlugin, self).__init__(instance, dn)

  

+ 

  class MemberOfPlugin(Plugin):

+     """An instance of MemberOf plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'MemberOf Plugin',

          'nsslapd-pluginEnabled' : 'off',
@@ -271,93 +571,181 @@ 

          self._must_attributes.extend(['memberOfGroupAttr', 'memberOfAttr'])

  

      def get_attr(self):

+         """Get memberofattr attribute"""

+ 

          return self.get_attr_val_utf8_l('memberofattr')

  

      def get_attr_formatted(self):

+         """Display memberofattr attribute"""

+ 

          return self.display_attr('memberofattr')

  

      def set_attr(self, attr):

+         """Set memberofattr attribute"""

+ 

          self.set('memberofattr', attr)

  

      def get_groupattr(self):

+         """Get memberofgroupattr attribute"""

+ 

          return self.get_attr_vals_utf8_l('memberofgroupattr')

  

      def get_groupattr_formatted(self):

+         """Display memberofgroupattr attribute"""

+ 

          return self.display_attr('memberofgroupattr')

  

      def add_groupattr(self, attr):

+         """Add memberofgroupattr attribute"""

+ 

          self.add('memberofgroupattr', attr)

  

+     def replace_groupattr(self, attr):

+         """Replace memberofgroupattr attribute"""

+ 

+         self.replace('memberofgroupattr', attr)

+ 

      def remove_groupattr(self, attr):

+         """Remove memberofgroupattr attribute"""

+ 

          self.remove('memberofgroupattr', attr)

  

      def get_allbackends(self):

+         """Get memberofallbackends attribute"""

+ 

          return self.get_attr_val_utf8_l('memberofallbackends')

  

      def get_allbackends_formatted(self):

+         """Display memberofallbackends attribute"""

+ 

          return self.display_attr('memberofallbackends')

  

      def enable_allbackends(self):

+         """Set memberofallbackends to on"""

+ 

          self.set('memberofallbackends', 'on')

  

      def disable_allbackends(self):

+         """Set memberofallbackends to off"""

+ 

          self.set('memberofallbackends', 'off')

  

      def get_skipnested(self):

+         """Get memberofskipnested attribute"""

+ 

          return self.get_attr_val_utf8_l('memberofskipnested')

  

      def get_skipnested_formatted(self):

+         """Display memberofskipnested attribute"""

+ 

          return self.display_attr('memberofskipnested')

  

      def enable_skipnested(self):

+         """Set memberofskipnested to on"""

+ 

          self.set('memberofskipnested', 'on')

  

      def disable_skipnested(self):

+         """Set memberofskipnested to off"""

+ 

          self.set('memberofskipnested', 'off')

  

      def get_autoaddoc(self):

+         """Get memberofautoaddoc attribute"""

+ 

          return self.get_attr_val_utf8_l('memberofautoaddoc')

  

      def get_autoaddoc_formatted(self):

+         """Display memberofautoaddoc attribute"""

+ 

          return self.display_attr('memberofautoaddoc')

  

      def set_autoaddoc(self, object_class):

+         """Set memberofautoaddoc attribute"""

+ 

          self.set('memberofautoaddoc', object_class)

  

      def remove_autoaddoc(self):

+         """Remove all memberofautoaddoc attributes"""

+ 

          self.remove_all('memberofautoaddoc')

  

      def get_entryscope(self, formatted=False):

+         """Get memberofentryscope attributes"""

+ 

          return self.get_attr_vals_utf8_l('memberofentryscope')

  

      def get_entryscope_formatted(self):

+         """Display memberofentryscope attributes"""

+ 

          return self.display_attr('memberofentryscope')

  

      def add_entryscope(self, attr):

+         """Add memberofentryscope attribute"""

+ 

          self.add('memberofentryscope', attr)

  

      def remove_entryscope(self, attr):

+         """Remove memberofentryscope attribute"""

+ 

          self.remove('memberofentryscope', attr)

  

      def remove_all_entryscope(self):

+         """Remove all memberofentryscope attributes"""

+ 

          self.remove_all('memberofentryscope')

  

      def get_excludescope(self):

+         """Get memberofentryscopeexcludesubtree attributes"""

+ 

          return self.get_attr_vals_utf8_l('memberofentryscopeexcludesubtree')

  

      def get_excludescope_formatted(self):

+         """Display memberofentryscopeexcludesubtree attributes"""

+ 

          return self.display_attr('memberofentryscopeexcludesubtree')

  

      def add_excludescope(self, attr):

+         """Add memberofentryscopeexcludesubtree attribute"""

+ 

          self.add('memberofentryscopeexcludesubtree', attr)

  

      def remove_excludescope(self, attr):

+         """Remove memberofentryscopeexcludesubtree attribute"""

+ 

          self.remove('memberofentryscopeexcludesubtree', attr)

  

      def remove_all_excludescope(self):

+         """Remove all memberofentryscopeexcludesubtree attributes"""

+ 

          self.remove_all('memberofentryscopeexcludesubtree')

  

+     def get_configarea(self):

+         """Get nsslapd-pluginConfigArea attribute"""

+ 

+         return self.get_attr_val_utf8_l('nsslapd-pluginConfigArea')

+ 

+     def set_configarea(self, attr):

+         """Set nsslapd-pluginConfigArea attribute"""

+ 

+         return self.set('nsslapd-pluginConfigArea', attr)

+ 

+     def remove_configarea(self):

+         """Remove nsslapd-pluginConfigArea attribute"""

+ 

+         return self.remove_all('nsslapd-pluginConfigArea')

+ 

      def fixup(self, basedn, _filter=None):

+         """Create a memberOf task

+ 

+         :param basedn: Basedn to fix up

+         :type basedn: str

+         :param _filter: a filter for entries to fix up

+         :type _filter: str

+ 

+         :returns: an instance of Task(DSLdapObject)

+         """

+ 

          task = tasks.MemberOfFixupTask(self._instance)

          task_properties = {'basedn': basedn}

          if _filter is not None:
@@ -366,27 +754,100 @@ 

  

          return task

  

+ 

+ class MemberOfSharedConfig(DSLdapObject):

+     """An instance of MemberOf config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn):

+         super(MemberOfSharedConfig, self).__init__(instance, dn)

+         self._dn = dn

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn', 'memberOfGroupAttr', 'memberOfAttr']

+         self._create_objectclasses = ['top', 'extensibleObject']

+         self._protected = False

+         self._exit_code = None

+ 

+ 

  class RetroChangelogPlugin(Plugin):

+     """An instance of Retro Changelog plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Retro Changelog Plugin,cn=plugins,cn=config"):

          super(RetroChangelogPlugin, self).__init__(instance, dn)

  

+ 

  class ClassOfServicePlugin(Plugin):

+     """An instance of Class of Service plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Class of Service,cn=plugins,cn=config"):

          super(ClassOfServicePlugin, self).__init__(instance, dn)

  

+ 

  class ViewsPlugin(Plugin):

+     """An instance of Views plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Views,cn=plugins,cn=config"):

          super(ViewsPlugin, self).__init__(instance, dn)

  

+ 

  class SevenBitCheckPlugin(Plugin):

+     """An instance of addn plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=7-bit check,cn=plugins,cn=config"):

          super(SevenBitCheckPlugin, self).__init__(instance, dn)

  

+ 

  class AccountUsabilityPlugin(Plugin):

+     """An instance of Account Usability plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Account Usability Plugin,cn=plugins,cn=config"):

          super(AccountUsabilityPlugin, self).__init__(instance, dn)

  

+ 

  class AutoMembershipPlugin(Plugin):

+     """An instance of Auto Membership plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'Auto Membership Plugin',

          'nsslapd-pluginEnabled' : 'off',
@@ -403,119 +864,227 @@ 

      def __init__(self, instance, dn="cn=Auto Membership Plugin,cn=plugins,cn=config"):

          super(AutoMembershipPlugin, self).__init__(instance, dn)

  

+     def fixup(self, basedn, _filter=None):

+         """Create an automember rebuild membership task

+ 

+         :param basedn: Basedn to fix up

+         :type basedn: str

+         :param _filter: a filter for entries to fix up

+         :type _filter: str

+ 

+         :returns: an instance of Task(DSLdapObject)

+         """

+ 

+         task = tasks.AutomemberRebuildMembershipTask(self._instance)

+         task_properties = {'basedn': basedn}

+         if _filter is not None:

+             task_properties['filter'] = _filter

+         task.create(properties=task_properties)

+ 

+         return task

+ 

+ 

  class AutoMembershipDefinition(DSLdapObject):

-     """A single instance of Auto Membership Plugin entry

+     """A single instance of Auto Membership Plugin config entry

  

-         :param instance: An instance

-         :type instance: lib389.DirSrv

-         :param dn: Entry DN

-         :type dn: str

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

      """

  

      def __init__(self, instance, dn=None):

          super(AutoMembershipDefinition, self).__init__(instance, dn)

          self._rdn_attribute = 'cn'

-         self._must_attributes = ['cn']

+         self._must_attributes = ['cn', 'autoMemberScope', 'autoMemberFilter', 'autoMemberGroupingAttr']

          self._create_objectclasses = ['top', 'AutoMemberDefinition']

          self._protected = False

  

      def get_groupattr(self):

-         """Get grouping attributes

+         """Get autoMemberGroupingAttr attributes"""

  

-             :returns: autoMemberGroupingAttr values

-         """

          return self.get_attr_vals_utf8('autoMemberGroupingAttr')

  

      def set_groupattr(self, attr):

-         """Set grouping attributes

+         """Set autoMemberGroupingAttr attribute"""

  

-             :param attr: autoMemberGroupingAttr value

-             :type attr: str

-         """

          self.set('autoMemberGroupingAttr', attr)

  

      def get_defaultgroup(self, attr):

-         """Get default group

+         """Get autoMemberDefaultGroup attributes"""

  

-             :returns: autoMemberDefaultGroup value

-         """

          return self.get_attr_vals_utf8('autoMemberDefaultGroup')

  

      def set_defaultgroup(self, attr):

-         """Set default group

+         """Set autoMemberDefaultGroup attribute"""

  

-             :param attr: autoMemberDefaultGroup value

-             :type attr: str

-         """

          self.set('autoMemberDefaultGroup', attr)  

  

      def get_scope(self, attr):

-         """Get scope

+         """Get autoMemberScope attributes"""

  

-             :returns: autoMemberScope value

-         """        

          return self.get_attr_vals_utf8('autoMemberScope')

  

      def set_scope(self, attr):

-         """Set scope

+         """Set autoMemberScope attribute"""

  

-             :param attr: autoMemberScope value

-             :type attr: str

-         """        

          self.set('autoMemberScope', attr)

  

      def get_filter(self, attr):

-         """Get filter

+         """Get autoMemberFilter attributes"""

  

-             :returns: autoMemberFilter value

-         """       

          return self.get_attr_vals_utf8('autoMemberFilter')

  

      def set_filter(self, attr):

-         """Set filter

+         """Set autoMemberFilter attributes"""

  

-             :param attr: autoMemberFilter value

-             :type attr: str

-         """ 

          self.set('autoMemberFilter', attr)

  

+ 

  class AutoMembershipDefinitions(DSLdapObjects):

-     """DSLdapObjects that represents Auto Membership Plugin entry

+     """A DSLdapObjects entity which represents Auto Membership Plugin config entry

  

-         :param instance: An instance

-         :type instance: lib389.DirSrv

-         :param basedn: Base DN for all account entries below

-         :type basedn: str

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

      """

  

      def __init__(self, instance, basedn="cn=Auto Membership Plugin,cn=plugins,cn=config"):

          super(AutoMembershipDefinitions, self).__init__(instance)

-         self._objectclasses = ['top','autoMemberDefinition']

+         self._objectclasses = ['top', 'autoMemberDefinition']

          self._filterattrs = ['cn']

          self._childobject = AutoMembershipDefinition

          self._basedn = basedn

  

+ 

  class ContentSynchronizationPlugin(Plugin):

+     """A single instance of Content Synchronization plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Content Synchronization,cn=plugins,cn=config"):

          super(ContentSynchronizationPlugin, self).__init__(instance, dn)

  

+ 

  class DereferencePlugin(Plugin):

+     """A single instance of deref plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=deref,cn=plugins,cn=config"):

          super(DereferencePlugin, self).__init__(instance, dn)

  

+ 

  class HTTPClientPlugin(Plugin):

+     """A single instance of HTTP Client plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=HTTP Client,cn=plugins,cn=config"):

          super(HTTPClientPlugin, self).__init__(instance, dn)

  

+ 

  class LinkedAttributesPlugin(Plugin):

+     """A single instance of Linked Attributes plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Linked Attributes,cn=plugins,cn=config"):

          super(LinkedAttributesPlugin, self).__init__(instance, dn)

  

+     def fixup(self, basedn, _filter=None):

+         """Create a fixup linked attributes task

+ 

+         :param basedn: Basedn to fix up

+         :type basedn: str

+         :param _filter: a filter for entries to fix up

+         :type _filter: str

+ 

+         :returns: an instance of Task(DSLdapObject)

+         """

+ 

+         task = tasks.FixupLinkedAttributesTask(self._instance)

+         task_properties = {'basedn': basedn}

+         if _filter is not None:

+             task_properties['filter'] = _filter

+         task.create(properties=task_properties)

+ 

+         return task

+ 

+ 

+ class LinkedAttributesConfig(DSLdapObject):

+     """A single instance of Linked Attributes Plugin config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn=None):

+         super(LinkedAttributesConfig, self).__init__(instance, dn)

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn']

+         self._create_objectclasses = ['top', 'extensibleObject']

+         self._protected = False

+ 

+ 

+ class LinkedAttributesConfigs(DSLdapObjects):

+     """A DSLdapObjects entity which represents Linked Attributes Plugin config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

+     """

+ 

+     def __init__(self, instance, basedn="cn=Linked Attributes,cn=plugins,cn=config"):

+         super(LinkedAttributesConfigs, self).__init__(instance)

+         self._objectclasses = ['top', 'extensibleObject']

+         self._filterattrs = ['cn']

+         self._childobject = LinkedAttributesConfig

+         self._basedn = basedn

+ 

+ 

  class PassThroughAuthenticationPlugin(Plugin):

+     """A single instance of Pass Through Authentication plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Pass Through Authentication,cn=plugins,cn=config"):

          super(PassThroughAuthenticationPlugin, self).__init__(instance, dn)

  

+ 

  class USNPlugin(Plugin):

+     """A single instance of USN (Update Sequence Number) plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'USN',

          'nsslapd-pluginEnabled': 'off',
@@ -535,16 +1104,31 @@ 

          self._create_objectclasses.extend(['extensibleObject'])

  

      def is_global_mode_set(self):

-         """Return True if global mode is enabled, else False."""

+         """Return True if nsslapd-entryusn-global is set to on, else False"""

+ 

          return self._instance.config.get_attr_val_utf8('nsslapd-entryusn-global') == 'on'

  

      def enable_global_mode(self):

+         """Set nsslapd-entryusn-global to on"""

+ 

          self._instance.config.set('nsslapd-entryusn-global', 'on')

  

      def disable_global_mode(self):

+         """Set nsslapd-entryusn-global to off"""

+ 

          self._instance.config.set('nsslapd-entryusn-global', 'off')

  

      def cleanup(self, suffix=None, backend=None, max_usn=None):

+         """Create a USN tombstone cleanup task

+ 

+         :param basedn: Basedn to fix up

+         :type basedn: str

+         :param _filter: a filter for entries to fix up

+         :type _filter: str

+ 

+         :returns: an instance of Task(DSLdapObject)

+         """

+ 

          task = tasks.USNTombstoneCleanupTask(self._instance)

          task_properties = {}

  
@@ -559,7 +1143,16 @@ 

  

          return task

  

+ 

  class WhoamiPlugin(Plugin):

+     """A single instance of whoami plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'whoami',

          'nsslapd-pluginEnabled' : 'on',
@@ -576,7 +1169,16 @@ 

      def __init__(self, instance, dn="cn=whoami,cn=plugins,cn=config"):

          super(WhoamiPlugin, self).__init__(instance, dn)

  

+ 

  class RootDNAccessControlPlugin(Plugin):

+     """A single instance of RootDN Access Control plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      _plugin_properties = {

          'cn' : 'RootDN Access Control',

          'nsslapd-pluginEnabled' : 'off',
@@ -595,42 +1197,68 @@ 

          self._create_objectclasses.extend(['rootDNPluginConfig'])

  

      def get_open_time(self):

+         """Get rootdn-open-time attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-open-time')

  

      def get_open_time_formatted(self):

+         """Display rootdn-open-time attribute"""

+ 

          return self.display_attr('rootdn-open-time')

  

      def set_open_time(self, attr):

+         """Set rootdn-open-time attribute"""

+ 

          self.set('rootdn-open-time', attr)

  

      def remove_open_time(self):

+         """Remove all rootdn-open-time attributes"""

+ 

          self.remove_all('rootdn-open-time')

  

      def get_close_time(self):

+         """Get rootdn-close-time attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-close-time')

  

      def get_close_time_formatted(self):

+         """Display rootdn-close-time attribute"""

+ 

          return self.display_attr('rootdn-close-time')

  

      def set_close_time(self, attr):

+         """Set rootdn-close-time attribute"""

+ 

          self.set('rootdn-close-time', attr)

  

      def remove_close_time(self):

+         """Remove all rootdn-close-time attributes"""

+ 

          self.remove_all('rootdn-close-time')

  

      def get_days_allowed(self):

+         """Get rootdn-days-allowed attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-days-allowed')

  

      def get_days_allowed_formatted(self):

+         """Display rootdn-days-allowed attribute"""

+ 

          return self.display_attr('rootdn-days-allowed')

  

      def set_days_allowed(self, attr):

+         """Set rootdn-days-allowed attribute"""

+ 

          self.set('rootdn-days-allowed', attr)

  

      def remove_days_allowed(self):

+         """Remove all rootdn-days-allowed attributes"""

+ 

          self.remove_all('rootdn-days-allowed')

  

      def add_allow_day(self, day):

+         """Add a value to rootdn-days-allowed attribute"""

+ 

          days = self.get_days_allowed()

          if days is None:

              days = ""
@@ -641,6 +1269,8 @@ 

              self.remove_days_allowed()

  

      def remove_allow_day(self, day):

+         """Remove a value from rootdn-days-allowed attribute"""

+ 

          days = self.get_days_allowed()

          if days is None:

              days = ""
@@ -651,69 +1281,108 @@ 

              self.remove_days_allowed()

  

      def get_allow_host(self):

+         """Get rootdn-allow-host attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-allow-host')

  

      def get_allow_host_formatted(self):

+         """Display rootdn-allow-host attribute"""

+ 

          return self.display_attr('rootdn-allow-host')

  

      def add_allow_host(self, attr):

+         """Add rootdn-allow-host attribute"""

+ 

          self.add('rootdn-allow-host', attr)

  

      def remove_allow_host(self, attr):

+         """Remove rootdn-allow-host attribute"""

+ 

          self.remove('rootdn-allow-host', attr)

  

      def remove_all_allow_host(self):

+         """Remove all rootdn-allow-host attributes"""

+ 

          self.remove_all('rootdn-allow-host')

  

      def get_deny_host(self):

+         """Get rootdn-deny-host attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-deny-host')

  

      def get_deny_host_formatted(self):

+         """Display rootdn-deny-host attribute"""

+ 

          return self.display_attr('rootdn-deny-host')

  

      def add_deny_host(self, attr):

+         """Add rootdn-deny-host attribute"""

+ 

          self.add('rootdn-deny-host', attr)

  

      def remove_deny_host(self, attr):

+         """Remove rootdn-deny-host attribute"""

+ 

          self.remove('rootdn-deny-host', attr)

  

      def remove_all_deny_host(self):

+         """Remove all rootdn-deny-host attribute"""

+ 

          self.remove_all('rootdn-deny-host')

  

      def get_allow_ip(self):

+         """Get rootdn-allow-ip attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-allow-ip')

  

      def get_allow_ip_formatted(self):

+         """Display rootdn-allow-ip attribute"""

+ 

          return self.display_attr('rootdn-allow-ip')

  

      def add_allow_ip(self, attr):

+         """Add rootdn-allow-ip attribute"""

+ 

          self.add('rootdn-allow-ip', attr)

  

      def remove_allow_ip(self, attr):

+         """Remove rootdn-allow-ip attribute"""

+ 

          self.remove('rootdn-allow-ip', attr)

  

      def remove_all_allow_ip(self):

+         """Remove all rootdn-allow-ip attribute"""

+ 

          self.remove_all('rootdn-allow-ip')

  

      def get_deny_ip(self):

+         """Remove all rootdn-deny-ip attribute"""

+ 

          return self.get_attr_val_utf8('rootdn-deny-ip')

  

      def get_deny_ip_formatted(self):

+         """Display rootdn-deny-ip attribute"""

+ 

          return self.display_attr('rootdn-deny-ip')

  

      def add_deny_ip(self, attr):

+         """Add rootdn-deny-ip attribute"""

+ 

          self.add('rootdn-deny-ip', attr)

  

      def remove_deny_ip(self, attr):

+         """Remove rootdn-deny-ip attribute"""

+ 

          self.remove('rootdn-deny-ip', attr)

  

      def remove_all_deny_ip(self):

+         """Remove all rootdn-deny-ip attribute"""

+ 

          self.remove_all('rootdn-deny-ip')

  

      @staticmethod

      def add_day_to_days(string_of_days, day):

-         """

-         Append a day in a string of comma seperated days and return the string.

+         """Append a day in a string of comma separated days and return the string.

          If day already exists in the string, return processed string.

  

          Keyword arguments:
@@ -723,6 +1392,7 @@ 

                                Tue, Wed, Thu

          day            -- a day, e.g. Mon, Tue, etc.

          """

+ 

          days = [i.strip() for i in string_of_days.split(',') if i]

  

          if not day in days:
@@ -732,8 +1402,7 @@ 

  

      @staticmethod

      def remove_day_from_days(string_of_days, day):

-         """

-         Remove a day from a string of comma seperated days and return the string.

+         """Remove a day from a string of comma separated days and return the string.

          If day does not exists in the string, return processed string.

  

          Keyword arguments:
@@ -743,6 +1412,7 @@ 

                                Tue, Wed, Thu

          day            -- a day, e.g. Mon, Tue, etc.

          """

+ 

          days = [i.strip() for i in string_of_days.split(',') if i]

  

          if day in days:
@@ -752,18 +1422,133 @@ 

  

  

  class LDBMBackendPlugin(Plugin):

+     """A single instance of ldbm database plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=ldbm database,cn=plugins,cn=config"):

          super(LDBMBackendPlugin, self).__init__(instance, dn)

  

+ 

  class ChainingBackendPlugin(Plugin):

+     """A single instance of chaining database plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=chaining database,cn=plugins,cn=config"):

          super(ChainingBackendPlugin, self).__init__(instance, dn)

  

+ 

  class AccountPolicyPlugin(Plugin):

+     """A single instance of Account Policy plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn="cn=Account Policy Plugin,cn=plugins,cn=config"):

          super(AccountPolicyPlugin, self).__init__(instance, dn)

  

+ 

+ class AccountPolicyConfig(DSLdapObject):

+     """A single instance of Account Policy Plugin config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn=None):

+         super(AccountPolicyConfig, self).__init__(instance, dn)

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn']

+         self._create_objectclasses = ['top', 'extensibleObject']

+         self._protected = False

+ 

+ 

+ class AccountPolicyConfigs(DSLdapObjects):

+     """A DSLdapObjects entity which represents Account Policy Plugin config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

+     """

+ 

+     def __init__(self, instance, basedn="cn=Account Policy Plugin,cn=plugins,cn=config"):

+         super(AccountPolicyConfigs, self).__init__(instance)

+         self._objectclasses = ['top', 'extensibleObject']

+         self._filterattrs = ['cn']

+         self._childobject = AccountPolicyConfig

+         self._basedn = basedn

+ 

+ 

+ class DNAPlugin(Plugin):

+     """A single instance of Distributed Numeric Assignment plugin entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn="cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config"):

+         super(DNAPlugin, self).__init__(instance, dn)

+ 

+ 

+ class DNAPluginConfig(DSLdapObject):

+     """A single instance of DNA Plugin config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

+     def __init__(self, instance, dn=None):

+         super(DNAPluginConfig, self).__init__(instance, dn)

+         self._rdn_attribute = 'cn'

+         self._must_attributes = ['cn']

+         self._create_objectclasses = ['top', 'dnaPluginConfig']

+         self._protected = False

+ 

+ 

+ class DNAPluginConfigs(DSLdapObjects):

+     """A DSLdapObjects entity which represents DNA Plugin config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

+     """

+ 

+     def __init__(self, instance, basedn="cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config"):

+         super(DNAPluginConfigs, self).__init__(instance)

+         self._objectclasses = ['top', 'dnaPluginConfig']

+         self._filterattrs = ['cn']

+         self._childobject = DNAPluginConfig

+         self._basedn = basedn

+ 

+ 

  class Plugins(DSLdapObjects):

+     """A DSLdapObjects entity which represents MEP config entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param basedn: Base DN for all account entries below

+     :type basedn: str

+     """

  

      # This is a map of plugin to type, so when we

      # do a get / list / create etc, we can map to the correct
@@ -793,10 +1578,10 @@ 

          else:

              return super(Plugins, self)._entry_to_instance(dn)

  

- 

-     # To maintain compat with pluginslegacy, here are some helpers.

- 

+     # To maintain compatibility with plugin's legacy, here are some helpers.

      def enable(self, name=None, plugin_dn=None):

+         """Set nsslapd-pluginEnabled to on"""

+ 

          if plugin_dn is not None:

              raise ValueError('You should swap to the new Plugin API!')

          if name is None:
@@ -805,6 +1590,8 @@ 

          plugin.enable()

  

      def disable(self, name=None, plugin_dn=None):

+         """Set nsslapd-pluginEnabled to off"""

+ 

          if plugin_dn is not None:

              raise ValueError('You should swap to the new Plugin API!')

          if name is None:

file modified
+81 -5
@@ -15,11 +15,7 @@ 

  from lib389 import Entry

  from lib389._mapped_object import DSLdapObject

  from lib389.exceptions import Error

- from lib389._constants import (

-         DEFAULT_SUFFIX, DEFAULT_BENAME, DN_EXPORT_TASK, DN_BACKUP_TASK,

-         DN_IMPORT_TASK, DN_RESTORE_TASK, DN_INDEX_TASK, DN_MBO_TASK,

-         DN_TOMB_FIXUP_TASK, DN_TASKS, DIRSRV_STATE_ONLINE

-         )

+ from lib389._constants import *

  from lib389.properties import (

          TASK_WAIT, EXPORT_REPL_INFO, MT_PROPNAME_TO_ATTRNAME, MT_SUFFIX,

          TASK_TOMB_STRIP
@@ -27,6 +23,14 @@ 

  

  

  class Task(DSLdapObject):

+     """A single instance of a task entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     :param dn: Entry DN

+     :type dn: str

+     """

+ 

      def __init__(self, instance, dn=None):

          super(Task, self).__init__(instance, dn)

          self._rdn_attribute = 'cn'
@@ -37,6 +41,7 @@ 

  

      def is_complete(self):

          """Return True if task is complete, else False."""

+ 

          self._exit_code = self.get_attr_val("nsTaskExitCode")

          if not self.exists() or self._exit_code is not None:

              return True
@@ -44,6 +49,7 @@ 

  

      def get_exit_code(self):

          """Return task's exit code if task is complete, else None."""

+ 

          if self.is_complete():

              try:

                  return int(self._exit_code)
@@ -53,6 +59,7 @@ 

  

      def wait(self, timeout=120):

          """Wait until task is complete."""

+ 

          count = 0

          while count < timeout:

              if self.is_complete():
@@ -61,16 +68,65 @@ 

              time.sleep(2)

  

      def create(self, rdn=None, properties={}, basedn=None):

+         """Create a Task entry

+ 

+         :param rdn: RDN of the new entry

+         :type rdn: str

+         :param properties: Attributes for the new entry

+         :type properties: dict

+         :param basedn: Base DN of the new entry

+         :type rdn: str

+ 

+         :returns: DSLdapObject of the created entry

+         """

+ 

          properties['cn'] = self.cn

          return super(Task, self).create(rdn, properties, basedn)

  

      @staticmethod

      def _get_task_date():

          """Return a timestamp to use in naming new task entries."""

+ 

          return datetime.now().isoformat()

  

  

+ class AutomemberRebuildMembershipTask(Task):

+     """A single instance of automember rebuild membership task entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     """

+ 

+     def __init__(self, instance, dn=None):

+         self.cn = 'automember_rebuild_' + Task._get_task_date()

+         dn = "cn=" + self.cn + "," + DN_AUTOMEMBER_REBUILD_TASK

+ 

+         super(AutomemberRebuildMembershipTask, self).__init__(instance, dn)

+         self._must_attributes.extend(['basedn', 'filter'])

+ 

+ 

+ class FixupLinkedAttributesTask(Task):

+     """A single instance of fixup linked attributes task entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     """

+ 

+     def __init__(self, instance, dn=None):

+         self.cn = 'fixup_linked_attrs_' + Task._get_task_date()

+         dn = "cn=" + self.cn + "," + DN_FIXUP_LINKED_ATTIBUTES

+ 

+         super(FixupLinkedAttributesTask, self).__init__(instance, dn)

+         self._must_attributes.extend(['basedn'])

+ 

+ 

  class MemberOfFixupTask(Task):

+     """A single instance of memberOf task entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     """

+ 

      def __init__(self, instance, dn=None):

          self.cn = 'memberOf_fixup_' + Task._get_task_date()

          dn = "cn=" + self.cn + "," + DN_MBO_TASK
@@ -80,6 +136,12 @@ 

  

  

  class USNTombstoneCleanupTask(Task):

+     """A single instance of USN tombstone cleanup task entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     """

+ 

      def __init__(self, instance, dn=None):

          self.cn = 'usn_cleanup_' + Task._get_task_date()

          dn = "cn=" + self.cn + ",cn=USN tombstone cleanup task," + DN_TASKS
@@ -92,13 +154,21 @@ 

  

          return super(USNTombstoneCleanupTask, self)._validate(rdn, properties, basedn)

  

+ 

  class SchemaReloadTask(Task):

+     """A single instance of schema reload task entry

+ 

+     :param instance: An instance

+     :type instance: lib389.DirSrv

+     """

+ 

      def __init__(self, instance, dn=None):

          self.cn = 'schema_reload_' + Task._get_task_date()

          dn = "cn=" + self.cn + ",cn=schema reload task," + DN_TASKS

  

          super(SchemaReloadTask, self).__init__(instance, dn)

  

+ 

  class AbortCleanAllRUVTask(Task):

      """Abort the Clean All Ruv task on all masters. You should

      call this from "CleanAllRUVTask.abort()" instead to provide
@@ -107,12 +177,14 @@ 

      :param instance: The instance

      :type instance: lib389.DirSrv

      """

+ 

      def __init__(self, instance, dn=None):

          self.cn = 'abortcleanallruv_' + Task._get_task_date()

          dn = "cn=" + self.cn + ",cn=abort cleanallruv," + DN_TASKS

  

          super(AbortCleanAllRUVTask, self).__init__(instance, dn)

  

+ 

  class CleanAllRUVTask(Task):

      """Create the clean all ruv task. This will be replicated through

      a topology to remove non-present ruvs. Note that if a ruv is NOT
@@ -122,6 +194,7 @@ 

      :param instance: The instance

      :type instance: lib389.DirSrv

      """

+ 

      def __init__(self, instance, dn=None):

          self.cn = 'cleanallruv_' + Task._get_task_date()

          dn = "cn=" + self.cn + ",cn=cleanallruv," + DN_TASKS
@@ -139,6 +212,7 @@ 

          :param basedn: Basedn to create the entry. Do not change this.

          :type basedn: str

          """

+ 

          # Stash the props for abort

          self._properties = properties

          return super(CleanAllRUVTask, self).create(rdn, properties, basedn)
@@ -150,6 +224,7 @@ 

          :type certify: bool

          :returns: AbortCleanAllRUVTask

          """

+ 

          if certify is True:

              self._properties['replica-certify-all'] = 'yes'

          else:
@@ -159,6 +234,7 @@ 

          abort_task.create(properties=self._properties)

          return abort_task

  

+ 

  class Tasks(object):

      proxied_methods = 'search_s getEntry'.split()

  

@@ -196,6 +196,9 @@ 

      def __iter__(self):

          return self.all_insts.values().__iter__()

  

+     def __getitem__(self, index):

+         return list(self.all_insts.values())[index]

+ 

      def pause_all_replicas(self):

          """Pause all agreements in the class instance"""

  

Description: Refactor plugins module and fix tests accordingly.
Add absent Task and Plugin objects. Add docstrings for every
fixed object.

https://pagure.io/389-ds-base/issue/49581

Reviewed by: ?

rebased onto a817f1bf747684b25d57abc01b19ab8d132b8087

6 years ago

rebased onto 82eb986c1d3b77c16b3415eecb3a7e0e18d229a1

6 years ago

rebased onto 0cd4007191ad537c6519596f853f77c0bc6ad1c8

6 years ago

1 new commit added

  • Move plugin acceptance tests to a separate module in plugins suite
6 years ago

2 new commits added

  • Move plugin acceptance tests to a separate module in plugins suite
  • Issue 49581 - Fix dynamic plugins test suite
6 years ago

rebased onto 9c7a76e27adfff02c40abdd4d49acfa187b97a14

6 years ago

Shouldn't we be doing this through a referint plugin object instead?

rebased onto 6503cb48f1235b36e417dfd7e9d0bd214ae0a6d7

6 years ago

Thanks! I fixed it. The changes in the last commit.

Great, looks good. I'll let one of the others check too? Maybe @mreynolds. I haven't run these tests so it would be good for someone else to actually give the branch a go. :)

rebased onto 7fb2df5ae12835840a8c92ef3923c1f62b596344

5 years ago

rebased onto 3c2c2101b89ca79902eadec96c9ac4d27d8a1163

5 years ago

rebased onto dc7f108

5 years ago

Pull-Request has been merged by spichugi

5 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This pull request has been cloned to Github as issue and is available here:
- https://github.com/389ds/389-ds-base/issues/2685

If you want to continue to work on the PR, please navigate to the github issue,
download the patch from the attachments and file a new pull request.

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago