namsral/flag

Reading individual values from files (eg. docker secrets)

jgimenez opened this issue · 3 comments

I'd find it useful to read certain parameters from a file, so for example say I have a password command line flag defined. I'd use it like -password=1234 with the flags package, and this package also adds compatibility with PASSWORD=1234 environment variable to fill it in. It would be even better if I could fill it in with a secret, like PASSWORD_FILE=/secrets/password.

I came here searching for this feature as well. Unfortunately, the magic 8-ball says "Outlook not so good". This project has a small number of PRs in the queue and no updates in quite a number of years. :(

Ruminating on this issue, this is definitely something that breaks current implementations.

Docker Secrets standards use _FILE appended to the name of the variable to indicate the variable (as you explained above), but there's nothing stopping me from having an actual PASSWORD_FILE variable, that really points to a file, that's not a docker secret.

In that case, I don't want to read a docker secret PASSWORD, I want the variable PASSWORD_FILE. So that means using secrets will have to be a build-time decision.

Perhaps setting flag.Secrets = true could trigger the alternate usage. At that point, I'm hesitant to put it upstream. It really is coding for a specific environment, that's not a majority, which I do not believe belongs in this package.

Believe me, I want it automagically too, that's why I came here. However, it might just be simpler to use github.com/ijustfool/docker-secrets and code for whichever variables you want to use _FILE for.

It's ugly, but functional.

package main

import (
	"fmt"

	secrets "github.com/ijustfool/docker-secrets"
	"github.com/namsral/flag"
)

var word = flag.String("word", "bird", "string")
var wordFile = flag.String("word_file", "", "string")

func main() {
	flag.Parse()

	if *wordFile != "" {
		dockerSecrets, _ := secrets.NewDockerSecrets(".")
		secret, _ := dockerSecrets.Get("word")
		*word = secret
	}
	fmt.Printf("word: %s\n", *word)
}
❯ cat food
pizza
❯ go run main.go -word banana
word: banana
❯ go run main.go -word_file food
word: pizza

Probably this is less important now because k8s can pass secrets as both environment variables or files.