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 |
|--------|-------|--------|
| GitLab UI | Schneller Start | Manuell für 100+ Projekte, schwach bei Konfigurationen |
| Lokales grep/ripgrep | Volle Kontrolle | Klonen aller Repositories dauert Stunden |
| 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.
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
Noch keine Kommentare.