diff --git a/cbutil/kadi_helper.py b/cbutil/kadi_helper.py
index e4e71350c024055228b736fcc2e3a5097f7b5ec4..9fc66a4665df42aa21e4863183cf24ef4bf47ae3 100644
--- a/cbutil/kadi_helper.py
+++ b/cbutil/kadi_helper.py
@@ -6,6 +6,8 @@ from kadi_apy import KadiManager
 
 import logging
 import builtins
+import re
+from typing import Iterable
 logger = logging.getLogger(__file__)
 
 
@@ -72,3 +74,67 @@ def create_kadi_record(manager: KadiManager, identifier: str, **kwargs):
                           create=True,
                           **kwargs,
                           )
+
+
+def get_all_collection_ids(manager: KadiManager, parent_collection_id: int) -> Iterable[int]:
+    meta_collection = manager.collection(id=parent_collection_id, create=False)
+    page = 1
+    while True:
+        collections = meta_collection.get_collections(page=page)
+        collection_json = collections.json()
+        for item in collection_json["items"]:
+            yield item["id"]
+        if page <= collection_json["_pagination"]["total_pages"]:
+            page += 1
+        else:
+            break
+
+
+def get_all_record_ids(manager: KadiManager, collection_id: int) -> Iterable[int]:
+    meta_collection = manager.collection(id=collection_id, create=False)
+    page = 1
+    while True:
+        collections = meta_collection.get_records(page=page)
+        collection_json = collections.json()
+        for item in collection_json["items"]:
+            yield item["id"]
+        if page <= collection_json["_pagination"]["total_pages"]:
+            page += 1
+        else:
+            break
+
+
+def add_user_to_collection(manager: KadiManager, collection_id: int, user_id: int, *, role="admin"):
+    collection = manager.collection(id=collection_id, create=False)
+    collection.add_user(user_id=user_id, role_name=role)
+
+
+def get_records(manager: KadiManager, record_ids: Iterable[int]):
+    for r in record_ids:
+        yield manager.record(id=r, create=False)
+
+
+def filter_record_after_title(records, pattern):
+    for r in records:
+        if re.match(pattern, r.meta["title"]):
+            yield r
+
+
+def connect_logs(records):
+    meta_logs = filter_record_after_title(records, r"fe2ti.*\.o[0-9]+")
+    for meta_log in meta_logs:
+        name_start = meta_log.meta["title"].split('.')[0]
+        for pl in filter_record_after_title(records, f"{name_start}_.*"):
+            logger.info(f"Linking {meta_log.id} with {pl.id}")
+            logger.debug(f"Linking {meta_log.meta['title']} with {pl.meta['title']}")
+            pl.link_record(meta_log.id,  "application call")
+
+
+def connect_likwid_files(records):
+    programm_logs = filter_record_after_title(records, "fe2ti.*_[6-8]_1e-[4,6,8]")
+    for p_log in programm_logs:
+        likwid_log = list(filter_record_after_title(records, f"likwid_MEM_DP_{p_log.meta['title']}"))
+        assert len(likwid_log) == 1, "found more than one likwid log"
+        logger.info(f"Linking {p_log.id} with {likwid_log[0].id}")
+        logger.info(f"Linking {p_log.meta['title']} with {likwid_log[0].meta['title']}")
+        likwid_log[0].link_record(p_log.id, "hardware performance counter")