feat: implement ntfy-discord bridge in Go
- SSE subscription to ntfy with auto-reconnect - Discord webhook integration with embed formatting - Priority to color mapping, tag to emoji conversion - Native HashiCorp Vault support (Kubernetes + token auth) - Hot reload secrets via fsnotify or Vault polling - Prometheus metrics (/metrics endpoint) - Health/ready endpoints for Kubernetes probes - Comprehensive unit tests and fuzz tests - Multi-stage Docker build (~10MB scratch image) - CI/CD pipeline for Gitea Actions
This commit is contained in:
59
main.go
Normal file
59
main.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/bridge"
|
||||
"git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/config"
|
||||
"git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/server"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Setup structured logging
|
||||
logLevel := slog.LevelInfo
|
||||
if os.Getenv("LOG_LEVEL") == "debug" {
|
||||
logLevel = slog.LevelDebug
|
||||
}
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel}))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
slog.Info("starting ntfy-discord bridge")
|
||||
|
||||
// Create context with cancellation
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// Load configuration (may connect to Vault)
|
||||
cfg, err := config.Load(ctx)
|
||||
if err != nil {
|
||||
slog.Error("failed to load config", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer cfg.Close()
|
||||
|
||||
// Start the bridge
|
||||
b := bridge.New(cfg)
|
||||
|
||||
// Start HTTP server for health/metrics
|
||||
srv := server.New(cfg.HTTPPort, b)
|
||||
go srv.Start()
|
||||
|
||||
// Start watching secrets for hot reload (Vault and/or file-based)
|
||||
cfg.WatchSecrets(ctx)
|
||||
|
||||
// Start the bridge
|
||||
go b.Run(ctx)
|
||||
|
||||
// Wait for shutdown signal
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigCh
|
||||
|
||||
slog.Info("shutting down")
|
||||
cancel()
|
||||
srv.Shutdown(ctx)
|
||||
}
|
||||
Reference in New Issue
Block a user