#!/usr/bin/python # # Re-construct LDIF from UDM debug output # import re import sys import os.path RE_ADD = re.compile('^\d\d.\d\d.\d\d \d\d:\d\d:\d\d(?:\.\d+)? LDAP +\( ALL +\) : add dn=(.+) al=(\[.+\])$') RE_MOD = re.compile('^\d\d.\d\d.\d\d \d\d:\d\d:\d\d(?:\.\d+)? LDAP +\( ALL +\) : mod dn=(.+) ml=(\[.+\])$') RE_ASCII = re.compile('^[\x21-\x7e][\x20-\x7e]*$') def print_attribute(key, value): if value is None: pass elif isinstance(value, basestring): if value == '': pass elif RE_ASCII.match(value): print '%s: %s' % (key, value) else: value = value.encode('base64_codec').replace('\n', '') print '%s:: %s' % (key, value) elif isinstance(new, (int, long)): print '%s: %s' % (key, value) else: raise TypeError(value) def parse_add(match): print "dn: %s" % match.group(1) print "changetype: add" addlist = eval(match.group(2)) for keyvalue in addlist: try: key, old, new = keyvalue except ValueError: key, new = keyvalue old = () if isinstance(new, (list, tuple)): for value in new: print_attribute(key, value) else: print_attribute(key, new) def parse_mod(match): print "dn: %s" % match.group(1) print "changetype: modify" modlist = eval(match.group(2)) for keyvalue in modlist: key, old, new = keyvalue ol = isinstance(old, (list, tuple)) nl = isinstance(new, (list, tuple)) if ol ^ nl: raise TypeError('incompatible types') elif ol and nl: if old: print 'delete: %s' % (key,) for value in old: print_attribute(key, value) print '-' if new: print 'add: %s' % (key,) for value in new: print_attribute(key, value) print '-' else: if old: print 'delete: %s' % (key,) print_attribute(key, old) print '-' if new: print 'add: %s' % (key,) print_attribute(key, new) print '-' def parse_log(filename): f = open(filename, 'r') try: for line in f: match = RE_ADD.match(line) if match: parse_add(match) print match = RE_MOD.match(line) if match: parse_mod(match) print finally: f.close() def main(): filenames = sys.argv[1:] or ( '/var/log/univention/directory-manager-cmd.log', '/var/log/univention/directory-manager-web.log', ) for filename in filenames: if not os.path.exists(filename): continue print >>sys.stderr, 'Parsing %s...' % (filename,) try: parse_log(filename) except IOError, e: print >>sys.stderr, 'Failed: %s' % (e,) if __name__ == '__main__': main()