#!/usr/bin/env python3 from ansible.module_utils.basic import AnsibleModule from caldav import DAVClient import vobject def connect_calendar(url, user=None, password=None, verify_ssl=True): try: client = DAVClient( url, username=user, password=password, ssl_verify_cert=verify_ssl ) calendar = client.calendar(url=url) # Test-Zugriff um sicherzustellen, dass der Kalender existiert calendar.get_properties(['displayname']) return calendar except Exception as e: raise Exception(f"Kalenderverbindung fehlgeschlagen: {str(e)}") def get_event_uid_map(calendar): uid_map = {} for event in calendar.events(): try: cal = vobject.readOne(event.data) uid = cal.vevent.uid.value uid_map[uid] = event except Exception as e: continue # Fehlerhafte Events überspringen return uid_map def sync_calendars(source_cal, target_cal): src_events = get_event_uid_map(source_cal) tgt_events = get_event_uid_map(target_cal) changed = False added, updated, removed = [], [], [] # Neue/aktualisierte Events for uid, src_event in src_events.items(): tgt_event = tgt_events.get(uid) src_data = src_event.data if not tgt_event: target_cal.add_event(src_data) added.append(uid) changed = True elif src_data != tgt_event.data: tgt_event.data = src_data tgt_event.save() updated.append(uid) changed = True # Entfernte Events löschen for uid in set(tgt_events.keys()) - set(src_events.keys()): tgt_events[uid].delete() removed.append(uid) changed = True return changed, added, updated, removed def run_module(): module_args = dict( source_url=dict(type='str', required=True), source_user=dict(type='str', required=False, default=None), source_password=dict(type='str', required=False, no_log=True, default=None), target_url=dict(type='str', required=True), target_user=dict(type='str', required=False, default=None), target_password=dict(type='str', required=False, no_log=True, default=None), verify_ssl=dict(type='bool', required=False, default=True) ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=False ) result = dict( changed=False, added=[], updated=[], removed=[] ) try: # Kalender verbinden source_cal = connect_calendar( url=module.params['source_url'], user=module.params['source_user'], password=module.params['source_password'], verify_ssl=module.params['verify_ssl'] ) target_cal = connect_calendar( url=module.params['target_url'], user=module.params['target_user'], password=module.params['target_password'], verify_ssl=module.params['verify_ssl'] ) # Synchronisation durchführen changed, added, updated, removed = sync_calendars(source_cal, target_cal) result.update({ 'changed': changed, 'added': added, 'updated': updated, 'removed': removed, 'msg': f"Synchronisiert: +{len(added)}/~{len(updated)}/-{len(removed)}" }) except Exception as e: module.fail_json(msg=f"Fehler bei der Synchronisation: {str(e)}", **result) module.exit_json(**result) if __name__ == '__main__': run_module()