146 lines
4.8 KiB
Go
146 lines
4.8 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
)
|
|
|
|
func handleTransportPolicies(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
transportMu.Lock()
|
|
policy := loadTransportPolicyState()
|
|
clientsState := loadTransportClientsState()
|
|
plan := loadTransportPolicyCompilePlan()
|
|
planSnapshot := captureTransportPolicyPlanStateSnapshot(policy, plan)
|
|
transportMu.Unlock()
|
|
|
|
policyTargets := transportPolicyClientsWithVirtualTargets(clientsState.Items)
|
|
nextPlan, planChanged := compileTransportPolicyPlanForSnapshot(policy, policyTargets, plan)
|
|
if planChanged {
|
|
_ = saveTransportPlanIfSnapshotCurrent(planSnapshot, nextPlan)
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, TransportPolicyResponse{
|
|
OK: true,
|
|
Message: "ok",
|
|
PolicyRevision: policy.Revision,
|
|
Intents: policy.Intents,
|
|
Plan: &nextPlan,
|
|
})
|
|
}
|
|
|
|
func handleTransportConflicts(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
transportMu.Lock()
|
|
st := loadTransportConflictsState()
|
|
transportMu.Unlock()
|
|
writeJSON(w, http.StatusOK, TransportConflictsResponse{
|
|
OK: true,
|
|
Message: "ok",
|
|
HasBlocking: st.HasBlocking,
|
|
Items: st.Items,
|
|
})
|
|
}
|
|
|
|
func handleTransportOwnership(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
transportMu.Lock()
|
|
policy := loadTransportPolicyState()
|
|
clientsState := loadTransportClientsState()
|
|
owners := loadTransportOwnershipState()
|
|
plan := loadTransportPolicyCompilePlan()
|
|
planSnapshot := captureTransportPolicyPlanStateSnapshot(policy, plan)
|
|
ownershipSnapshot := captureTransportOwnershipStateSnapshot(policy, owners)
|
|
transportMu.Unlock()
|
|
|
|
policyTargets := transportPolicyClientsWithVirtualTargets(clientsState.Items)
|
|
nextPlan, planChanged := compileTransportPolicyPlanForSnapshot(policy, policyTargets, plan)
|
|
if planChanged {
|
|
_ = saveTransportPlanIfSnapshotCurrent(planSnapshot, nextPlan)
|
|
}
|
|
planDigest := digestTransportPolicyCompilePlan(nextPlan)
|
|
if transportOwnershipNeedsRebuild(policy.Revision, owners, planDigest) {
|
|
owners = buildTransportOwnershipStateFromPlan(nextPlan, policy.Revision)
|
|
_ = saveTransportOwnershipIfSnapshotCurrent(ownershipSnapshot, owners)
|
|
}
|
|
items, lockCount := attachTransportOwnershipLockState(owners.Items, policyTargets)
|
|
writeJSON(w, http.StatusOK, TransportOwnershipResponse{
|
|
OK: true,
|
|
Message: "ok",
|
|
PolicyRevision: owners.PolicyRevision,
|
|
PlanDigest: owners.PlanDigest,
|
|
Count: len(items),
|
|
LockCount: lockCount,
|
|
Items: items,
|
|
})
|
|
}
|
|
|
|
func handleTransportOwnerLocks(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
transportMu.Lock()
|
|
locks := loadTransportOwnerLocksState()
|
|
transportMu.Unlock()
|
|
writeJSON(w, http.StatusOK, TransportOwnerLocksResponse{
|
|
OK: true,
|
|
Message: "ok",
|
|
PolicyRevision: locks.PolicyRevision,
|
|
Count: len(locks.Items),
|
|
Items: locks.Items,
|
|
})
|
|
}
|
|
|
|
func handleTransportCapabilities(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, TransportCapabilitiesResponse{
|
|
OK: true,
|
|
Message: "ok",
|
|
Clients: map[string]map[string]bool{
|
|
"singbox": {"tcp": true, "udp": true, "dns_tunnel": true, "ssh_tunnel": false},
|
|
"dnstt": {"tcp": true, "udp": false, "dns_tunnel": true, "ssh_tunnel": true},
|
|
"phoenix": {"tcp": true, "udp": true, "dns_tunnel": false, "ssh_tunnel": true},
|
|
"adguardvpn": {"vpn": true, "autoloop": true, "dns_tunnel": false, "ssh_tunnel": false},
|
|
},
|
|
RuntimeModes: map[string]bool{
|
|
"exec": true,
|
|
"embedded": false,
|
|
"sidecar": false,
|
|
},
|
|
PackagingProfiles: map[string]bool{
|
|
"system": true,
|
|
"bundled": true,
|
|
},
|
|
Lifecycle: []string{"provision", "start", "stop", "restart"},
|
|
HealthFields: []string{"status", "latency_ms", "last_error", "health.last_check"},
|
|
MetricsFields: []string{"restarts", "state_changes", "uptime_sec", "last_transition_at"},
|
|
ErrorCodes: []string{
|
|
"TRANSPORT_CLIENT_NOT_FOUND",
|
|
"TRANSPORT_CLIENT_SAVE_FAILED",
|
|
"TRANSPORT_CLIENT_DEGRADED",
|
|
"BACKEND_RUNTIME_ERROR",
|
|
"TRANSPORT_BACKEND_NETNS_SETUP_FAILED",
|
|
"TRANSPORT_BACKEND_BOOTSTRAP_BYPASS_FAILED",
|
|
"TRANSPORT_BACKEND_SINGBOX_DNS_MIGRATE_FAILED",
|
|
"TRANSPORT_BACKEND_UNIT_REQUIRED",
|
|
"TRANSPORT_BACKEND_ACTION_FAILED",
|
|
"TRANSPORT_BACKEND_HEALTH_FAILED",
|
|
"TRANSPORT_BACKEND_PROVISION_CONFIG_REQUIRED",
|
|
"TRANSPORT_BACKEND_PROVISION_FAILED",
|
|
"TRANSPORT_BACKEND_RUNTIME_MODE_UNSUPPORTED",
|
|
},
|
|
})
|
|
}
|