51 lines
1.2 KiB
Go
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
|
|
}
|