From 7981260f22a0f3ba376fefae5c02712d0e6da051 Mon Sep 17 00:00:00 2001 From: Sven Rebhan <36194019+srebhan@users.noreply.github.com> Date: Thu, 9 Mar 2023 11:54:27 +0100 Subject: [PATCH] feat(agent): Add command-line option to specify password (#12812) --- cmd/telegraf/cmd_secretstore.go | 6 +++++- cmd/telegraf/main.go | 5 +++++ cmd/telegraf/telegraf.go | 6 ++++++ config/config.go | 3 +++ plugins/secretstores/jose/jose.go | 20 +++++++++++++------- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/cmd/telegraf/cmd_secretstore.go b/cmd/telegraf/cmd_secretstore.go index dae87f583..ed4368d5d 100644 --- a/cmd/telegraf/cmd_secretstore.go +++ b/cmd/telegraf/cmd_secretstore.go @@ -8,9 +8,10 @@ import ( "sort" "strings" - "github.com/influxdata/telegraf/config" "github.com/urfave/cli/v2" "golang.org/x/term" + + "github.com/influxdata/telegraf/config" ) func processFilterOnlySecretStoreFlags(ctx *cli.Context) Filters { @@ -78,6 +79,7 @@ To also reveal the actual secret, i.e. the value, you can pass the config: cCtx.StringSlice("config"), configDir: cCtx.StringSlice("config-directory"), plugindDir: cCtx.String("plugin-directory"), + password: cCtx.String("password"), debug: cCtx.Bool("debug"), } w := WindowFlags{} @@ -155,6 +157,7 @@ with the ID 'mystore'. config: cCtx.StringSlice("config"), configDir: cCtx.StringSlice("config-directory"), plugindDir: cCtx.String("plugin-directory"), + password: cCtx.String("password"), debug: cCtx.Bool("debug"), } w := WindowFlags{} @@ -218,6 +221,7 @@ you will be prompted to enter the value of the secret. config: cCtx.StringSlice("config"), configDir: cCtx.StringSlice("config-directory"), plugindDir: cCtx.String("plugin-directory"), + password: cCtx.String("password"), debug: cCtx.Bool("debug"), } w := WindowFlags{} diff --git a/cmd/telegraf/main.go b/cmd/telegraf/main.go index a8a78775d..65bcda89a 100644 --- a/cmd/telegraf/main.go +++ b/cmd/telegraf/main.go @@ -224,6 +224,7 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi watchConfig: cCtx.String("watch-config"), pidFile: cCtx.String("pidfile"), plugindDir: cCtx.String("plugin-directory"), + password: cCtx.String("password"), test: cCtx.Bool("test"), debug: cCtx.Bool("debug"), once: cCtx.Bool("once"), @@ -281,6 +282,10 @@ func runApp(args []string, outputBuffer io.Writer, pprof Server, c TelegrafConfi Name: "pidfile", Usage: "file to write our pid to", }, + &cli.StringFlag{ + Name: "password", + Usage: "password to unlock secret-stores", + }, // // Bool flags &cli.BoolFlag{ diff --git a/cmd/telegraf/telegraf.go b/cmd/telegraf/telegraf.go index 2f4b4d138..03fe78889 100644 --- a/cmd/telegraf/telegraf.go +++ b/cmd/telegraf/telegraf.go @@ -38,6 +38,7 @@ type GlobalFlags struct { watchConfig string pidFile string plugindDir string + password string test bool debug bool once bool @@ -81,6 +82,11 @@ func (t *Telegraf) Init(pprofErr <-chan error, f Filters, g GlobalFlags, w Windo t.secretstoreFilters = f.secretstore t.GlobalFlags = g t.WindowFlags = w + + // Set global password + if g.password != "" { + config.Password = config.NewSecret([]byte(g.password)) + } } func (t *Telegraf) ListSecretStores() ([]string, error) { diff --git a/config/config.go b/config/config.go index 4ba5ca31c..7863856cc 100644 --- a/config/config.go +++ b/config/config.go @@ -51,6 +51,9 @@ var ( // fetchURLRe is a regex to determine whether the requested file should // be fetched from a remote or read from the filesystem. fetchURLRe = regexp.MustCompile(`^\w+://`) + + // Password specified via command-line + Password Secret ) // Config specifies the URL/user/password for the database that telegraf diff --git a/plugins/secretstores/jose/jose.go b/plugins/secretstores/jose/jose.go index a86f28d99..2f9f87fac 100644 --- a/plugins/secretstores/jose/jose.go +++ b/plugins/secretstores/jose/jose.go @@ -40,15 +40,21 @@ func (j *Jose) Init() error { return errors.New("path missing") } - passwd, err := j.Password.Get() - if err != nil { - return fmt.Errorf("getting password failed: %w", err) - } - defer config.ReleaseSecret(passwd) - // Create the prompt-function in case we need it promptFunc := keyring.TerminalPrompt - if len(passwd) != 0 { + if !j.Password.Empty() { + passwd, err := j.Password.Get() + if err != nil { + return fmt.Errorf("getting password failed: %w", err) + } + defer config.ReleaseSecret(passwd) + promptFunc = keyring.FixedStringPrompt(string(passwd)) + } else if !config.Password.Empty() { + passwd, err := config.Password.Get() + if err != nil { + return fmt.Errorf("getting global password failed: %w", err) + } + defer config.ReleaseSecret(passwd) promptFunc = keyring.FixedStringPrompt(string(passwd)) }