def test_abort(automember_fixture, topo): """Test the abort rebuild task :id: 24763279-48ec-4c34-91b3-f681679dec3a :setup: Standalone Instance :steps: 1. Setup automember and create a bunch of users 2. Start rebuild task 3. Abort rebuild task 4. Verify rebuild task was aborted :expectedresults: 1. Success 2. Success 3. Success 4. Success """ automemberplugin = AutoMembershipPlugin(topo.standalone) # Run rebuild task task = automemberplugin.fixup(DEFAULT_SUFFIX, "objectclass=top") time.sleep(1) # Abort rebuild task automemberplugin.abort_fixup() # Wait for rebuild task to finish task.wait() # Check errors log for abort message assert topo.standalone.searchErrorsLog("task was intentionally aborted")
def automember_fixture(topo, request): # Create group groups = [] group_obj = Groups(topo.standalone, DEFAULT_SUFFIX) groups.append(group_obj.create(properties={'cn': 'testgroup'})) groups.append(group_obj.create(properties={'cn': 'testgroup2'})) groups.append(group_obj.create(properties={'cn': 'testgroup3'})) # Create test user user_accts = UserAccounts(topo.standalone, DEFAULT_SUFFIX) user = user_accts.create_test_user() # Create automember definitions and regex rules automember_prop = { 'cn': 'testgroup_definition', 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'objectclass=posixaccount', 'autoMemberDefaultGroup': groups[0].dn, 'autoMemberGroupingAttr': 'member:dn', } automembers = AutoMembershipDefinitions(topo.standalone) auto_def = automembers.create(properties=automember_prop) auto_def.add_regex_rule("regex1", groups[1].dn, include_regex=['cn=mark.*']) auto_def.add_regex_rule("regex2", groups[2].dn, include_regex=['cn=simon.*']) # Enable plugin automemberplugin = AutoMembershipPlugin(topo.standalone) automemberplugin.enable() topo.standalone.restart() return (user, groups)
def _enable_plugins(inst, group_dn): # Enable automember amp = AutoMembershipPlugin(inst) amp.enable() # Create the automember definition automembers = AutoMembershipDefinitions(inst) automember = automembers.create( properties={ 'cn': 'testgroup_definition', 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'objectclass=nsAccount', 'autoMemberDefaultGroup': group_dn, 'autoMemberGroupingAttr': 'member:dn', }) # Enable MemberOf mop = MemberOfPlugin(inst) mop.enable() # Enable referint rip = ReferentialIntegrityPlugin(inst) # We only need to enable the plugin, the default configuration is sane and # correctly coveres member as an enforced attribute. rip.enable() # Restart to make sure it's enabled and good to go. inst.restart()
def create_definition(inst, basedn, log, args): """ Create automember definition. :param name: An instance :type name: lib389.DirSrv :param groupattr: autoMemberGroupingAttr value :type groupattr: str :param defaultgroup: autoMemberDefaultGroup value :type defaultgroup: str :param scope: autoMemberScope value :type scope: str :param filter: autoMemberFilter value :type filter: str """ automember_prop = { 'cn': args.name, 'autoMemberScope': args.scope, 'autoMemberFilter': args.filter, 'autoMemberDefaultGroup': args.defaultgroup, 'autoMemberGroupingAttr': args.groupattr, } plugin = AutoMembershipPlugin(inst) plugin.enable() automembers = AutoMembershipDefinitions(inst) try: automember = automembers.create(properties=automember_prop) log.info("Automember definition created successfully!") except Exception as e: log.info("Failed to create Automember definition: {}".format(str(e))) raise e
def test_configuration(topo): """Automembership plugin and mixed in the plugin configuration :id: 45a5a8f8-e800-11e8-ab16-8c16451d917b :setup: Single Instance :steps: 1. Automembership plugin fails in a MMR setup, if data and config area mixed in the plugin configuration 2. Plugin configuration should throw proper error messages if not configured properly :expected results: 1. Should success 2. Should success """ # Configure pluginConfigArea for PLUGIN_AUTO AutoMembershipPlugin(topo.standalone).set("nsslapd-pluginConfigArea", 'cn=config') # Enable MemberOf plugin MemberOfPlugin(topo.standalone).enable() topo.standalone.restart() # Add invalid configuration, which mixes data and config area: All will fail automembers = AutoMembershipDefinitions(topo.standalone) with pytest.raises(ldap.UNWILLING_TO_PERFORM): automembers.create(properties={ 'cn': 'autouserGroups', 'autoMemberScope': f'ou=Employees,cn=config', 'autoMemberFilter': "objectclass=posixAccount", 'autoMemberDefaultGroup': [f'cn=SuffDef1,ou=autouserGroups,cn=config', f'cn=SuffDef2,ou=autouserGroups,cn=config'], 'autoMemberGroupingAttr': 'member:dn' }) # Search in error logs assert topo.standalone.ds_error_log.match('.*ERR - auto-membership-plugin - ' 'automember_parse_config_entry - The default group ' '"cn=SuffDef1,ou=autouserGroups,cn=config" ' 'can not be a child of the plugin config area "cn=config"')
def fixup(inst, basedn, log, args): plugin = AutoMembershipPlugin(inst) log.info( 'Attempting to add task entry... This will fail if Automembership plug-in is not enabled.' ) if not plugin.status(): log.error( "'%s' is disabled. Rebuild membership task can't be executed" % plugin.rdn) fixup_task = plugin.fixup(args.DN, args.filter) fixup_task.wait() exitcode = fixup_task.get_exit_code() if exitcode != 0: log.error( 'Rebuild membership task for %s has failed. Please, check logs') else: log.info('Successfully added task entry')
def test_invalid_regex(topo): """Test invalid regex is properly reportedin the error log :id: a6d89f84-ec76-4871-be96-411d051800b1 :setup: Standalone Instance :steps: 1. Setup automember 2. Add invalid regex 3. Error log reports useful message :expectedresults: 1. Success 2. Success 3. Success """ REGEX_DN = "cn=regex1,cn=testregex,cn=auto membership plugin,cn=plugins,cn=config" REGEX_VALUE = "cn=*invalid*" REGEX_ESC_VALUE = "cn=\\*invalid\\*" GROUP_DN = "cn=demo_group,ou=groups," + DEFAULT_SUFFIX AutoMembershipPlugin( topo.standalone).remove_all("nsslapd-pluginConfigArea") automemberplugin = AutoMembershipPlugin(topo.standalone) automember_prop = { 'cn': 'testRegex', 'autoMemberScope': 'ou=People,' + DEFAULT_SUFFIX, 'autoMemberFilter': 'objectclass=*', 'autoMemberDefaultGroup': GROUP_DN, 'autoMemberGroupingAttr': 'member:dn', } automember_defs = AutoMembershipDefinitions( topo.standalone, "cn=Auto Membership Plugin,cn=plugins,cn=config") automember_def = automember_defs.create(properties=automember_prop) automember_def.add_regex_rule("regex1", GROUP_DN, include_regex=[REGEX_VALUE]) automemberplugin.enable() topo.standalone.restart() # Check errors log for invalid message ERR_STR1 = "automember_parse_regex_rule - Unable to parse regex rule" ERR_STR2 = f"Skipping invalid inclusive regex rule in rule entry \"{REGEX_DN}\" \\(rule = \"{REGEX_ESC_VALUE}\"\\)" assert topo.standalone.searchErrorsLog(ERR_STR1) assert topo.standalone.searchErrorsLog(ERR_STR2)
def definition_add(inst, basedn, log, args): log = log.getChild('definition_add') plugin = AutoMembershipPlugin(inst) props = {'cn': args.DEFNAME} generic_object_add(AutoMembershipDefinition, inst, log, args, arg_to_attr_definition, basedn=plugin.dn, props=props)
def automember_fixture(topo, request): # Create group group_obj = Groups(topo.standalone, DEFAULT_SUFFIX) automem_group = group_obj.create(properties={'cn': 'testgroup'}) # Create users users = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=None) NUM_USERS = 1000 for num in range(NUM_USERS): num_ran = int(round(num)) USER_NAME = 'test%05d' % num_ran users.create( properties={ 'uid': USER_NAME, 'sn': USER_NAME, 'cn': USER_NAME, 'uidNumber': '%s' % num_ran, 'gidNumber': '%s' % num_ran, 'homeDirectory': '/home/%s' % USER_NAME, 'mail': '*****@*****.**' % USER_NAME, 'userpassword': '******' % num_ran, }) # Create automember definitions and regex rules automember_prop = { 'cn': 'testgroup_definition', 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'objectclass=posixaccount', 'autoMemberDefaultGroup': automem_group.dn, 'autoMemberGroupingAttr': 'member:dn', } automembers = AutoMembershipDefinitions(topo.standalone) auto_def = automembers.create(properties=automember_prop) auto_def.add_regex_rule("regex1", automem_group.dn, include_regex=['uid=.*']) # Enable plugin automemberplugin = AutoMembershipPlugin(topo.standalone) automemberplugin.enable() topo.standalone.restart()
def automember_fixture(topo, request): groups = Groups(topo.standalone, DEFAULT_SUFFIX) group = groups.create(properties={'cn': 'testgroup'}) automemberplugin = AutoMembershipPlugin(topo.standalone) automemberplugin.enable() topo.standalone.restart() automember_prop = { 'cn': 'testgroup_definition', 'autoMemberScope': 'ou=People,' + DEFAULT_SUFFIX, 'autoMemberFilter': 'objectclass=*', 'autoMemberDefaultGroup': group.dn, 'autoMemberGroupingAttr': 'member:dn', } automembers = AutoMembershipDefinitions(topo.standalone, "cn=Auto Membership Plugin,cn=plugins,cn=config") automember = automembers.create(properties=automember_prop) return (group, automembers, automember)
def topology(request): topology = default_topology(request) plugin = AutoMembershipPlugin(topology.standalone) if not plugin.exists(): plugin.create() # we need to restart the server after enabling the plugin plugin.enable() topology.standalone.restart() topology.logcap.flush() return topology
def enable_plugins(topology_st): topo = topology_st.standalone log.info("Enable automember plugin") plugin = AutoMembershipPlugin(topo) plugin.enable() log.info('Enable Referential Integrity plugin') plugin = ReferentialIntegrityPlugin(topo) plugin.enable() log.info('Set nsslapd-plugin-logging to on') topo.config.set(PLUGIN_LOGGING, 'ON') log.info('Restart the server') topo.restart()
def test_sync_repl_cookie_with_failure(topology, request): """Test sync_repl cookie are progressing is the right order when there is a failure in nested updates :id: e0103448-170e-4080-8f22-c34606447ce2 :setup: Standalone Instance :steps: 1.: enable retroCL 2.: configure retroCL to log nsuniqueid as targetUniqueId 3.: enable content_sync plugin 4.: enable automember 5.: create (4) groups. make group2 groupOfUniqueNames so the automember will fail to add 'member' (uniqueMember expected) 6.: configure automember to provision those groups with 'member' 7.: enable and configure memberof plugin 8.: enable plugin log level 9.: restart the server 10.: create a thread dedicated to run a sync repl client 11.: Create a group that will be the only update received by sync repl client 12.: Create (9) users that will generate nested updates (automember/memberof) 13.: stop sync repl client and collect the list of cookie.change_no 14.: check that the list of cookie.change_no contains only the group 'step 11' :expectedresults: 1.: succeeds 2.: succeeds 3.: succeeds 4.: succeeds 5.: succeeds 6.: succeeds 7.: succeeds 8.: succeeds 9.: succeeds 10.: succeeds 11.: succeeds 12.: Fails (expected) 13.: succeeds 14.: succeeds """ inst = topology[0] # Enable/configure retroCL plugin = RetroChangelogPlugin(inst) plugin.disable() plugin.enable() plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin plugin = ContentSyncPlugin(inst) plugin.enable() # Enable automember plugin = AutoMembershipPlugin(inst) plugin.disable() plugin.enable() # Add the automember group groups = Groups(inst, DEFAULT_SUFFIX) group = [] for i in range(1, 5): group.append(groups.create(properties={'cn': 'group%d' % i})) # Set group2 as a groupOfUniqueNames so that automember will fail to update that group # This will trigger a failure in internal MOD and a failure to add member group[1].replace('objectclass', 'groupOfUniqueNames') # Add the automember config entry am_configs = AutoMembershipDefinitions(inst) for g in group: am_config = am_configs.create( properties={ 'cn': 'config %s' % g.get_attr_val_utf8('cn'), 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'uid=*', 'autoMemberDefaultGroup': g.dn, 'autoMemberGroupingAttr': 'member:dn' }) # Enable and configure memberof plugin plugin = MemberOfPlugin(inst) plugin.disable() plugin.enable() plugin.replace_groupattr('member') memberof_config = MemberOfSharedConfig( inst, 'cn=memberOf config,{}'.format(DEFAULT_SUFFIX)) memberof_config.create( properties={ 'cn': 'memberOf config', 'memberOfGroupAttr': 'member', 'memberOfAttr': 'memberof' }) # Enable plugin log level (usefull for debug) inst.setLogLevel(65536) inst.restart() # create a sync repl client and wait 5 seconds to be sure it is running sync_repl = Sync_persist(inst) sync_repl.start() time.sleep(5) # Add a test group just to check that sync_repl receives only one update group.append(groups.create(properties={'cn': 'group%d' % 10})) # create users, that automember/memberof will generate nested updates users = UserAccounts(inst, DEFAULT_SUFFIX) users_set = [] for i in range(1000, 1010): try: users_set.append(users.create_test_user(uid=i)) # Automember should fail to add uid=1000 in group2 assert (False) except ldap.UNWILLING_TO_PERFORM: pass # stop the server to get the sync_repl result set (exit from while loop). # Only way I found to acheive that. # and wait a bit to let sync_repl thread time to set its result before fetching it. inst.stop() time.sleep(10) cookies = sync_repl.get_result() # checking that the cookie list contains only one entry assert len(cookies) == 1 prev = 0 for cookie in cookies: log.info('Check cookie %s' % cookie) assert int(cookie) > 0 assert int(cookie) < 1000 assert int(cookie) > prev prev = int(cookie) sync_repl.join() log.info('test_sync_repl_cookie_with_failure: PASS\n') def fin(): inst.restart() for user in users_set: try: user.delete() except: pass for g in group: try: g.delete() except: pass request.addfinalizer(fin)
def test_sync_repl_cookie_add_del(topology, request): """Test sync_repl cookie are progressing is an increasing order when there add and del :id: 83e11038-6ed0-4a5b-ac77-e44887ab11e3 :setup: Standalone Instance :steps: 1.: enable retroCL 2.: configure retroCL to log nsuniqueid as targetUniqueId 3.: enable content_sync plugin 4.: enable automember 5.: create (2) groups. Few groups can help to reproduce the concurrent updates problem. 6.: configure automember to provision those groups with 'member' 7.: enable and configure memberof plugin 8.: enable plugin log level 9.: restart the server 10.: create a thread dedicated to run a sync repl client 11.: Create (3) users that will generate nested updates (automember/memberof) 12.: Delete (3) users 13.: stop sync repl client and collect the list of cookie.change_no 14.: check that cookies.change_no are in increasing order :expectedresults: 1.: succeeds 2.: succeeds 3.: succeeds 4.: succeeds 5.: succeeds 6.: succeeds 7.: succeeds 8.: succeeds 9.: succeeds 10.: succeeds 11.: succeeds 12.: succeeds 13.: succeeds 14.: succeeds """ inst = topology[0] # Enable/configure retroCL plugin = RetroChangelogPlugin(inst) plugin.disable() plugin.enable() plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin plugin = ContentSyncPlugin(inst) plugin.enable() # Enable automember plugin = AutoMembershipPlugin(inst) plugin.disable() plugin.enable() # Add the automember group groups = Groups(inst, DEFAULT_SUFFIX) group = [] for i in range(1, 3): group.append(groups.create(properties={'cn': 'group%d' % i})) # Add the automember config entry am_configs = AutoMembershipDefinitions(inst) for g in group: am_config = am_configs.create( properties={ 'cn': 'config %s' % g.get_attr_val_utf8('cn'), 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'uid=*', 'autoMemberDefaultGroup': g.dn, 'autoMemberGroupingAttr': 'member:dn' }) # Enable and configure memberof plugin plugin = MemberOfPlugin(inst) plugin.disable() plugin.enable() plugin.replace_groupattr('member') memberof_config = MemberOfSharedConfig( inst, 'cn=memberOf config,{}'.format(DEFAULT_SUFFIX)) memberof_config.create( properties={ 'cn': 'memberOf config', 'memberOfGroupAttr': 'member', 'memberOfAttr': 'memberof' }) # Enable plugin log level (usefull for debug) inst.setLogLevel(65536) inst.restart() # create a sync repl client and wait 5 seconds to be sure it is running sync_repl = Sync_persist(inst) sync_repl.start() time.sleep(5) # create users, that automember/memberof will generate nested updates users = UserAccounts(inst, DEFAULT_SUFFIX) users_set = [] for i in range(10001, 10004): users_set.append(users.create_test_user(uid=i)) time.sleep(10) # delete users, that automember/memberof will generate nested updates for user in users_set: user.delete() # stop the server to get the sync_repl result set (exit from while loop). # Only way I found to acheive that. # and wait a bit to let sync_repl thread time to set its result before fetching it. inst.stop() cookies = sync_repl.get_result() # checking that the cookie are in increasing and in an acceptable range (0..1000) assert len(cookies) > 0 prev = 0 for cookie in cookies: log.info('Check cookie %s' % cookie) assert int(cookie) > 0 assert int(cookie) < 1000 assert int(cookie) > prev prev = int(cookie) sync_repl.join() log.info('test_sync_repl_cookie_add_del: PASS\n') def fin(): inst.restart() for g in group: try: g.delete() except: pass request.addfinalizer(fin) return
def init_sync_repl_plugins(topology, request): """Prepare test environment (retroCL/sync_repl/ automember/memberof) and cleanup at the end of the test 1.: enable retroCL 2.: configure retroCL to log nsuniqueid as targetUniqueId 3.: enable content_sync plugin 4.: enable automember 5.: create (2) groups. Few groups can help to reproduce the concurrent updates problem. 6.: configure automember to provision those groups with 'member' 7.: enable and configure memberof plugin 8.: enable plugin log level 9.: restart the server """ inst = topology[0] inst.restart() # Enable/configure retroCL plugin = RetroChangelogPlugin(inst) plugin.disable() plugin.enable() plugin.set('nsslapd-attribute', 'nsuniqueid:targetuniqueid') # Enable sync plugin plugin = ContentSyncPlugin(inst) plugin.enable() # Enable automember plugin = AutoMembershipPlugin(inst) plugin.disable() plugin.enable() # Add the automember group groups = Groups(inst, DEFAULT_SUFFIX) group = [] for i in range(1, 5): group.append(groups.create(properties={'cn': 'group%d' % i})) # Add the automember config entry am_configs = AutoMembershipDefinitions(inst) am_configs_cleanup = [] for g in group: am_config = am_configs.create( properties={ 'cn': 'config %s' % g.get_attr_val_utf8('cn'), 'autoMemberScope': DEFAULT_SUFFIX, 'autoMemberFilter': 'uid=*', 'autoMemberDefaultGroup': g.dn, 'autoMemberGroupingAttr': 'member:dn' }) am_configs_cleanup.append(am_config) # Enable and configure memberof plugin plugin = MemberOfPlugin(inst) plugin.disable() plugin.enable() plugin.replace_groupattr('member') memberof_config = MemberOfSharedConfig( inst, 'cn=memberOf config,{}'.format(DEFAULT_SUFFIX)) try: memberof_config.create( properties={ 'cn': 'memberOf config', 'memberOfGroupAttr': 'member', 'memberOfAttr': 'memberof' }) except ldap.ALREADY_EXISTS: pass # Enable plugin log level (usefull for debug) inst.setLogLevel(65536) inst.restart() def fin(): inst.restart() for am_config in am_configs_cleanup: am_config.delete() for g in group: try: g.delete() except: pass request.addfinalizer(fin)
def _create_entries(topo_m4): """ Will act as module .Will set up required user/entries for the test cases. """ for instance in [ topo_m4.ms['supplier1'], topo_m4.ms['supplier2'], topo_m4.ms['supplier3'], topo_m4.ms['supplier4'] ]: assert instance.status() for org in ['autouserGroups', 'Employees', 'TaskEmployees']: OrganizationalUnits(topo_m4.ms['supplier1'], DEFAULT_SUFFIX).create(properties={'ou': org}) Backends(topo_m4.ms['supplier1']).create( properties={ 'cn': 'SubAutoMembers', 'nsslapd-suffix': SUBSUFFIX, 'nsslapd-CACHE_SIZE': CACHE_SIZE, 'nsslapd-CACHEMEM_SIZE': CACHEMEM_SIZE }) Domain(topo_m4.ms['supplier1'], SUBSUFFIX).create( properties={ 'dc': SUBSUFFIX.split('=')[1].split(',')[0], 'aci': [ f'(targetattr="userPassword")(version 3.0;aci "Replication Manager Access";' f'allow (write,compare) userdn="ldap:///{REPMANDN},cn=config";)', f'(target ="ldap:///{SUBSUFFIX}")(targetattr !="cn||sn||uid")(version 3.0;' f'acl "Group Permission";allow (write)(groupdn = "ldap:///cn=GroupMgr,{SUBSUFFIX}");)', f'(target ="ldap:///{SUBSUFFIX}")(targetattr !="userPassword")(version 3.0;' f'acl "Anonym-read access"; allow (read,search,compare) (userdn="ldap:///anyone");)' ] }) for suff, grp in [ (DEFAULT_SUFFIX, 'SubDef1'), (DEFAULT_SUFFIX, 'SubDef2'), (DEFAULT_SUFFIX, 'SubDef3'), (DEFAULT_SUFFIX, 'SubDef4'), (DEFAULT_SUFFIX, 'SubDef5'), (DEFAULT_SUFFIX, 'Employees'), (DEFAULT_SUFFIX, 'NewEmployees'), (DEFAULT_SUFFIX, 'testuserGroups'), (SUBSUFFIX, 'subsuffGroups'), (SUBSUFFIX, 'Employees'), (DEFAULT_SUFFIX, 'autoMembersPlugin'), (DEFAULT_SUFFIX, 'replsubGroups'), ("cn=replsubGroups,{}".format(DEFAULT_SUFFIX), 'Managers'), ("cn=replsubGroups,{}".format(DEFAULT_SUFFIX), 'Contractors'), ("cn=replsubGroups,{}".format(DEFAULT_SUFFIX), 'Interns'), ("cn=replsubGroups,{}".format(DEFAULT_SUFFIX), 'Visitors'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'SuffDef1'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'SuffDef2'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'SuffDef3'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'SuffDef4'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'SuffDef5'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'Contractors'), ("ou=autouserGroups,{}".format(DEFAULT_SUFFIX), 'Managers'), ("CN=testuserGroups,{}".format(DEFAULT_SUFFIX), 'TestDef1'), ("CN=testuserGroups,{}".format(DEFAULT_SUFFIX), 'TestDef2'), ("CN=testuserGroups,{}".format(DEFAULT_SUFFIX), 'TestDef3'), ("CN=testuserGroups,{}".format(DEFAULT_SUFFIX), 'TestDef4'), ("CN=testuserGroups,{}".format(DEFAULT_SUFFIX), 'TestDef5') ]: Groups(topo_m4.ms['supplier1'], suff, rdn=None).create(properties={'cn': grp}) for suff, grp, gid in [ (SUBSUFFIX, 'SubDef1', '111'), (SUBSUFFIX, 'SubDef2', '222'), (SUBSUFFIX, 'SubDef3', '333'), (SUBSUFFIX, 'SubDef4', '444'), (SUBSUFFIX, 'SubDef5', '555'), ('cn=subsuffGroups,{}'.format(SUBSUFFIX), 'Managers', '666'), ('cn=subsuffGroups,{}'.format(SUBSUFFIX), 'Contractors', '999') ]: PosixGroups(topo_m4.ms['supplier1'], suff, rdn=None).create(properties={ 'cn': grp, 'gidNumber': gid }) for supplier in [ topo_m4.ms['supplier1'], topo_m4.ms['supplier2'], topo_m4.ms['supplier3'], topo_m4.ms['supplier4'] ]: AutoMembershipPlugin(supplier).add( "nsslapd-pluginConfigArea", "cn=autoMembersPlugin,{}".format(DEFAULT_SUFFIX)) MemberOfPlugin(supplier).enable() automembers = AutoMembershipDefinitions( topo_m4.ms['supplier1'], f'cn=autoMembersPlugin,{DEFAULT_SUFFIX}') automember1 = automembers.create( properties={ 'cn': 'replsubGroups', 'autoMemberScope': f'ou=Employees,{DEFAULT_SUFFIX}', 'autoMemberFilter': "objectclass=posixAccount", 'autoMemberDefaultGroup': [ f'cn=SubDef1,{DEFAULT_SUFFIX}', f'cn=SubDef2,{DEFAULT_SUFFIX}', f'cn=SubDef3,{DEFAULT_SUFFIX}', f'cn=SubDef4,{DEFAULT_SUFFIX}', f'cn=SubDef5,{DEFAULT_SUFFIX}' ], 'autoMemberGroupingAttr': 'member:dn' }) automembers = AutoMembershipRegexRules(topo_m4.ms['supplier1'], automember1.dn) automembers.create( properties={ 'cn': 'Managers', 'description': f'Group placement for Managers', 'autoMemberTargetGroup': [f'cn=Managers,cn=replsubGroups,{DEFAULT_SUFFIX}'], 'autoMemberInclusiveRegex': [ 'uidNumber=^5..5$', 'gidNumber=^[1-4]..3$', 'nsAdminGroupName=^Manager$|^Supervisor$' ], "autoMemberExclusiveRegex": [ 'uidNumber=^999$', 'gidNumber=^[6-8].0$', 'nsAdminGroupName=^Junior$' ], }) automembers.create( properties={ 'cn': 'Contractors', 'description': f'Group placement for Contractors', 'autoMemberTargetGroup': [f'cn=Contractors,cn=replsubGroups,{DEFAULT_SUFFIX}'], 'autoMemberInclusiveRegex': [ 'uidNumber=^8..5$', 'gidNumber=^[5-9]..3$', 'nsAdminGroupName=^Contract|^Temporary$' ], "autoMemberExclusiveRegex": [ 'uidNumber=^[1,3,8]99$', 'gidNumber=^[2-4]00$', 'nsAdminGroupName=^Employee$' ], }) automembers.create( properties={ 'cn': 'Interns', 'description': f'Group placement for Interns', 'autoMemberTargetGroup': [f'cn=Interns,cn=replsubGroups,{DEFAULT_SUFFIX}'], 'autoMemberInclusiveRegex': [ 'uidNumber=^1..6$', 'gidNumber=^[1-9]..3$', 'nsAdminGroupName=^Interns$|^Trainees$' ], "autoMemberExclusiveRegex": [ 'uidNumber=^[1-9]99$', 'gidNumber=^[1-9]00$', 'nsAdminGroupName=^Students$' ], }) automembers.create( properties={ 'cn': 'Visitors', 'description': f'Group placement for Visitors', 'autoMemberTargetGroup': [f'cn=Visitors,cn=replsubGroups,{DEFAULT_SUFFIX}'], 'autoMemberInclusiveRegex': [ 'uidNumber=^1..6$', 'gidNumber=^[1-5]6.3$', 'nsAdminGroupName=^Visitors$' ], "autoMemberExclusiveRegex": [ 'uidNumber=^[7-9]99$', 'gidNumber=^[7-9]00$', 'nsAdminGroupName=^Inter' ], }) for instance in [ topo_m4.ms['supplier1'], topo_m4.ms['supplier2'], topo_m4.ms['supplier3'], topo_m4.ms['supplier4'] ]: instance.restart()
def test_mods(automember_fixture, topo): """Modify the user so that it is added to the various automember groups :id: 28a2b070-7f16-4905-8831-c80fa6441693 :setup: Standalone Instance :steps: 1. Update user that should add it to group[0] 2. Update user that should add it to group[1] 3. Update user that should add it to group[2] 4. Update user that should add it to group[0] 5. Test rebuild task correctly moves user to group[1] :expectedresults: 1. Success 2. Success 3. Success 4. Success 5. Success """ (user, groups) = automember_fixture # Update user which should go into group[0] user.replace('cn', 'whatever') groups[0].is_member(user.dn) if groups[1].is_member(user.dn): assert False if groups[2].is_member(user.dn): assert False # Update user0 which should go into group[1] user.replace('cn', 'mark') groups[1].is_member(user.dn) if groups[0].is_member(user.dn): assert False if groups[2].is_member(user.dn): assert False # Update user which should go into group[2] user.replace('cn', 'simon') groups[2].is_member(user.dn) if groups[0].is_member(user.dn): assert False if groups[1].is_member(user.dn): assert False # Update user which should go back into group[0] (full circle) user.replace('cn', 'whatever') groups[0].is_member(user.dn) if groups[1].is_member(user.dn): assert False if groups[2].is_member(user.dn): assert False # # Test rebuild task. First disable plugin # automemberplugin = AutoMembershipPlugin(topo.standalone) automemberplugin.disable() topo.standalone.restart() # Make change that would move the entry from group[0] to group[1] user.replace('cn', 'mark') # Enable plugin automemberplugin.enable() topo.standalone.restart() # Run rebuild task task = automemberplugin.fixup(DEFAULT_SUFFIX, "objectclass=posixaccount") task.wait() # Test membership groups[1].is_member(user.dn) if groups[0].is_member(user.dn): assert False if groups[2].is_member(user.dn): assert False # Success log.info("Test PASSED")