#18 New DSLdapObject api requires documentation
Closed: Fixed Opened by firstyear.

Create pydoc compatible documentation for the new API to aid in it's adoption. Worked examples are a good idea too.


Metadata Update from @firstyear:
- Issue assigned to firstyear

Metadata Update from @spichugi:
- Issue assigned to spichugi (was: firstyear)

The part I have in my guide and I plan to refactor docstrings according to this workflow:

DSLdapObjects and DSLdapObject are inherited by other objects like Replicas, Tasks, MappingTrees, etc.

DSLdapObjects represent the next idea: "Everything is an instance of something that exists in this way", i.e. we unite LDAP entries by some set of parameters with the object. For instance, UserAccounts(standalone, DEFAULT_SUFFIX) represents all user accounts under DEFAULT_SUFFIX.

With it, we can list, create and get entries.

# We can define the new object
users = UserAccounts(standalone, DEFAULT_SUFFIX)
backends = Backends(standalone)
# List - return a list object with instances of DSLdapObject in it 
for backend in backends.list():
    # here, backend is an instance of DSLdapObject
    print(backend.display())
# Create one DSLdapObject
user_properties = {
    'uid': 'testuser',
    'cn': 'testuser',
    'sn': 'user',
    'uidNumber': '1000',
    'gidNumber': '2000',
    'homeDirectory': '/home/testuser'
}
# Other parameters are carried out - it takes 'rdn' from properties, and 'basedn' from parent class
users.create(properties=user_properties)
# Get one DSLdapObject
# with 'selector'
user = users.get('testuser')
# or with 'dn'
user = users.get(dn='uid=testuser,{}'.format(DEFAULT_SUFFIX))

After obtaining the entry we can start to work with DSLdapObject instance.

# Bind
# If the account can be bound to, this will attempt to do so.
# We don't check for exceptions, just pass them back!
user.bind('password')
# Delete
user.delete()
# Get LDAP entry object ('Entry' object)
user_entry = user.raw_entry()
# The same as previous, but represent it as a string LDIF
user_ldif = user.display()
# Get attrs
user_all_attrs = user.get_all_attrs() # real attributes + operational attributes
user_attr_val = user.get_attr_val('homeDirectory')
user_attr_vals = user.get_attr_vals('homeDirectory')
user_attrs_vals = user.get_attrs_vals(['homeDirectory', 'uidNumber', 'gidNumber'])
user_home = user.display_attr('homeDirectory') # Get all values of given attribute - 'attr: value\n'
# Get dn
user_dn = user.dn()
# Get rdn
user_rdn = user.rdn()
# Check if some attr, or some attr / value exist on the entry.
assert(user.present(attr='homeDirectory'))
assert(user.present(attr='homeDirectory', value='/home/testuser'))
# Set - more general method for 'modify_s' operations (default action=ldap.MOD_REPLACE)
user.set('homeDirectory', '/home/testuser_new')
# Replace
user.replace('homeDirectory', '/home/testuser')
# Remove
user.remove('homeDirectory', '/home/testuser')
user.remove_all('homeDirectory')
# Multiple modification - the same as set, but accepts list of tuples of [(action, key, value),]
mods = [('homeDirectory', '/home/testuser_new', ldap.MOD_DELETE),
                ('uidNumber', '3000', ldap.MOD_REPLACE),
                ('gidNumber', '3000', ldap.MOD_REPLACE)]
user.apply_mods(mods):
# Compare if two RDN objects have same attributes and values.
# This comparison is a loose comparison, not a strict one i.e. "this object *is* this other object"
# It will just check if the attributes are same.
# 'nsUniqueId' attribute is not checked intentionally because we want to compare arbitrary objects
# i.e they may have different 'nsUniqueId' but same attributes.
# Example:
#   cn=user1,ou=a
#   cn=user1,ou=b
# Comparision of these two objects should result in same, even though their 'nsUniqueId' attribute differs.
# This function returns 'True' if objects have same attributes else returns 'False'
assert(UserAccount.compare(testuser1, testuser2) == False)

Looks good - see my comments on the other doc ticket. :)

It is documented now.

Metadata Update from @spichugi:
- Custom field Origin adjusted to None
- Custom field Review Status adjusted to None

Metadata Update from @spichugi:
- Issue close_status updated to: Fixed
- Issue status updated to: Closed (was: Open)

Metadata