422 lines
10 KiB
Markdown
422 lines
10 KiB
Markdown
# LIAM NTFS Massenverarbeitung / AD-Gruppenanlage - konkretes Konzept
|
|
|
|
## Ziel
|
|
|
|
Dieses Dokument beschreibt ein konkretes Zielkonzept fuer die Verarbeitung grosser NTFS-Strukturen mit vielen Ordnern und automatischer AD-Gruppenanlage.
|
|
|
|
Beispielgroessenordnung:
|
|
|
|
- 1000 Ordner
|
|
- pro Ordner 3 bis 6 Berechtigungsgruppen
|
|
- optional Traverse-Gruppen
|
|
|
|
Ziel ist eine fachlich korrekte, aber vor allem skalierbare Verarbeitung ohne unkontrolliert lange Laufzeiten.
|
|
|
|
## Problem des aktuellen Zustands
|
|
|
|
Der aktuelle Code ist funktional auf einzelne Ordner oder kleine Mengen ausgerichtet.
|
|
|
|
Bei grossen Strukturen ergeben sich mehrere Engpaesse:
|
|
|
|
- Verarbeitung erfolgt pro Ordner sequentiell
|
|
- pro Ordner werden Gruppen einzeln aufgeloest oder angelegt
|
|
- bestehende Gruppen werden teilweise ueber OU-weite Wildcard-Suche gesucht
|
|
- ACLs werden pro Ordner direkt gesetzt
|
|
- Traverse-Verarbeitung enthaelt eine harte Wartezeit
|
|
|
|
Damit ist die aktuelle Implementierung fuer Massenlaeufe fachlich nutzbar, aber technisch nicht belastbar.
|
|
|
|
## Ist-Zustand
|
|
|
|
### 1. Automatischer Ensure-Pfad bei `Get DataAreas`
|
|
|
|
Wenn `EnsureNtfsPermissionGroups=true` gesetzt ist, wird fuer jede erkannte `cLiamNtfsFolder` nacheinander `EnsureMissingPermissionGroupsAsync(...)` aufgerufen.
|
|
|
|
Das bedeutet:
|
|
|
|
- jeder Ordner wird isoliert behandelt
|
|
- keine gemeinsame Voranalyse
|
|
- kein Caching ueber den gesamten Lauf
|
|
|
|
### 2. Create-/Ensure-Pfad
|
|
|
|
Pro Ordner passiert derzeit im Wesentlichen:
|
|
|
|
1. Soll-Gruppen generieren
|
|
2. Benutzer-SIDs aufloesen
|
|
3. pro Gruppe in AD suchen
|
|
4. fehlende Gruppe anlegen
|
|
5. Mitglieder setzen
|
|
6. ACLs setzen
|
|
7. optional Traverse-Gruppen verarbeiten
|
|
|
|
### 3. Teure Stellen
|
|
|
|
Die teuersten Einzelschritte sind aktuell:
|
|
|
|
- OU-weite Wildcard-Suche in AD
|
|
- mehrfaches Erzeugen und Pruefen von Gruppennamen bei Kollisionen
|
|
- sequentielle LDAP-/AD-Zugriffe
|
|
- sequentielle ACL-Updates
|
|
- `Thread.Sleep(180000)` im Traverse-Pfad
|
|
|
|
## Skalierungsannahmen
|
|
|
|
Grobe Groessenordnung fuer 1000 Ordner:
|
|
|
|
- AGP:
|
|
- 3 Gruppen pro Ordner
|
|
- ca. 3000 Gruppenoperationen
|
|
- AGDLP:
|
|
- 6 Gruppen pro Ordner
|
|
- ca. 6000 Gruppenoperationen
|
|
|
|
Falls jeder Zugriff separat gegen AD und Dateisystem geht, ist die Gesamtlaufzeit nicht mehr akzeptabel.
|
|
|
|
## Zielbild
|
|
|
|
Die Verarbeitung soll von einer ordnerweisen Online-Logik zu einem mehrstufigen Batch-Modell umgebaut werden.
|
|
|
|
Empfohlenes Zielbild:
|
|
|
|
1. Struktur erfassen
|
|
2. Soll-Zustand fuer alle Ordner berechnen
|
|
3. Ist-Zustand aus AD und ACLs gesammelt laden
|
|
4. Delta bilden
|
|
5. Gruppen in kontrollierten Batches anlegen oder wiederverwenden
|
|
6. ACLs in kontrollierten Batches setzen
|
|
7. Traverse separat behandeln
|
|
|
|
## Grundprinzip
|
|
|
|
Nicht pro Ordner sofort alles erledigen, sondern:
|
|
|
|
- zuerst global analysieren
|
|
- dann gesammelt abgleichen
|
|
- dann nur das Delta ausfuehren
|
|
|
|
Das reduziert:
|
|
|
|
- LDAP-Calls
|
|
- Share-/Dateisystemzugriffe
|
|
- Redundanz
|
|
- Gefahr von doppelten Gruppen
|
|
|
|
## Fachliche Verarbeitungsschritte
|
|
|
|
### Schritt 1: Ordnerliste erfassen
|
|
|
|
Fuer den gewaehlten Root werden alle relevanten Ordner einmalig geladen.
|
|
|
|
Ergebnis je Ordner:
|
|
|
|
- technischer Pfad
|
|
- Parent-Pfad
|
|
- Tiefe
|
|
- fachlicher Typ
|
|
|
|
Wichtig:
|
|
|
|
- dieser Schritt dient nur der Strukturerfassung
|
|
- noch keine AD-Anlage
|
|
|
|
### Schritt 2: Soll-Gruppen fuer alle Ordner berechnen
|
|
|
|
Fuer jeden Ordner werden die erwarteten Gruppen aus Naming Conventions und Tags berechnet.
|
|
|
|
Ergebnis je Soll-Gruppe:
|
|
|
|
- Ordnerpfad
|
|
- Gruppe
|
|
- Scope
|
|
- AccessRole
|
|
- exakter Soll-Name
|
|
- Wildcard
|
|
- benoetigte Mitglieder
|
|
- benoetigte verschachtelte Gruppen
|
|
|
|
Damit existiert ein kompletter Soll-Bestand fuer den gesamten Lauf.
|
|
|
|
### Schritt 3: AD-Ist-Zustand einmalig oder in grossen Batches laden
|
|
|
|
Statt pro Gruppe die OU neu zu durchsuchen, wird die Ziel-OU gesammelt geladen.
|
|
|
|
Empfohlene Daten:
|
|
|
|
- `sAMAccountName`
|
|
- `distinguishedName`
|
|
- `objectSid`
|
|
- `member`
|
|
|
|
Die geladene OU wird in Dictionaries abgelegt:
|
|
|
|
- nach `sAMAccountName`
|
|
- optional nach Regex-relevanten Merkmalen
|
|
|
|
Vorteil:
|
|
|
|
- keine OU-Vollsuche pro Gruppe
|
|
- kein O(n*m)-Verhalten bei vielen Gruppen
|
|
|
|
## Wichtige Optimierung
|
|
|
|
Die aktuelle Wildcard-Suche darf im Batch-Pfad nicht mehr als LDAP-Vollscan pro Gruppe stattfinden.
|
|
|
|
Stattdessen:
|
|
|
|
- OU einmal lesen
|
|
- lokal in Memory gegen Regex pruefen
|
|
|
|
Das ist einer der wichtigsten Performance-Gewinne.
|
|
|
|
### Schritt 4: ACL-Ist-Zustand gesammelt erfassen
|
|
|
|
Wenn bestehende ACL-Gruppen wiederverwendet werden sollen, werden die ACLs der Zielordner ebenfalls zuerst gesammelt gelesen.
|
|
|
|
Ergebnis je Ordner:
|
|
|
|
- direkt gesetzte ACL-Gruppen
|
|
- gematchte Owner-/Write-/Read-/Traverse-Gruppen
|
|
|
|
Dadurch kann die Wiederverwendung bestehender Gruppen lokal entschieden werden, ohne spaetere AD-Neuanlagen zu provozieren.
|
|
|
|
### Schritt 5: Delta bilden
|
|
|
|
Fuer jede Soll-Gruppe wird entschieden:
|
|
|
|
- exakter Treffer vorhanden
|
|
- eindeutiger ACL-Treffer vorhanden
|
|
- eindeutiger Regex-Treffer vorhanden
|
|
- Gruppe fehlt und muss erzeugt werden
|
|
|
|
Nur fuer fehlende Gruppen wird eine Anlage geplant.
|
|
|
|
### Schritt 6: Gruppenanlage in Batches
|
|
|
|
Die Neuanlage sollte kontrolliert parallelisiert werden.
|
|
|
|
Empfehlung:
|
|
|
|
- kleiner, begrenzter Parallelitaetsgrad
|
|
- z. B. 4 bis 8 parallele AD-Operationen
|
|
|
|
Nicht empfohlen:
|
|
|
|
- ungebremste Parallelisierung ueber Hunderte von Gruppen
|
|
|
|
Grund:
|
|
|
|
- AD, DCs und Netzwerk sollen nicht ueberlastet werden
|
|
- Kollisionen und Transienten bleiben beherrschbar
|
|
|
|
### Schritt 7: Mitgliedschaften und Verschachtelung als eigener Schritt
|
|
|
|
Gruppen anlegen und Mitglieder setzen sollten getrennt betrachtet werden.
|
|
|
|
Empfohlene Reihenfolge:
|
|
|
|
1. alle fehlenden Gruppen erzeugen
|
|
2. SIDs/DNs refreshen
|
|
3. Mitglieder und Nested Groups setzen
|
|
|
|
Das verhindert Folgefehler durch noch nicht existierende Gruppen.
|
|
|
|
### Schritt 8: ACLs in eigenem Batch-Schritt
|
|
|
|
ACLs werden erst gesetzt, wenn die benoetigten Gruppen sicher existieren.
|
|
|
|
Auch hier:
|
|
|
|
- kontrollierte Parallelitaet
|
|
- Fehler pro Ordner isolieren
|
|
- Ergebnislisten sammeln
|
|
|
|
## Traverse-Gruppen
|
|
|
|
Traverse muss aus dem normalen Massenpfad herausgezogen werden.
|
|
|
|
Der aktuelle Ansatz mit harter Wartezeit ist fuer grosse Strukturen nicht tragbar.
|
|
|
|
Fuer grosse Laeufe gilt:
|
|
|
|
- Traverse standardmaessig deaktivieren oder separieren
|
|
- Traverse als eigener Nachlauf
|
|
- keine feste `Thread.Sleep`-Pause
|
|
|
|
Stattdessen:
|
|
|
|
- Polling oder Retry mit kleinem Intervall
|
|
- nur fuer die konkret benoetigten Gruppen
|
|
|
|
## Neue logische Komponenten
|
|
|
|
### 1. `NtfsBulkPlanBuilder`
|
|
|
|
Verantwortung:
|
|
|
|
- Ordnerliste laden
|
|
- Soll-Gruppen pro Ordner berechnen
|
|
- Soll-ACLs vorbereiten
|
|
|
|
### 2. `AdSnapshotLoader`
|
|
|
|
Verantwortung:
|
|
|
|
- OU einmalig oder abschnittsweise laden
|
|
- In-Memory-Index fuer:
|
|
- `sAMAccountName`
|
|
- `SID`
|
|
- `DN`
|
|
|
|
### 3. `AclSnapshotLoader`
|
|
|
|
Verantwortung:
|
|
|
|
- direkte ACLs aller Zielordner einlesen
|
|
- passende Berechtigungsgruppen markieren
|
|
|
|
### 4. `NtfsBulkDeltaResolver`
|
|
|
|
Verantwortung:
|
|
|
|
- Soll/Ist vergleichen
|
|
- Wiederverwendung oder Neuanlage entscheiden
|
|
|
|
### 5. `AdBatchExecutor`
|
|
|
|
Verantwortung:
|
|
|
|
- Gruppenanlage
|
|
- Mitglieder setzen
|
|
- verschachtelte Gruppen setzen
|
|
|
|
### 6. `AclBatchExecutor`
|
|
|
|
Verantwortung:
|
|
|
|
- ACLs setzen
|
|
- vorhandene ACLs erkennen
|
|
- nur fehlende ACEs schreiben
|
|
|
|
## Empfohlenes Ausfuehrungsmodell
|
|
|
|
### Modus A: Analyse
|
|
|
|
Nur ermitteln:
|
|
|
|
- welche Gruppen fehlen
|
|
- welche wiederverwendet wuerden
|
|
- welche ACLs fehlen
|
|
|
|
Ohne Schreibzugriffe.
|
|
|
|
### Modus B: Ensure
|
|
|
|
Nur Delta anwenden:
|
|
|
|
- fehlende Gruppen anlegen
|
|
- fehlende Mitglieder ergaenzen
|
|
- fehlende ACLs setzen
|
|
|
|
### Modus C: Traverse-Nachlauf
|
|
|
|
Separat und optional:
|
|
|
|
- Traverse-Gruppen erzeugen
|
|
- Traverserechte setzen
|
|
|
|
## Fehlerstrategie
|
|
|
|
Bei grossen Mengen darf ein Einzelfehler nicht immer den Gesamtjob abbrechen.
|
|
|
|
Empfohlen:
|
|
|
|
- Fehler pro Ordner oder Gruppe sammeln
|
|
- Schwellenwert definieren
|
|
- am Ende Gesamtstatus ableiten
|
|
|
|
Beispiel:
|
|
|
|
- `Success`
|
|
- `SuccessWithWarnings`
|
|
- `PartialFailure`
|
|
- `Failure`
|
|
|
|
## Logging und Monitoring
|
|
|
|
Bei grossen Laeufen werden strukturierte Fortschrittsdaten gebraucht.
|
|
|
|
Empfohlene Kennzahlen:
|
|
|
|
- Anzahl gescannter Ordner
|
|
- Anzahl Soll-Gruppen
|
|
- Anzahl wiederverwendeter Gruppen
|
|
- Anzahl neu erzeugter Gruppen
|
|
- Anzahl geaenderter Gruppenmitgliedschaften
|
|
- Anzahl gesetzter ACLs
|
|
- Anzahl uebersprungener ACLs
|
|
- Anzahl Fehler
|
|
- Laufzeit je Phase
|
|
|
|
Wichtig:
|
|
|
|
- Fortschritt nicht nur pro Objekt loggen
|
|
- zusaetzlich Phasen- und Batch-Statistik loggen
|
|
|
|
## Konkrete technische Leitplanken
|
|
|
|
### Nicht mehr so
|
|
|
|
- pro Ordner komplette OU-Wildcard-Suche
|
|
- pro Gruppe sofortiger AD-Zugriff
|
|
- Traverse mit fester 180-Sekunden-Wartezeit
|
|
- keine Trennung zwischen Analyse und Ausfuehrung
|
|
|
|
### Stattdessen
|
|
|
|
- OU-Snapshot einmalig laden
|
|
- ACL-Snapshot gesammelt laden
|
|
- Delta zentral berechnen
|
|
- kontrollierte Parallelitaet
|
|
- Traverse separat
|
|
|
|
## Rueckwaertskompatibilitaet
|
|
|
|
Der bestehende Einzelordner-Pfad kann bestehen bleiben.
|
|
|
|
Empfehlung:
|
|
|
|
- bestehende Methoden fuer Einzelobjekte weiter nutzen
|
|
- neuen Bulk-Pfad zusaetzlich einfuehren
|
|
|
|
Beispiele:
|
|
|
|
- `EnsureMissingPermissionGroupsAsync(...)` bleibt fuer Einzelordner
|
|
- neuer Bulk-Einstieg fuer Listen oder Root-Strukturen
|
|
|
|
## Minimal sinnvolle erste Ausbaustufe
|
|
|
|
Wenn nicht sofort das gesamte Zielbild umgesetzt werden soll, ist die sinnvollste erste Stufe:
|
|
|
|
1. OU nicht mehr pro Gruppe scannen, sondern einmalig laden
|
|
2. ACL-Wiederverwendung fuer alle Zielordner gesammelt vorbereiten
|
|
3. Traverse aus grossen Laeufen herausnehmen
|
|
4. Ensure fuer grosse Mengen explizit batchen
|
|
|
|
Schon diese vier Punkte wuerden die groessten praktischen Probleme stark reduzieren.
|
|
|
|
## Entscheidung
|
|
|
|
Fuer grosse Strukturen mit 1000+ Ordnern ist die aktuelle ordnerweise Online-Logik nicht ausreichend.
|
|
|
|
Die empfohlene Zielumsetzung ist daher:
|
|
|
|
- Batch-orientierte Voranalyse
|
|
- AD-Snapshot statt OU-Scan pro Gruppe
|
|
- ACL-Snapshot statt Einzelfallentscheidungen
|
|
- Delta-basierte Ausfuehrung
|
|
- kontrollierte Parallelisierung
|
|
- Traverse als separater Spezialpfad
|
|
|
|
Nur damit wird die AD-Gruppenanlage fuer grosse Strukturen technisch belastbar und operativ beherrschbar.
|