Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read flag value from file (Kubernetes, Docker Swarm) #613

Closed
bradrydzewski opened this issue Mar 31, 2017 · 5 comments
Closed

Read flag value from file (Kubernetes, Docker Swarm) #613

bradrydzewski opened this issue Mar 31, 2017 · 5 comments

Comments

@bradrydzewski
Copy link
Contributor

bradrydzewski commented Mar 31, 2017

I would like to propose new functionality (which I'm willing to implement) to load individual arguments from file:

type StringFlag struct {
	Name        string
	Usage       string
	EnvVar      string
+	FilePath    string
	Hidden      bool
	Value       string
	Destination *string
}

When declaring flags one could specify an optional path for loading the value:

cli.StringFlag{
	Name: "mysql-password",
	EnvVar: "MYSQL_PASSWORD",
+	File: "/run/secrets/mysql_password",
}

This is functionally similar to loading a flag value from environment variable. If you follow the 12-factor pattern loading values from environment variable can be very helpful. If you are using systems like Docker Swarm and Kubernetes you may desire to load parameters from the contents of mounted files [1][2]

An example use case would be starting my server with a mysql password. When using Kubernetes or Docker swarm I might choose to load this parameter value from the filesystem using the built-in secret stores.

So for local development I might provide the mysql password using a flag:

$ ./app --mysql-password=<value>

For a 12 factor deployment I might provide the mysql password using an environment variable:

$ MYSQL_PASSWORD=<value> ./app

And for a Kubernetes or Swarm deployment I might source the mysql password using the built-in secret capabilities of the platform, from the file system.

$ docker secret create mysql_password <value>
$ docker run --secret=mysql_password ...

The implementation would be pretty straightforward:

if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
	envValDuration, err := time.ParseDuration(envVal)
	if err != nil {
		return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err)
	}

	f.Value = envValDuration
}

[1] https://docs.docker.com/engine/swarm/secrets/#simple-example-get-started-with-secrets
[2] https://kubernetes.io/docs/user-guide/secrets/#using-secrets-as-files-from-a-pod

@bradrydzewski bradrydzewski changed the title Read Arg from File (Kubernetes, Docker Swarm) Read flag value from file (Kubernetes, Docker Swarm) Mar 31, 2017
@jmalloc
Copy link

jmalloc commented Mar 31, 2017

As a user who is interested in this functionality for the same reasons (Docker specifically), I'd like to suggest allowing the filename to be specified via a second environment variable, so as to avoid hard-coding the details of Docker's /run/secrets filesystem layout into the binary.

cli.StringFlag{
	Name: "mysql-password",
	EnvVar: "MYSQL_PASSWORD",
+	FileEnvVar: "MYSQL_PASSWORD_FILE",
}

This also has the advantage of allowing the flag to be omitted by simply not defining any of the environment variables or setting them to empty, rather than having to remove the file from disk.

@bradrydzewski
Copy link
Contributor Author

Baseline pull request at #614

@gravis
Copy link
Member

gravis commented Apr 2, 2017

Would love to see this merged :)

@marcbachmann
Copy link

I agree with @jmalloc. Pointing to a specific file using an env var is much more flexible. Not all platforms use the same path. That pattern is also pretty common nowadays.

@bradrydzewski
Copy link
Contributor Author

closing now that #675 is merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants