2026-08-21 07:34:45 +03:00
|
|
|
// Command prober runs on one of the external test sites. It polls the
|
|
|
|
|
// Control API for the set of floating IPs currently under test and probes
|
|
|
|
|
// each directly (TCP connect + ICMP echo) to measure inbound reachability
|
|
|
|
|
// from this vantage point.
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"flag"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"os"
|
|
|
|
|
"os/signal"
|
|
|
|
|
"syscall"
|
|
|
|
|
|
|
|
|
|
"cloudipvalidator/internal/config"
|
|
|
|
|
"cloudipvalidator/internal/probercore"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
configPath := flag.String("config", "configs/prober.yaml", "path to prober config file")
|
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
log := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
|
|
|
|
|
|
|
|
|
|
cfg, err := config.LoadProber(*configPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("load config", "err", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
|
|
|
defer stop()
|
|
|
|
|
|
2026-10-01 11:35:24 +03:00
|
|
|
token := os.Getenv(cfg.ControlAPITokenEnv)
|
|
|
|
|
if token == "" {
|
|
|
|
|
log.Warn("agent token is not set: result calls will be rejected by an authenticated control-api", "env", cfg.ControlAPITokenEnv)
|
|
|
|
|
}
|
|
|
|
|
prober := probercore.New(cfg, log).WithToken(token)
|
2026-08-21 07:34:45 +03:00
|
|
|
if err := prober.Run(ctx); err != nil && err != context.Canceled {
|
|
|
|
|
log.Error("prober stopped", "err", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
}
|