smartconfig/resolver_etcd.go
sneak 8a38afba5e passes tests, has cli filter now.
* still has not been *really* tested yet
2025-07-20 15:29:06 +02:00

51 lines
1.2 KiB
Go

package smartconfig
import (
"context"
"fmt"
"os"
"strings"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
)
// EtcdResolver retrieves values from etcd.
// Usage: ${ETCD:/myapp/config/key}
// Requires ETCD_ENDPOINTS environment variable or defaults to localhost:2379
type EtcdResolver struct{}
// Resolve retrieves the value from etcd.
func (r *EtcdResolver) Resolve(value string) (string, error) {
// Default to localhost:2379 if ETCD_ENDPOINTS is not set
endpoints := strings.Split(os.Getenv("ETCD_ENDPOINTS"), ",")
if len(endpoints) == 1 && endpoints[0] == "" {
endpoints = []string{"localhost:2379"}
}
cli, err := clientv3.New(clientv3.Config{
Endpoints: endpoints,
DialTimeout: 5 * time.Second,
})
if err != nil {
return "", fmt.Errorf("failed to create etcd client: %w", err)
}
defer func() {
_ = cli.Close()
}()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
resp, err := cli.Get(ctx, value)
if err != nil {
return "", fmt.Errorf("failed to get key %s from etcd: %w", value, err)
}
if len(resp.Kvs) == 0 {
return "", fmt.Errorf("key %s not found in etcd", value)
}
return string(resp.Kvs[0].Value), nil
}