From 65c89cc711331e5ae97f95b1f39190be1e9fdc3c Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Oct 15 2015 16:37:52 +0000 Subject: Add method to read changes from LDIF modifications_from_ldif will read LDIF file and changes in LDIF will be cached until parse() is called. After calling parse() method changes will be applied into destination LDIF. Only changetype modify is supported, the default operation is add. https://fedorahosted.org/freeipa/ticket/4949 Also fixes: https://fedorahosted.org/freeipa/ticket/4048 https://fedorahosted.org/freeipa/ticket/1930 Reviewed-By: Martin Babinsky --- diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index 8e9e43d..1d3551f 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -1280,6 +1280,46 @@ class ModifyLDIF(ldif.LDIFParser): self.remove_value(dn, attr) self.add_value(dn, attr, values) + def modifications_from_ldif(self, ldif_file): + """ + Parse ldif file. Default operation is add, only changetypes "add" + and "modify" are supported. + :param ldif_file: an opened file for read + :raises: ValueError + """ + parser = ldif.LDIFRecordList(ldif_file) + parser.parse() + + last_dn = None + for dn, entry in parser.all_records: + if dn is None: + # ldif parser return None, if records belong to previous DN + dn = last_dn + else: + last_dn = dn + + if "replace" in entry: + for attr in entry["replace"]: + try: + self.replace_value(dn, attr, entry[attr]) + except KeyError: + raise ValueError("replace: {dn}, {attr}: values are " + "missing".format(dn=dn, attr=attr)) + elif "delete" in entry: + for attr in entry["delete"]: + self.remove_value(dn, attr, entry.get(attr, None)) + elif "add" in entry: + for attr in entry["add"]: + try: + self.replace_value(dn, attr, entry[attr]) + except KeyError: + raise ValueError("add: {dn}, {attr}: values are " + "missing".format(dn=dn, attr=attr)) + else: + root_logger.error("Ignoring entry: %s : only modifications " + "are allowed (missing \"changetype: " + "modify\")", dn) + def handle(self, dn, entry): if dn in self.modifications: self.dn_updated.add(dn)