97 lines
2.4 KiB
Go
97 lines
2.4 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// аккуратный разбор лога autoloop: игнорим "route:", смотрим status
|
|
func parseAutoloopStatus(lines []string) (word, raw string) {
|
|
for i := len(lines) - 1; i >= 0; i-- {
|
|
line := strings.TrimSpace(lines[i])
|
|
if line == "" {
|
|
continue
|
|
}
|
|
if idx := strings.Index(line, "autoloop:"); idx >= 0 {
|
|
line = strings.TrimSpace(line[idx+len("autoloop:"):])
|
|
}
|
|
lower := strings.ToLower(line)
|
|
|
|
// route: default dev ... - нам неинтересно
|
|
if strings.HasPrefix(lower, "route: ") {
|
|
continue
|
|
}
|
|
|
|
switch {
|
|
case strings.Contains(lower, "status: connected"),
|
|
strings.Contains(lower, "after connect: connected"):
|
|
return "CONNECTED", line
|
|
case strings.Contains(lower, "status: reconnecting"):
|
|
return "RECONNECTING", line
|
|
case strings.Contains(lower, "status: disconnected"),
|
|
strings.Contains(lower, "still disconnected"):
|
|
return "DISCONNECTED", line
|
|
case strings.Contains(lower, "timeout"),
|
|
strings.Contains(lower, "failed"):
|
|
return "ERROR", line
|
|
}
|
|
}
|
|
return "unknown", ""
|
|
}
|
|
|
|
func handleVPNAutoloopStatus(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
lines := tailFile(autoloopLogPath, 200)
|
|
word, raw := parseAutoloopStatus(lines)
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"raw_text": raw,
|
|
"status_word": word,
|
|
})
|
|
}
|
|
|
|
func handleVPNStatus(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
// desired location
|
|
loc := ""
|
|
if data, err := os.ReadFile(desiredLocation); err == nil {
|
|
loc = parseStoredVPNLocationPrimary(string(data))
|
|
}
|
|
|
|
// unit state
|
|
stdout, _, _, err := runCommand("systemctl", "is-active", adgvpnUnit)
|
|
unitState := strings.TrimSpace(stdout)
|
|
if err != nil || unitState == "" {
|
|
unitState = "unknown"
|
|
}
|
|
|
|
// автолуп
|
|
lines := tailFile(autoloopLogPath, 200)
|
|
word, raw := parseAutoloopStatus(lines)
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"desired_location": loc,
|
|
"status_word": word,
|
|
"raw_text": raw,
|
|
"unit_state": unitState,
|
|
})
|
|
}
|
|
|
|
func parseStoredVPNLocationPrimary(raw string) string {
|
|
v := strings.TrimSpace(raw)
|
|
if v == "" {
|
|
return ""
|
|
}
|
|
if p := strings.SplitN(v, "|", 2); len(p) == 2 {
|
|
return strings.TrimSpace(p[0])
|
|
}
|
|
return v
|
|
}
|