✨ Config service
This commit is contained in:
133
pkg/config/main.go
Normal file
133
pkg/config/main.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"git.solsynth.dev/goatworks/turbine/pkg/shared/registrar"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func hash(s string) uint32 {
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(s))
|
||||
return h.Sum32()
|
||||
}
|
||||
|
||||
func init() {
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Info().Msg("Starting Config Service...")
|
||||
viper.SetConfigName("settings")
|
||||
viper.AddConfigPath(".")
|
||||
viper.SetConfigType("toml")
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to read config file")
|
||||
}
|
||||
log.Info().Msg("Configuration loaded.")
|
||||
|
||||
// --- Service Registration ---
|
||||
etcdEndpoints := viper.GetStringSlice("etcd.endpoints")
|
||||
if len(etcdEndpoints) == 0 {
|
||||
log.Fatal().Msg("etcd.endpoints not configured")
|
||||
}
|
||||
|
||||
if viper.GetBool("etcd.insecure") {
|
||||
for i, ep := range etcdEndpoints {
|
||||
if !strings.HasPrefix(ep, "http://") && !strings.HasPrefix(ep, "https://") {
|
||||
etcdEndpoints[i] = "http://" + ep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serviceReg, err := registrar.NewServiceRegistrar(etcdEndpoints)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to create service registrar")
|
||||
}
|
||||
|
||||
listenAddr := viper.GetString("listen")
|
||||
host := viper.GetString("host")
|
||||
if host == "" {
|
||||
log.Fatal().Msg("host not configured")
|
||||
}
|
||||
portStr := strings.TrimPrefix(listenAddr, ":")
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Invalid listen address")
|
||||
}
|
||||
|
||||
serviceName := "config"
|
||||
instanceID := fmt.Sprint(hash(fmt.Sprintf("%s-%s-%d", serviceName, host, port)))[:8]
|
||||
|
||||
err = serviceReg.Register(serviceName, "http", instanceID, host, port, 30)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to register service")
|
||||
}
|
||||
log.Info().Str("service", serviceName).Str("instanceID", instanceID).Msg("Service registered successfully")
|
||||
|
||||
// --- Web Server ---
|
||||
app := fiber.New(fiber.Config{
|
||||
ServerHeader: "Turbine Config",
|
||||
})
|
||||
|
||||
// This is the main endpoint that serves the configuration as JSON.
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
log.Info().Msg("Serving shared configuration as JSON")
|
||||
|
||||
// Use a new Viper instance to read the shared config
|
||||
v := viper.New()
|
||||
v.SetConfigName("shared_config")
|
||||
v.AddConfigPath(".") // Look in the current directory (pkg/config)
|
||||
v.SetConfigType("toml")
|
||||
|
||||
if err := v.ReadInConfig(); err != nil {
|
||||
log.Error().Err(err).Msg("Failed to read shared_config.toml")
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "could not load configuration",
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(v.AllSettings())
|
||||
})
|
||||
|
||||
// Health check endpoint
|
||||
app.Get("/health", func(c fiber.Ctx) error {
|
||||
return c.SendString("Config service is running")
|
||||
})
|
||||
|
||||
// --- Graceful Shutdown ---
|
||||
go func() {
|
||||
err := app.Listen(listenAddr, fiber.ListenConfig{DisableStartupMessage: true})
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to start server")
|
||||
}
|
||||
}()
|
||||
log.Info().Msg("Server is listening on " + listenAddr)
|
||||
|
||||
stop := make(chan os.Signal, 1)
|
||||
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-stop
|
||||
|
||||
log.Info().Msg("Shutting down service...")
|
||||
if err := serviceReg.Deregister(); err != nil {
|
||||
log.Error().Err(err).Msg("Failed to deregister service")
|
||||
} else {
|
||||
log.Info().Msg("Service deregistered successfully")
|
||||
}
|
||||
|
||||
if err := app.Shutdown(); err != nil {
|
||||
log.Error().Err(err).Msg("Error during server shutdown")
|
||||
}
|
||||
}
|
||||
12
pkg/config/settings.toml
Normal file
12
pkg/config/settings.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
# The address the config service will listen on
|
||||
listen = ":8081"
|
||||
|
||||
# The host address to register with etcd.
|
||||
# This should be the address that other services can use to reach this service.
|
||||
# For local testing, 127.0.0.1 is fine. In production, this should be a reachable IP.
|
||||
host = "127.0.0.1"
|
||||
|
||||
# ETCD configuration for service registration
|
||||
[etcd]
|
||||
endpoints = ["etcd.orb.local:2379"]
|
||||
insecure = true
|
||||
5
pkg/config/shared_config.toml
Normal file
5
pkg/config/shared_config.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
[database]
|
||||
connection_string = "postgres://user:password@db-host:5432/mydatabase?sslmode=require"
|
||||
|
||||
[redis]
|
||||
address = "redis-host:6379"
|
||||
Reference in New Issue
Block a user