Files
elmprodvpn/selective-vpn-api/app/transport_client_runtime_state.go

85 lines
2.2 KiB
Go

package app
import (
"strings"
"time"
)
func transportRuntimeSnapshot(it TransportClient, now time.Time) TransportClientRuntime {
rt := it.Runtime
if strings.TrimSpace(rt.Backend) == "" {
rt.Backend = selectTransportBackend(it).ID()
}
if len(rt.AllowedActions) == 0 {
rt.AllowedActions = []string{"provision", "start", "stop", "restart"}
}
if rt.Metrics.Restarts < 0 {
rt.Metrics.Restarts = 0
}
if rt.Metrics.StateChanges < 0 {
rt.Metrics.StateChanges = 0
}
if strings.TrimSpace(rt.LastError.Message) == "" && strings.TrimSpace(it.Health.LastError) != "" {
rt.LastError = TransportClientError{
Code: "BACKEND_RUNTIME_ERROR",
Message: strings.TrimSpace(it.Health.LastError),
Retryable: true,
At: strings.TrimSpace(it.Health.LastCheck),
}
}
rt.Metrics.UptimeSec = transportUptimeSec(it.Status, rt.StartedAt, now)
return rt
}
func normalizeTransportRuntimeStored(rt TransportClientRuntime, kind TransportClientKind, cfg map[string]any) (TransportClientRuntime, bool) {
changed := false
if strings.TrimSpace(rt.Backend) == "" {
rt.Backend = selectTransportBackend(TransportClient{Kind: kind, Config: cfg}).ID()
changed = true
}
wantActions := []string{"provision", "start", "stop", "restart"}
if !equalStringSlices(rt.AllowedActions, wantActions) {
rt.AllowedActions = append([]string(nil), wantActions...)
changed = true
}
if rt.Metrics.Restarts < 0 {
rt.Metrics.Restarts = 0
changed = true
}
if rt.Metrics.StateChanges < 0 {
rt.Metrics.StateChanges = 0
changed = true
}
if rt.Metrics.UptimeSec < 0 {
rt.Metrics.UptimeSec = 0
changed = true
}
if rt.LastExitCode < 0 {
rt.LastExitCode = 0
changed = true
}
if strings.TrimSpace(rt.LastError.Message) == "" && strings.TrimSpace(rt.LastError.Code) != "" {
rt.LastError.Code = ""
changed = true
}
return rt, changed
}
func transportUptimeSec(status TransportClientStatus, startedAt string, now time.Time) int64 {
if status != TransportClientUp {
return 0
}
ts := strings.TrimSpace(startedAt)
if ts == "" {
return 0
}
started, err := time.Parse(time.RFC3339, ts)
if err != nil {
return 0
}
if started.After(now) {
return 0
}
return int64(now.Sub(started).Seconds())
}