# Standard modules
import logging
import copy
+import re
+import sys
# Third party modules
from fb_tools.xlate import format_list
from .ldap import LdapAppError, FatalLDAPError
from .ldap import BaseLdapApplication
-__version__ = '0.1.0'
+__version__ = '0.2.0'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
class EvalDuplicateAttribsApplication(BaseLdapApplication):
"""Application class for evaluating duplicate attributes, which should be unique, in LDAP."""
+ use_default_ldap_connection = False
+ use_multiple_ldap_connections = False
+ show_cmdline_ldap_timeout = True
+ apply_default_ldap_instance_if_not_given = True
+
default_uniq_attributes = ['uid', 'uidNumber', 'mail']
- default_dpendend_uniq_attribs = {
+ default_dependend_uniq_attribs = {
'gidNumber': 'objectClass=posixGroup',
}
def __init__(self, appname=None, base_dir=None):
"""Constructor."""
self.uniq_attributes = copy.copy(self.default_uniq_attributes)
- self.dpendend_uniq_attribs = copy.copy(self.default_dpendend_uniq_attribs)
+ self.dependend_uniq_attribs = copy.copy(self.default_dependend_uniq_attribs)
self.result = {}
desc = _(
) + ' ' + format_list(self.default_uniq_attributes, do_repr=True),
)
+ eval_group.add_argument(
+ '--dependend-attribs', nargs='*', dest='dependend_attribs', metavar=_('ATTRIBUTE'),
+ help=_(
+ "All attributes, where their uniqueness depends on an additional "
+ "LDAP filter. For instance, dhe attribute 'gidNumber' should be unique for "
+ "all entries, which are using the objectClass 'posixGroup'. The value "
+ "for this argument should be in the form: 'ATTRIBUTE: \"FILTER\"'. For the latter "
+ "example this would be: 'gidNumber: \"objectClass=posixGroup\"' (which "
+ "is also the default for this option). Please note, that this filter will "
+ "be wrapped by parenthesis.")
+ )
+
super(EvalDuplicateAttribsApplication, self).init_arg_parser()
# -------------------------------------------------------------------------
super(EvalDuplicateAttribsApplication, self)._verify_instances(
is_admin=False, readonly=True)
+ # -------------------------------------------------------------------------
+ def post_init(self):
+ """
+ Method to execute before calling run().
+ """
+
+ super(EvalDuplicateAttribsApplication, self).post_init()
+
+ pat_dep_attribs = r'^(?P<attrib>[a-z](?:[a-z0-9-]*[a-z0-9])?):\s*'
+ pat_dep_attribs += r'(?P<quote>[\'"])?(?P<filter>.+)(?P=quote)?$'
+ if self.verbose > 2:
+ LOG.debug("Pattern for verifying dependend unique attributes: {!r}".format(
+ pat_dep_attribs))
+ re_dep_attribs = re.compile(pat_dep_attribs, re.IGNORECASE)
+
+ given_unique_attribs = getattr(self.args, 'uniq_attribs', [])
+ if given_unique_attribs:
+ self.uniq_attributes = given_unique_attribs
+
+ dependend_attribs = getattr(self.args, 'dependend_attribs', [])
+ wrong_attribs = False
+ if dependend_attribs:
+ dep_attribs = {}
+ for attrib in dependend_attribs:
+ m = re_dep_attribs.match(attrib)
+ if m:
+ attr_name = m.group('attrib')
+ attr_filter = m.group('filter')
+ dep_attribs[attr_name] = attr_filter
+ else:
+ wrong_attribs = True
+ msg = _("Wrong definition if a filter dependend unique attribute given:")
+ msg += ' {!r}'.format(attrib)
+ LOG.error(msg)
+ if wrong_attribs:
+ self.empty_line()
+ self.arg_parser.print_usage(sys.stdout)
+ self.exit(1)
+ self.dependend_uniq_attribs = dep_attribs
+
# -------------------------------------------------------------------------
def _run(self):
LOG.info("And here we go ...")
+ for attrib in self.uniq_attributes:
+ self.empty_line()
+ msg1 = _("Checking for globally unique attribute '")
+ msg2 = _("' ...")
+ msg_oc = msg1 + attrib + msg2
+ msg_c = (
+ self.colored(msg1, 'cyan') + self.colored(attrib, 'GREEN') + self.colored(
+ msg2, 'cyan'))
+ print(msg_c)
+ self.line(len(msg_oc))
+
+ for attrib in self.dependend_uniq_attribs.keys():
+ flter = self.dependend_uniq_attribs[attrib]
+ self.empty_line()
+ msg1 = _("Checking for dependend unique attribute '")
+ msg2 = _("' ...")
+ msg_oc = msg1 + attrib + msg2
+ msg_c = (
+ self.colored(msg1, 'cyan') + self.colored(attrib, 'GREEN') + self.colored(
+ msg2, 'cyan'))
+ print(msg_c)
+ self.line(len(msg_oc))
+ print(_('Used filter:') + ' ' + flter)
+
+ self.empty_line()
# =============================================================================
if __name__ == "__main__":