def revive(self): """Revive this object within the tree. This duplicates "as much as possible", excluding some internal attributes. """ orig_dn = self.get_attr_val_utf8('nscpEntryDN') self._log.info("Reviving %s -> %s" % (self.dn, orig_dn)) # Get all our attributes properties = self.get_all_attrs() properties.pop('nsuniqueid', None) properties.pop('modifiersname', None) properties.pop('createtimestamp', None) properties.pop('creatorsname', None) properties.pop('modifytimestamp', None) properties.pop('entryid', None) properties.pop('entrydn', None) properties.pop('parentid', None) properties.pop('nsparentuniqueid', None) properties.pop('nstombstonecsn', None) properties.pop('nscpentrydn', None) properties['objectclass'].remove(b'nsTombstone') e = Entry(orig_dn) e.update(properties) self._instance.add_ext_s(e, serverctrls=self._server_controls, clientctrls=self._client_controls)
def create(self, rdn=None, properties=None, basedn=None): assert(len(self._create_objectclasses) > 0) self._log.debug('Creating %s %s : %s' % (rdn, basedn, properties)) # Add the objectClasses to the properties (dn, valid_props) = self._validate(rdn, properties, basedn) # Check if the entry exists or not? .add_s is going to error anyway ... self._log.debug('Validated %s : %s' % (dn, valid_props)) e = Entry(dn) e.update({'objectclass': ensure_list_bytes(self._create_objectclasses)}) e.update(valid_props) # We rely on exceptions here to indicate failure to the parent. self._log.debug('Creating entry %s : %s' % (dn, e)) self._instance.add_s(e) # If it worked, we need to fix our instance dn self._dn = dn return self
def handle(self, dn, entry): """ Append single record to dictionary of all records. """ if not dn: dn = '' newentry = Entry((dn, entry)) self.dndict[normalizeDN(dn)] = newentry self.dnlist.append(newentry)
def _create(self, rdn=None, properties=None, basedn=None, ensure=False): """Internal implementation of create. This is used by ensure and create, to prevent code duplication. You should *never* call this method directly. """ assert (len(self._create_objectclasses) > 0) basedn = ensure_str(basedn) self._log.debug('Checking "%s" under %s : %s' % (rdn, basedn, properties)) # Add the objectClasses to the properties (dn, valid_props) = self._validate(rdn, properties, basedn) # Check if the entry exists or not? .add_s is going to error anyway ... self._log.debug('Validated dn %s : valid_props %s' % (dn, valid_props)) exists = False try: self._instance.search_ext_s(dn, ldap.SCOPE_BASE, self._object_filter, attrsonly=1, serverctrls=self._server_controls, clientctrls=self._client_controls) exists = True except ldap.NO_SUCH_OBJECT: pass if exists and ensure: # update properties self._log.debug('Exists %s' % dn) self._dn = dn # Now use replace_many to setup our values mods = [] for k, v in valid_props.items(): mods.append((ldap.MOD_REPLACE, k, v)) self._instance.modify_ext_s(self._dn, mods, serverctrls=self._server_controls, clientctrls=self._client_controls) elif exists and not ensure: # raise "already exists." raise ldap.ALREADY_EXISTS("Entry %s already exists" % dn) if not exists: self._log.debug('Creating %s' % dn) e = Entry(dn) e.update( {'objectclass': ensure_list_bytes(self._create_objectclasses)}) e.update(valid_props) # We rely on exceptions here to indicate failure to the parent. self._log.debug('Creating entry %s : %s' % (dn, e)) self._instance.add_ext_s(e, serverctrls=self._server_controls, clientctrls=self._client_controls) # If it worked, we need to fix our instance dn self._dn = dn return self
def _create(self, rdn=None, properties=None, basedn=None, ensure=False): """Internal implementation of create. This is used by ensure and create, to prevent code duplication. You should *never* call this method directly. """ assert(len(self._create_objectclasses) > 0) basedn = ensure_str(basedn) self._log.debug('Checking "%s" under %s : %s' % (rdn, basedn, display_log_data(properties))) # Add the objectClasses to the properties (dn, valid_props) = self._validate(rdn, properties, basedn) # Check if the entry exists or not? .add_s is going to error anyway ... self._log.debug('Validated dn {}'.format(dn)) exists = False if ensure: # If we are running in stateful ensure mode, we need to check if the object exists, and # we can see the state that it is in. try: self._instance.search_ext_s(dn, ldap.SCOPE_BASE, self._object_filter, attrsonly=1, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure') exists = True except ldap.NO_SUCH_OBJECT: pass if exists and ensure: # update properties self._log.debug('Exists %s' % dn) self._dn = dn # Now use replace_many to setup our values mods = [] for k, v in list(valid_props.items()): mods.append((ldap.MOD_REPLACE, k, v)) self._instance.modify_ext_s(self._dn, mods, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure') elif not exists: # This case is reached in two cases. One is we are in ensure mode, and we KNOW the entry # doesn't exist. # The alternate, is that we are in a non-stateful create, so we "just create" and see # what happens. I believe the technical term is "yolo create". self._log.debug('Creating %s' % dn) e = Entry(dn) e.update({'objectclass': ensure_list_bytes(self._create_objectclasses)}) e.update(valid_props) # We rely on exceptions here to indicate failure to the parent. self._instance.add_ext_s(e, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure') self._log.debug('Created entry %s : %s' % (dn, display_log_data(e.data))) # If it worked, we need to fix our instance dn for the object's self reference. Because # we may not have a self reference yet (just created), it may have changed (someone # set dn, but validate altered it). self._dn = dn else: # This case can't be reached now that we only check existance on ensure. # However, it's good to keep it for "complete" behaviour, exhausting all states. # We could highlight bugs ;) raise AssertionError("Impossible State Reached in _create") return self
def list(self, paged_search=None, paged_critical=True): """Get a list of children entries (DSLdapObject, Replica, etc.) using a base DN and objectClasses of our object (DSLdapObjects, Replicas, etc.) :param paged_search: None for no paged search, or an int of page size to use. :returns: A list of children entries """ # Filter based on the objectclasses and the basedn insts = None # This will yield and & filter for objectClass with as many terms as needed. filterstr = self._get_objectclass_filter() self._log.debug('list filter = %s' % filterstr) if type(paged_search) == int: self._log.debug('listing with paged search -> %d', paged_search) # If paged_search -> results = [] pages = 0 pctrls = [] req_pr_ctrl = SimplePagedResultsControl(paged_critical, size=paged_search, cookie='') if self._server_controls is not None: controls = [req_pr_ctrl] + self._server_controls else: controls = [req_pr_ctrl] while True: msgid = self._instance.search_ext( base=self._basedn, scope=self._scope, filterstr=filterstr, attrlist=self._list_attrlist, serverctrls=controls, clientctrls=self._client_controls, escapehatch='i am sure' ) self._log.info('Getting page %d' % (pages,)) rtype, rdata, rmsgid, rctrls = self._instance.result3(msgid, escapehatch='i am sure') results.extend(rdata) pages += 1 self._log.debug("%s" % rctrls) pctrls = [ c for c in rctrls if c.controlType == SimplePagedResultsControl.controlType] if pctrls and pctrls[0].cookie: req_pr_ctrl.cookie = pctrls[0].cookie if self._server_controls is not None: controls = [req_pr_ctrl] + self._server_controls else: controls = [req_pr_ctrl] else: break #End while # Result3 doesn't map through Entry, so we have to do it manually. results = [Entry(r) for r in results] insts = [self._entry_to_instance(dn=r.dn, entry=r) for r in results] # End paged search else: # If not paged try: results = self._instance.search_ext_s( base=self._basedn, scope=self._scope, filterstr=filterstr, attrlist=self._list_attrlist, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure' ) # def __init__(self, instance, dn=None): insts = [self._entry_to_instance(dn=r.dn, entry=r) for r in results] except ldap.NO_SUCH_OBJECT: # There are no objects to select from, se we return an empty array insts = [] return insts
def get(self, dn): ndn = normalizeDN(dn) return self.dndict.get(ndn, Entry(None))