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)