Run the service
(c *cobra.Command, args []string)
| 347 | |
| 348 | // Run the service |
| 349 | func runRoot(c *cobra.Command, args []string) { |
| 350 | applyFlagDefaults() |
| 351 | // All three listeners (HTTP, metrics, gRPC) bind concurrently; any |
| 352 | // collision is unrecoverable at runtime, so we fail fast at startup. |
| 353 | ports := map[string]int{ |
| 354 | "--http-port": rootArgs.server.HTTPPort, |
| 355 | "--metrics-port": rootArgs.server.MetricsPort, |
| 356 | "--grpc-port": rootArgs.config.GRPCPort, |
| 357 | } |
| 358 | for nameA, a := range ports { |
| 359 | for nameB, b := range ports { |
| 360 | if nameA < nameB && a == b { |
| 361 | fmt.Fprintf(os.Stderr, "invalid server ports: %s (%d) and %s (%d) must differ — each listener binds independently\n", nameA, a, nameB, b) |
| 362 | os.Exit(1) |
| 363 | } |
| 364 | } |
| 365 | } |
| 366 | |
| 367 | // Refuse to start without an admin secret. The previous default of |
| 368 | // "password" was a publicly known credential — operators upgrading from |
| 369 | // older versions must now supply --admin-secret explicitly. The strength |
| 370 | // of the supplied value is the operator's responsibility; we only |
| 371 | // guarantee it is non-empty. |
| 372 | if strings.TrimSpace(rootArgs.config.AdminSecret) == "" { |
| 373 | fmt.Fprintln(os.Stderr, "FATAL: --admin-secret is required and must not be empty.") |
| 374 | os.Exit(1) |
| 375 | } |
| 376 | |
| 377 | // Prepare logger |
| 378 | ctx := context.Background() |
| 379 | // Parse the log level |
| 380 | zeroLogLevel, err := zerolog.ParseLevel(rootArgs.logLevel) |
| 381 | if err != nil { |
| 382 | // If the log level is invalid, set it to debug |
| 383 | zeroLogLevel = zerolog.DebugLevel |
| 384 | } |
| 385 | // Create a new console writer |
| 386 | // consoleWriter := zerolog.New(os.Stdout) |
| 387 | // consoleWriter.NoColor = true |
| 388 | // consoleWriter.TimeFormat = time.RFC3339 |
| 389 | // consoleWriter.TimeLocation = time.UTC |
| 390 | zerolog.TimestampFunc = func() time.Time { |
| 391 | return time.Now().UTC() |
| 392 | } |
| 393 | log := zerolog.New(os.Stdout). |
| 394 | Level(zeroLogLevel). |
| 395 | With().Timestamp().Logger() |
| 396 | |
| 397 | // Warn if AllowedOrigins is the wildcard ["*"] — this is a development- |
| 398 | // friendly default but in production it pairs poorly with credentialed |
| 399 | // requests. Operators should set an explicit allowlist before deploying. |
| 400 | for _, o := range rootArgs.config.AllowedOrigins { |
| 401 | if o == "*" { |
| 402 | log.Warn().Msg("AllowedOrigins contains \"*\" — this is unsafe for production. Set --allowed-origins to an explicit list of trusted origins. CSRF middleware will fall back to same-origin enforcement for state-changing requests.") |
| 403 | break |
| 404 | } |
| 405 | } |
| 406 |