platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func handleTransportPoliciesValidateExec(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
var body TransportPolicyValidateRequest
|
||||
if r.Body != nil {
|
||||
defer r.Body.Close()
|
||||
if err := json.NewDecoder(io.LimitReader(r.Body, 2<<20)).Decode(&body); err != nil && err != io.EOF {
|
||||
http.Error(w, "bad json", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
transportMu.Lock()
|
||||
clientsState := loadTransportClientsState()
|
||||
current := loadTransportPolicyState()
|
||||
locks := TransportOwnerLockState{}
|
||||
if transportPolicyKernelConntrackStickyEnabled() {
|
||||
locks = loadTransportOwnerLocksState()
|
||||
}
|
||||
transportMu.Unlock()
|
||||
clients := transportPolicyClientsWithVirtualTargets(clientsState.Items)
|
||||
|
||||
result := validateTransportPolicy(body.Intents, current.Intents, clients)
|
||||
ownerSwitchConflicts := detectTransportOwnerSwitchConflicts(current.Intents, result.Normalized)
|
||||
if len(ownerSwitchConflicts) > 0 {
|
||||
result.Conflicts = append(result.Conflicts, ownerSwitchConflicts...)
|
||||
result.Conflicts = dedupeTransportConflicts(result.Conflicts)
|
||||
result.Summary = summarizeTransportConflicts(result.Conflicts)
|
||||
result.Valid = result.Summary.BlockCount == 0
|
||||
}
|
||||
ownerLockConflicts := detectTransportOwnerLockConflicts(current.Intents, result.Normalized, clients)
|
||||
if len(ownerLockConflicts) > 0 {
|
||||
result.Conflicts = append(result.Conflicts, ownerLockConflicts...)
|
||||
result.Conflicts = dedupeTransportConflicts(result.Conflicts)
|
||||
result.Summary = summarizeTransportConflicts(result.Conflicts)
|
||||
result.Valid = result.Summary.BlockCount == 0
|
||||
}
|
||||
destinationLockConflicts := detectTransportDestinationLockConflicts(current.Intents, result.Normalized, locks)
|
||||
if len(destinationLockConflicts) > 0 {
|
||||
result.Conflicts = append(result.Conflicts, destinationLockConflicts...)
|
||||
result.Conflicts = dedupeTransportConflicts(result.Conflicts)
|
||||
result.Summary = summarizeTransportConflicts(result.Conflicts)
|
||||
result.Valid = result.Summary.BlockCount == 0
|
||||
}
|
||||
if body.BaseRevision > 0 && body.BaseRevision != current.Revision {
|
||||
result.Conflicts = append(result.Conflicts, TransportConflictRecord{
|
||||
Key: "base_revision",
|
||||
Type: "stale_base",
|
||||
Severity: "warn",
|
||||
Reason: fmt.Sprintf("base_revision=%d differs from current=%d", body.BaseRevision, current.Revision),
|
||||
SuggestedResolution: "refresh policy and retry validate/apply",
|
||||
})
|
||||
result.Summary.WarnCount++
|
||||
result.Conflicts = dedupeTransportConflicts(result.Conflicts)
|
||||
result.Summary = summarizeTransportConflicts(result.Conflicts)
|
||||
result.Valid = result.Summary.BlockCount == 0
|
||||
}
|
||||
|
||||
plan, compileConflicts := compileTransportPolicyPlan(result.Normalized, clients, current.Revision)
|
||||
if len(compileConflicts) > 0 {
|
||||
result.Conflicts = append(result.Conflicts, compileConflicts...)
|
||||
result.Conflicts = dedupeTransportConflicts(result.Conflicts)
|
||||
result.Summary = summarizeTransportConflicts(result.Conflicts)
|
||||
result.Valid = result.Summary.BlockCount == 0
|
||||
}
|
||||
|
||||
digest := digestTransportIntents(result.Normalized)
|
||||
confirmToken := issueTransportConfirmToken(current.Revision, digest)
|
||||
state := TransportConflictState{
|
||||
Version: transportStateVersion,
|
||||
UpdatedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
HasBlocking: result.Summary.BlockCount > 0,
|
||||
Items: append([]TransportConflictRecord(nil), result.Conflicts...),
|
||||
}
|
||||
|
||||
transportMu.Lock()
|
||||
_ = saveTransportConflictsState(state)
|
||||
transportMu.Unlock()
|
||||
|
||||
msg := "validation complete"
|
||||
code := ""
|
||||
if result.Summary.BlockCount > 0 {
|
||||
msg = "policy has blocking conflicts"
|
||||
code = "POLICY_CONFLICT_BLOCK"
|
||||
}
|
||||
|
||||
events.push("transport_policy_validated", map[string]any{
|
||||
"valid": result.Valid,
|
||||
"block_count": result.Summary.BlockCount,
|
||||
"warn_count": result.Summary.WarnCount,
|
||||
})
|
||||
if result.Summary.BlockCount > 0 {
|
||||
events.push("transport_conflict_detected", map[string]any{
|
||||
"count": result.Summary.BlockCount,
|
||||
})
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, TransportPolicyValidateResponse{
|
||||
OK: true,
|
||||
Message: msg,
|
||||
Code: code,
|
||||
Valid: result.Valid,
|
||||
BaseRevision: current.Revision,
|
||||
ConfirmToken: confirmToken,
|
||||
Summary: result.Summary,
|
||||
Conflicts: result.Conflicts,
|
||||
Diff: result.Diff,
|
||||
Plan: &plan,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user