7a85441b81
Add standalone proxy management: - Multi-step validation pipeline (DNS, TCP, HTTP) with diagnostic hints - Proxy lifecycle: create/update/delete via NPM API with SSL auto-assign - Periodic health monitoring (5min) with event log on status transitions - Unified /api/proxies/all endpoint merging standalone + managed proxies - Frontend types and API functions for downstream UI phases
75 lines
2.1 KiB
Go
75 lines
2.1 KiB
Go
package proxy
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
)
|
|
|
|
// diagnosticHint returns a user-friendly suggestion for a validation failure.
|
|
func diagnosticHint(step string, err error) string {
|
|
if err == nil {
|
|
return ""
|
|
}
|
|
|
|
switch step {
|
|
case StepDNS:
|
|
return "Domain cannot be resolved. Check DNS settings or use an IP address."
|
|
|
|
case StepTCP:
|
|
return tcpHintFromError(err)
|
|
|
|
case StepHTTP:
|
|
return httpHint(err.Error())
|
|
|
|
default:
|
|
return "Validation failed: " + err.Error()
|
|
}
|
|
}
|
|
|
|
// tcpHintFromError returns a specific hint based on the TCP error type.
|
|
func tcpHintFromError(err error) string {
|
|
if err == nil {
|
|
return ""
|
|
}
|
|
|
|
var opErr *net.OpError
|
|
if errors.As(err, &opErr) {
|
|
lower := strings.ToLower(opErr.Err.Error())
|
|
switch {
|
|
case strings.Contains(lower, "connection refused"):
|
|
return "Port is not accepting connections. Check if the service is running and the port is correct."
|
|
case strings.Contains(lower, "i/o timeout") || strings.Contains(lower, "timeout"):
|
|
return "Connection timed out. Possible firewall blocking. Check network/firewall rules."
|
|
case strings.Contains(lower, "no route to host") || strings.Contains(lower, "host is unreachable"):
|
|
return "Host is not reachable. Verify the IP address and network connectivity."
|
|
}
|
|
}
|
|
|
|
msg := err.Error()
|
|
lower := strings.ToLower(msg)
|
|
switch {
|
|
case strings.Contains(lower, "connection refused"):
|
|
return "Port is not accepting connections. Check if the service is running and the port is correct."
|
|
case strings.Contains(lower, "timeout"):
|
|
return "Connection timed out. Possible firewall blocking. Check network/firewall rules."
|
|
default:
|
|
return fmt.Sprintf("TCP connection failed: %s", msg)
|
|
}
|
|
}
|
|
|
|
// httpHint returns a specific hint based on the HTTP probe result.
|
|
func httpHint(msg string) string {
|
|
lower := strings.ToLower(msg)
|
|
|
|
switch {
|
|
case strings.Contains(lower, "status"):
|
|
return msg // Already formatted by the caller with the status code.
|
|
case strings.Contains(lower, "timeout"):
|
|
return "HTTP health probe timed out. The service may be slow or unresponsive."
|
|
default:
|
|
return "HTTP health probe failed: " + msg
|
|
}
|
|
}
|