Zurück zur Startseite

Hybride Codesuche in GitLab über 100+ Projekte

Hybrides Skript beschleunigt String-Suche über 100+ GitLab-Projekte: API-Suche für Code und Dokumentation, rekursive Traversierung für Configs. Parallele Verarbeitung mit ThreadPoolExecutor. Detaillierter Code und Berichte für technische Audits.

Schnelle Suche über 100+ GitLab-Repositories: hybride API+Deep
Advertisement 728x90

Hybride GitLab-Repository-Suche: API und tiefgehende Konfigurationsprüfung

Mit der wachsenden Anzahl von Projekten in GitLab wird die Suche nach bestimmten Zeichenketten in Code, YAML-, JSON- und .env-Dateien zur Herausforderung. Die Standard-UI- und API-Suche funktioniert schnell für Code, übersieht aber Konfigurationen. Die Lösung ist ein hybrides Python-Skript mit python-gitlab: API-Suche für Code und rekursive Durchquerung für Konfigurationen. Die Suchzeit über 100+ Projekte wurde auf Minuten reduziert.

Analyse alternativer Ansätze

Vor der Entwicklung haben wir bestehende Methoden bewertet. Keine deckte die Aufgabe vollständig ohne Kompromisse ab.

| Ansatz | Vorteile | Nachteile |

Google AdInline article slot

|--------|-------|--------|

| GitLab UI | Schneller Start | Manuell für 100+ Projekte, schwach bei Konfigurationen |

| Lokales grep/ripgrep | Volle Kontrolle | Klonen aller Repositories dauert Stunden |

Google AdInline article slot

| GitLab API-Suche | Remote verfügbar | Übersieht YAML/JSON/env |

| Sourcegraph | Leistungsstarke Indizierung | Erfordert Infrastrukturbereitstellung |

Der hybride Crawler erwies sich als optimal: Nutzt API-Stärken und fügt Durchquerung für Schwachstellen ohne externe Abhängigkeiten hinzu.

Google AdInline article slot

Unterschiede bei der Suche nach Dateitypen

GitLab indiziert Code und Dokumentation zuverlässig, aber Konfigurationen bleiben oft außerhalb der Suche.

  • Code (.py, .js, .go, .ts): API-Suche — Indizierung deckt vollständig ab.
  • Dokumentation (.md, .txt): API-Suche — ausreichende Geschwindigkeit und Genauigkeit.
  • Konfigurationen (.yml, .yaml, .json, .env): Tiefensuche — rekursiver Baum + Inhaltsabruf.
  • Binärdateien: Ausgeschlossen, um Ressourcen zu sparen.

Logik: Delegiere Aufgaben an das Tool für starke Typen, behandle schwache manuell.

Skript-Architektur

Das Skript folgt einer Pipeline:

  • Liste der Projekte in einer Gruppe mit Untergruppen abrufen.
  • Archivierte und inaktive herausfiltern.
  • Parallele Verarbeitung: API-Suche + Tiefensuche.
  • Ergebnisse aggregieren.
  • Berichte generieren.
GitLab-Gruppe → projects.list() → aktive filtern
↓
Parallel: API-Suche (Code) + Tiefensuche (Konfigurationen)
↓
Zusammenführen → Detaillierter Bericht + Zusammenfassung + Fehler

Die Suche ist auf den Master-Branch für aktuelle Konfigurationen beschränkt. Erweiterung auf alle Branches ist möglich, erhöht aber die Zeit.

Implementierung der Schlüsselkomponenten

Projekte abrufen

group = gl.groups.get(GROUP_ID)
all_projects = group.projects.list(include_subgroups=True, all=True)

Filtern nach Status archived=false und last_activity.

API-Suche für Code

def api_search(gl, project_id, search_terms):
    results = {term: [] for term in search_terms}
    for term in search_terms:
        blobs = gl.search('blobs', term, project_id=project_id)
        for blob in blobs:
            file_path = blob.get('path', '')
            file_ext = os.path.splitext(file_path)[1].lower()
            if file_ext in CODE_EXTENSIONS or file_ext == '':
                results[term].append({
                    'path': file_path,
                    'url': blob.get('web_url', '#'),
                    'found_by': 'API'
                })
    return results

Verarbeitet Blobs nach Code-Erweiterungen.

Tiefensuche für Konfigurationen

def deep_search_configs(gl, project_id, search_terms):
    results = {term: [] for term in search_terms}
    project = gl.projects.get(project_id)
    files = project.repository_tree(recursive=True, ref='master')
    for file in files:
        if file['type'] != 'blob':
            continue
        ext = os.path.splitext(file['name'])[1].lower()
        if ext not in CONFIG_EXTENSIONS:
            continue
        content = project.files.get(file_path=file['path'], ref='master').decode()
        content_lower = content.lower()
        for term in search_terms:
            if term.lower() in content_lower:
                results[term].append({
                    'path': file['path'],
                    'found_by': 'Deep'
                })
    return results

Rekursiver Baum, Inhalte abrufen, Zeichenkettensuche.

Parallelisierung der Verarbeitung

ThreadPoolExecutor mit 3 Workern beschleunigt für 100+ Projekte:

with ThreadPoolExecutor(max_workers=3) as executor:
    futures = {executor.submit(process_one_project, gl, p): p for p in active_projects}
    for future in as_completed(futures):
        result = future.result()
        results_list.append(result)

Reduziert Zeit von Stunden auf Minuten ohne GIL-Probleme bei IO-lastigen Aufgaben.

Berichtsformate

Detailliert: Projekt, Pfad, Begriff, Zeile, Suchmethode.

Beispiel:

PROJEKT: service-a
Pfad: backend/service-a
'SERVICE_EXAMPLE': 2 Vorkommen
  - deploy/prod/values.yml:42 [Deep]
    Zeile 42: SERVICE_EXAMPLE: "{{ .Values.secrets.apiKey }}"

Zusammenfassung: Anzahl der Projekte, Vorkommen, API vs. Deep.

Geschwindigkeitsfaktoren

  • Ausschluss unnötiger Dateien/Projekte.
  • API für 80% der Fälle (Code).
  • Parallelität.
  • Fokus auf Master.

Einschränkungen

  • Nur Master.
  • Keine Regex.
  • Keine Deduplizierung.
  • Konsolenausgabe.

Wichtige Punkte

  • Hybrid minimiert GitLab-Suchschwächen für Konfigurationen.
  • Parallelität mit 3 Threads ist optimal für API-Ratenlimits.
  • Projektfilterung reduziert Last um 30–50%.
  • Tiefensuche ist genau für YAML/JSON/env.
  • Geeignet für einmalige Prüfungen ohne Infrastruktur.

— Editorial Team

Advertisement 728x90

Weiterlesen