towerops-agent/main.go

77 lines
1.9 KiB
Go

package main
import (
"context"
"flag"
"fmt"
"log/slog"
"os"
"os/signal"
"strings"
"syscall"
)
var version = "dev"
func main() {
apiURL := flag.String("api-url", os.Getenv("TOWEROPS_API_URL"), "API URL (e.g., wss://towerops.net)")
token := flag.String("token", os.Getenv("TOWEROPS_AGENT_TOKEN"), "Agent authentication token")
logLevel := flag.String("log-level", envOrDefault("LOG_LEVEL", "info"), "Log level (debug, info, warn, error)")
flag.Parse()
// Setup structured logging
var level slog.Level
switch strings.ToLower(*logLevel) {
case "debug":
level = slog.LevelDebug
case "warn", "warning":
level = slog.LevelWarn
case "error":
level = slog.LevelError
default:
level = slog.LevelInfo
}
slog.SetDefault(slog.New(newColorHandler(os.Stderr, &slog.HandlerOptions{Level: level})))
if *apiURL == "" || *token == "" {
fmt.Fprintln(os.Stderr, "error: --api-url and --token are required (or set TOWEROPS_API_URL and TOWEROPS_AGENT_TOKEN)")
flag.Usage()
os.Exit(1)
}
slog.Info("towerops agent starting", "version", version)
// Convert HTTP(S) to WebSocket URL
wsURL := toWebSocketURL(*apiURL)
slog.Info("websocket url", "url", wsURL)
// Signal handling
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
defer cancel()
// Run agent with reconnect loop
runAgent(ctx, wsURL, *token)
slog.Info("towerops agent stopped")
}
// toWebSocketURL converts an HTTP(S) URL to a WebSocket URL.
func toWebSocketURL(url string) string {
switch {
case strings.HasPrefix(url, "http://"):
return "ws://" + strings.TrimPrefix(url, "http://")
case strings.HasPrefix(url, "https://"):
return "wss://" + strings.TrimPrefix(url, "https://")
case strings.HasPrefix(url, "ws://"), strings.HasPrefix(url, "wss://"):
return url
default:
return "wss://" + url
}
}
func envOrDefault(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}