From f925900a3e6c9c3ad5ade438fe5c8b702253f20e Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Thu, 15 Jun 2023 16:19:33 +0200 Subject: [PATCH] Fixing prompt timeout --- .../app/clean_empty_ldap_groups.py | 78 ++++++++++++++++--- lib/pp_admintools/app/ldap.py | 9 ++- locale/de_DE/LC_MESSAGES/pp_admintools.po | 2 +- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/lib/pp_admintools/app/clean_empty_ldap_groups.py b/lib/pp_admintools/app/clean_empty_ldap_groups.py index 14e6001..b25c3a8 100644 --- a/lib/pp_admintools/app/clean_empty_ldap_groups.py +++ b/lib/pp_admintools/app/clean_empty_ldap_groups.py @@ -30,7 +30,7 @@ from .. import pp from ..argparse_actions import LimitedIntegerOptionAction from ..xlate import XLATOR -__version__ = '0.2.0' +__version__ = '0.3.0' LOG = logging.getLogger(__name__) _ = XLATOR.gettext @@ -48,9 +48,14 @@ class CleanEmptyLdapGroupsUserError(LdapAppError): 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 @@ -61,10 +66,6 @@ class CleanEmptyLdapGroupsApplication(BaseLdapApplication): # ------------------------------------------------------------------------- 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() @@ -72,6 +73,8 @@ class CleanEmptyLdapGroupsApplication(BaseLdapApplication): 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) @@ -189,6 +192,9 @@ class CleanEmptyLdapGroupsApplication(BaseLdapApplication): 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.""" @@ -224,11 +230,20 @@ class CleanEmptyLdapGroupsApplication(BaseLdapApplication): 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() @@ -240,13 +255,58 @@ class CleanEmptyLdapGroupsApplication(BaseLdapApplication): # 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__': diff --git a/lib/pp_admintools/app/ldap.py b/lib/pp_admintools/app/ldap.py index d9255d8..dd0b544 100644 --- a/lib/pp_admintools/app/ldap.py +++ b/lib/pp_admintools/app/ldap.py @@ -45,7 +45,7 @@ from ..config.ldap import DEFAULT_TIMEOUT from ..config.ldap import LdapConfiguration, LdapConnectionInfo from ..xlate import XLATOR, format_list -__version__ = '0.11.7' +__version__ = '0.11.8' LOG = logging.getLogger(__name__) _ = XLATOR.gettext @@ -310,6 +310,7 @@ class BaseLdapApplication(BaseDPXApplication): """ res = super(BaseLdapApplication, self).as_dict(short=short) + res['default_default_ldap_instance'] = self.default_default_ldap_instance res['pattern_re_ldap_dn'] = self.pattern_re_ldap_dn res['password_file'] = self.password_file res['show_cmdline_ldap_timeout'] = self.show_cmdline_ldap_timeout @@ -463,6 +464,12 @@ class BaseLdapApplication(BaseDPXApplication): if v: self.cfg.ldap_timeout = v + if self.prompt_timeout > self.cfg.ldap_timeout: + msg = _('Limiting console timeout to {} seconds due to LDAP timeout.').format( + self.cfg.ldap_timeout) + LOG.warn(msg) + self.prompt_timeout = self.cfg.ldap_timeout + self._init_default_connection() if self.use_default_ldap_connection: diff --git a/locale/de_DE/LC_MESSAGES/pp_admintools.po b/locale/de_DE/LC_MESSAGES/pp_admintools.po index 5392876..d6a1605 100644 --- a/locale/de_DE/LC_MESSAGES/pp_admintools.po +++ b/locale/de_DE/LC_MESSAGES/pp_admintools.po @@ -434,7 +434,7 @@ msgstr "Überprüfe Attribute mit DN-Syntax von Eintrag {!r} …" #: lib/pp_admintools/app/check_ldap_dn_attributes.py:219 msgid "Got attributes:" -msgstr "Gefindene Attribute:" +msgstr "Gefundene Attribute:" #: lib/pp_admintools/app/dns_deploy_zones.py:122 msgid "Generation of the BIND9 configuration file for slave zones." -- 2.39.5