@William Brown <[email protected]>

Thanks for the reply .

I was wondering if UserAccount can do it , why UserAccounts cant .

Anyway now i will go for 3. (best) to solve the problem.

Thanks
Anuj Borah

On Wed, Mar 27, 2019 at 5:45 AM William Brown <[email protected]> wrote:

> Hi,
>
> I have previously commented a number of times on this pattern that you
> have been using and that it is incorrect in reviews.
>
> > On 26 Mar 2019, at 13:27, Anuj Borah <[email protected]> wrote:
> >
> > Hay everyone,
> >
> > Consider bellow condition:
> >
> > users = UserAccounts(topo.standalone, f"ou=Keywords,{DEFAULT_SUFFIX}",
> rdn=None)
> > for i in [f'NONE_2_KEY,ou=Authmethod',
> >           f'EVERYDAY_KEY,ou=Dayofweek',
> >           f'TODAY_KEY,ou=Dayofweek',
> >           f'NODAY_KEY,ou=Dayofweek',
> >           f'NETSCAPEDNS_KEY,ou=DNS',
> >           f'FULLIP_KEY,ou=IP',
> >           f'NETSCAPEIP_KEY,ou=IP',
> >           f'NOIP_KEY,ou=IP',
> >           f'FULLWORKER_KEY,ou=Timeofday',
> >           f'DAYWORKER_KEY,ou=Timeofday',
> >           f'NIGHTWORKER_KEY,ou=Timeofday',
> >           f'NOWORKER_KEY,ou=Timeofday']:
> >     properties = {
> >         'uid': i,
> >         'cn': i.split(',')[0],
> >         'sn': 'user',
> >         'uidNumber': '1000',
> >         'gidNumber': '2000',
> >         'homeDirectory': '/home/' + i,
> >         'userPassword': PW_DM
> >     }
> >     users.create(properties=properties)
>
> ^ This is where the mistake happens. UserAccounts *already* knows that you
> have an rdn etc. So then you say “users.create(uid = “everyday_key,ou=….”).
>
> So it LITERALLY takes that, escapes the content (which is the cause of the
> \\2C and \\3D you see below) and put’s that into the field)
>
>
> >
> >
> > If you see the created users:
> >
> > for i in users.list(): i.dn
> > 'uid=NONE_2_KEY\\2Cou\\3DAuthmethod,ou=Keywords,dc=example,dc=com'
> > 'uid=EVERYDAY_KEY\\2Cou\\3DDayofweek,ou=Keywords,dc=example,dc=com'
> > 'uid=TODAY_KEY\\2Cou\\3DDayofweek,ou=Keywords,dc=example,dc=com'
> > 'uid=NODAY_KEY\\2Cou\\3DDayofweek,ou=Keywords,dc=example,dc=com'
> > 'uid=NETSCAPEDNS_KEY\\2Cou\\3DDNS,ou=Keywords,dc=example,dc=com'
> > 'uid=FULLIP_KEY\\2Cou\\3DIP,ou=Keywords,dc=example,dc=com'
> > 'uid=NETSCAPEIP_KEY\\2Cou\\3DIP,ou=Keywords,dc=example,dc=com'
> > 'uid=NOIP_KEY\\2Cou\\3DIP,ou=Keywords,dc=example,dc=com'
> > 'uid=FULLWORKER_KEY\\2Cou\\3DTimeofday,ou=Keywords,dc=example,dc=com'
> > 'uid=DAYWORKER_KEY\\2Cou\\3DTimeofday,ou=Keywords,dc=example,dc=com'
> > 'uid=NIGHTWORKER_KEY\\2Cou\\3DTimeofday,ou=Keywords,dc=example,dc=com'
> > 'uid=NOWORKER_KEY\\2Cou\\3DTimeofday,ou=Keywords,dc=example,dc=com'
> >
> > We can see users become useless to use for further operations.
> >
> > And consider bellow condition:
> >
> >
> > for i in [f'NONE_2_KEY,ou=Authmethod',
> >           f'EVERYDAY_KEY,ou=Dayofweek',
> >           f'TODAY_KEY,ou=Dayofweek',
> >           f'NODAY_KEY,ou=Dayofweek',
> >           f'NETSCAPEDNS_KEY,ou=DNS',
> >           f'FULLIP_KEY,ou=IP',
> >           f'NETSCAPEIP_KEY,ou=IP',
> >           f'NOIP_KEY,ou=IP',
> >           f'FULLWORKER_KEY,ou=Timeofday',
> >           f'DAYWORKER_KEY,ou=Timeofday',
> >           f'NIGHTWORKER_KEY,ou=Timeofday',
> >           f'NOWORKER_KEY,ou=Timeofday']:
> >     properties = {
> >         'uid': i,
> >         'cn': i.split(',')[0],
> >         'sn': 'user',
> >         'uidNumber': '1000',
> >         'gidNumber': '2000',
> >         'homeDirectory': '/home/' + i,
> >         'userPassword': PW_DM
> >     }
> >     users = UserAccount(topo.standalone,
> f"cn={i},ou=Keywords,{DEFAULT_SUFFIX}")
> >     users.create(properties=properties)
> >
> >
> > users = UserAccounts(topo.standalone, f"ou=Keywords,{DEFAULT_SUFFIX}",
> rdn=None)
> >
> > for i in users.list(): i.dn
> > 'cn=NONE_2_KEY,ou=Authmethod,ou=Keywords,dc=example,dc=com'
> > 'cn=EVERYDAY_KEY,ou=Dayofweek,ou=Keywords,dc=example,dc=com'
> > 'cn=TODAY_KEY,ou=Dayofweek,ou=Keywords,dc=example,dc=com'
> > 'cn=NODAY_KEY,ou=Dayofweek,ou=Keywords,dc=example,dc=com'
> > 'cn=NETSCAPEDNS_KEY,ou=DNS,ou=Keywords,dc=example,dc=com'
> > 'cn=FULLIP_KEY,ou=IP,ou=Keywords,dc=example,dc=com'
> > 'cn=NETSCAPEIP_KEY,ou=IP,ou=Keywords,dc=example,dc=com'
> > 'cn=NOIP_KEY,ou=IP,ou=Keywords,dc=example,dc=com'
> > 'cn=FULLWORKER_KEY,ou=Timeofday,ou=Keywords,dc=example,dc=com'
> > 'cn=DAYWORKER_KEY,ou=Timeofday,ou=Keywords,dc=example,dc=com'
> > 'cn=NIGHTWORKER_KEY,ou=Timeofday,ou=Keywords,dc=example,dc=com'
> > 'cn=NOWORKER_KEY,ou=Timeofday,ou=Keywords,dc=example,dc=com'
> >
> > Here users are in good shape .
>
> Here, because you do cn as i.split(,), now the cn becomes “EVERYDAY_KEY”
> and the provided basedn you have in the UserAccount initialise is now set
> to the full DN, so the create works.
>
> Basically, the mistake here is that you are iterating over a list of
> partial-dn’s and you expect lib389 to magically fix this all for you, and
> it’s behaviour is now surprising you because it’s “making safe” from your
> mistake.
>
>
> There are two main pieces of advice I would give here.
>
> First is to *stop* thinking about everything in terms of DN’s and start
> thinking about things in terms of “containers and what they hold”. When you
> do:
>
> uas = UserAccounts(basedn=DEFAULT_SUFFIX, rdn=ou=People)
>
> You are describing “Here is the set of all possible users, and where they
> exist in the servers tree”. So now that UserAccounts is setup like this you
> can do:
>
> uas.create(properties={
>     uid: ’test'
> })
>
> this will be combined to make uid=test + ou=People + DEFAULT_SUFFIX ->
> uid=test,ou=people,DEFAULT_SUFFIX.
>
> Now, when we look at your example, because you are trying to take
> shortcuts, you are including the location of the object into the cn
> parameter with things like: ‘ips,ou=ips’ ….
>
>
> There are three possible ways to handle this.
>
> 1: (okay, but not the best)
>
> Create each item bypassing UserAccounts, by loading the full dn into the
> UserAccount setup. This is done with:
>
> u = UserAccount(topo.standalone, dn=“uid=test,ou=People,dc=example,dc=com”)
> u.create(properties={
>     ….
> })
>
> Remember, UserAccount (singular) being an absolute object, can have a full
> path into the DN like this. Once you have added all these, even if you do
> say:
>
> u = UserAccount(topo.standalone,
> dn=“uid=test,ou=Container,ou=People,dc=example,dc=com”)
> …
> uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=ou=People)
> uas.list()
>
> uas.list/get will find the userAccount becaus it’s a subtree seacch,
> regardless of how many containers exist in the path.
>
>
> 2. (“good enough")
>
> Keep updating and changing your UserAccounts to account for the relative
> location change during your create:
>
> authmethod_users = UserAccounts(topo.standalone, DEFAULT_SUFFIX,
> rdn=ou=Authmethod,ou=Keywords)
> uas.create( …)
>
> ip_users = UserAccounts(topo.standalone, DEFAULT_SUFFIX,
> rdn=ou=IP,ou=Keywords)
> ip_users.create(…)
>
> So this at the very least means you keep things work in the best way
> possible, even though you need to do lots of changes to get all the weird
> rdns. You can probably solve this with some lists of tuples like:
>
> my users = [ (’name’, ‘ou=ip,ou=keywords’),
>                      ….]
>
> for (uid, rdn) in my_users:
>     us = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn)
>     us.create(properties={ ‘uid’: uid })
>
>
>
> 3. (best)
>
> Unless the test requires you to have all these crazy ou’s (and even if it
> does … fixtures per test, rather than one giant fixture per module …), then
> your users should all be in a SINGLE OU anyway. LDAP supports filtering and
> querying, which is a much more effective way of expressing constraints and
> what users you want etc.
>
> So just do:
>
> users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
>
>
> test_fixture_1
>     users.create(…)
>     fin:
>         for u in users.get():
>             u.delete()
>
> test_fixture_2
>     users.create(…)
>     …
>
>
> my_test(test_fixture_1)
>     # Now do the test thing. Apply my ACI to ou=People instead, and do the
> test, then reset in the fixture.
>
> I think you often are trying to copy-paste ACI’s as they are from past
> tests, you are trying to duplicate bad test structure from TET, and you are
> then hitting up against lib389 and wondering why it won’t work. Of course
> it won’t! Lib389 *can* allow you to do everything you want with LDAP, but
> for the common cases, lib389 is trying to guide you to do things in a
> certain, correct, and simple way. Sprawling deep tree directories are awful
> to administer and understand, where flatter structures defined by group
> memberships and filtering are far nicer.
>
> Remember: if you find you are struggling to do something, is it the API
> that’s at fault? Or the way you are approaching the problem?
>
>
> Hope that helps,
>
>
> —
> Sincerely,
>
> William Brown
>
> Senior Software Engineer, 389 Directory Server
> SUSE Labs
> _______________________________________________
> 389-devel mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
> List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
> List Archives:
> https://lists.fedoraproject.org/archives/list/[email protected]
>
_______________________________________________
389-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/[email protected]

Reply via email to