from ..argparse_actions import LimitedIntegerOptionAction
from ..xlate import XLATOR
-__version__ = '0.2.0'
+__version__ = '0.3.0'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
class CleanEmptyLdapGroupsApplication(BaseLdapApplication):
"""Application class for removing empty groups from LDAP."""
+ use_default_ldap_connection = False
+ use_multiple_ldap_connections = False
+ show_cmdline_ldap_timeout = True
show_simulate_option = True
show_quiet_option = False
+ default_prompt_timeout = 10
+
default_max_cycles = 20
max_max_cycles = 1000
# -------------------------------------------------------------------------
def __init__(self, appname=None, base_dir=None):
"""Initialize the CleanEmptyLdapGroupsApplication object."""
- self.use_default_ldap_connection = False
- self.use_multiple_ldap_connections = True
- self.show_cmdline_ldap_timeout = True
-
self.dns_todo = CIStringSet()
self.dns_done = CIStringSet()
self.last_nr_groups_done = 0
self._base_dn = None
self._max_cycles = self.default_max_cycles
+ self.instance = None
+ self.connect_info = None
list_oc = format_list(self.group_object_classes, do_repr=True)
list_attr = format_list(self.member_attributes, do_repr=True)
self.check_instances()
+ self.instance = self.ldap_instances[0]
+ self.connect_info = self.cfg.ldap_connection[self.instance]
+
# -------------------------------------------------------------------------
def check_instances(self):
"""Check given instances for admin and read/write access."""
LOG.debug(_('Searching for empty groups ...'))
- inst = self.ldap_instances[0]
- self.get_empty_groups(inst)
+ i = 0
+ while True:
+ i += 1
+ self.get_empty_groups()
+ if not len(self.dns_todo):
+ LOG.info(_('No more empty groups left for removing.'))
+ break
+ self.empty_line()
+ msg = _('Lap {} on searching for empty groups to remove.').format(i)
+ LOG.info(msg)
+ self.remove_empty_groups()
# -------------------------------------------------------------------------
- def get_empty_groups(self, inst):
+ def get_empty_groups(self):
"""Retrieve all LDAP groups without members."""
self.dns_todo = CIStringSet()
# LOG.debug('LDAP filter: ' + ldap_filter)
dns = self.get_all_entry_dns(
- inst=inst, ldap_filter=ldap_filter, base_dn=self.base_dn, no_complain=True)
+ inst=self.instance, ldap_filter=ldap_filter, base_dn=self.base_dn, no_complain=True)
for dn in dns:
if dn not in self.dns_done:
self.dns_todo.add(dn)
if self.verbose > 1:
LOG.debug('Found Group-DNs:\n' + pp(self.dns_todo.as_list()))
+ # -------------------------------------------------------------------------
+ def remove_empty_groups(self):
+ """Ask for removing and remove it then."""
+ for dn in self.dns_todo:
+ self.remove_empty_group(dn)
+
+ # -------------------------------------------------------------------------
+ def remove_empty_group(self, dn):
+ """Ask for removing the given group and remove it then."""
+ self.dns_done.add(dn)
+
+ LOG.debug(_('Searching for member attributes of {!r} ...').format(dn))
+ entry = self.get_entry(dn, self.instance)
+ attributes = self.normalized_attributes(entry)
+ if self.verbose > 2:
+ LOG.debug(_('Got attributes:') + '\n' + pp(attributes))
+ member_attribs_found = False
+ for attrib in self.member_attributes:
+ if attrib in attributes and len(attributes[attrib]):
+ member_attribs_found = True
+ if self.verbose > 1:
+ LOG.debug(_('Found attribute {at!r} in group {g!r}.').format(
+ at=attrib, g=dn))
+ if member_attribs_found:
+ msg = _('Group {!r} is not empty!').format(dn)
+ LOG.warn(msg)
+ return
+
+ if self.request_for_remove(dn):
+ msg = _('Removing group {!r} ...').format(dn)
+ LOG.info(msg)
+ self.delete_entry(self.instance, dn)
+ else:
+ msg = _("Dont't removing group {!r}.").format(dn)
+ LOG.debug(msg)
+
+ # -------------------------------------------------------------------------
+ def request_for_remove(self, dn):
+ """Request from operator whther to really remove it."""
+ print()
+ msg = self.colored(_('Do you really want to remove the group {!r}').format(dn), 'CYAN')
+ msg += ' ' + _('[{yes}/{no}]?').format(
+ yes=self.colored(_('yes'), 'RED'), no=self.colored(_('No'), 'GREEN')) + ' '
+ return self.ask_for_yes_or_no(msg, default_on_empty=False)
+
# =============================================================================
if __name__ == '__main__':