diff --git a/changelog/1.0.0_2023-10-26/file-secrets.md b/changelog/1.0.0_2023-10-26/file-secrets.md new file mode 100644 index 0000000..5973a26 --- /dev/null +++ b/changelog/1.0.0_2023-10-26/file-secrets.md @@ -0,0 +1,7 @@ +Change: Read secrets form files + +We have added proper support to load secrets like tokens from files or from +base64-encoded strings. Just provide the flags or environment variables with a +DSN formatted string like `file://path/to/file` or `base64://Zm9vYmFy`. + +https://github.com/promhippie/prometheus-hcloud-sd/pulls/ diff --git a/changelog/1.0.0_2023-10-26/update-deps.md b/changelog/1.0.0_2023-10-26/update-deps.md new file mode 100644 index 0000000..8c9dd47 --- /dev/null +++ b/changelog/1.0.0_2023-10-26/update-deps.md @@ -0,0 +1,7 @@ +Enhancement: Update all releated dependencies + +We've updated all dependencies to the latest available versions, including more +current versions of build tools and used Go version to build the binaries. It's +time to mark a stable release. + +https://github.com/promhippie/prometheus-hcloud-sd/pulls/ diff --git a/pkg/action/server.go b/pkg/action/server.go index 39688ad..4bc233e 100644 --- a/pkg/action/server.go +++ b/pkg/action/server.go @@ -2,6 +2,7 @@ package action import ( "context" + "fmt" "io" "net/http" "os" @@ -39,9 +40,21 @@ func Server(cfg *config.Config, logger log.Logger) error { clients := make(map[string]*hcloud.Client, len(cfg.Target.Credentials)) for _, credential := range cfg.Target.Credentials { + token, err := config.Value(credential.Token) + + if err != nil { + level.Error(logger).Log( + "msg", "Failed to read token secret", + "project", credential.Project, + "err", err, + ) + + return fmt.Errorf("failed to read token secret for %s", credential.Project) + } + clients[credential.Project] = hcloud.NewClient( hcloud.WithToken( - credential.Token, + token, ), ) } diff --git a/pkg/config/config.go b/pkg/config/config.go index dafedbf..116660f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,5 +1,12 @@ package config +import ( + "encoding/base64" + "fmt" + "os" + "strings" +) + // Credential defines a single project credential. type Credential struct { Project string `json:"project" yaml:"project"` @@ -42,3 +49,32 @@ func Load() *Config { }, } } + +// Value returns the config value based on a DSN. +func Value(val string) (string, error) { + if strings.HasPrefix(val, "file://") { + content, err := os.ReadFile( + strings.TrimPrefix(val, "file://"), + ) + + if err != nil { + return "", fmt.Errorf("failed to parse secret file: %w", err) + } + + return string(content), nil + } + + if strings.HasPrefix(val, "base64://") { + content, err := base64.StdEncoding.DecodeString( + strings.TrimPrefix(val, "base64://"), + ) + + if err != nil { + return "", fmt.Errorf("failed to parse base64 value: %w", err) + } + + return string(content), nil + } + + return val, nil +}