Skip to content

Commit

Permalink
Merge pull request #1516 from lawliet89/http-token-file
Browse files Browse the repository at this point in the history
Add support for providing Consul ACL Token via a file
  • Loading branch information
eikenb committed Jan 26, 2022
2 parents 6ae6d3b + 495ba7d commit fc22b48
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ The current processes environment is used when executing commands with the follo

- `CONSUL_HTTP_ADDR`
- `CONSUL_HTTP_TOKEN`
- `CONSUL_HTTP_TOKEN_FILE`
- `CONSUL_HTTP_AUTH`
- `CONSUL_HTTP_SSL`
- `CONSUL_HTTP_SSL_VERIFY`
Expand Down
8 changes: 8 additions & 0 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ func (cli *CLI) ParseFlags(args []string) (
return nil
}), "consul-token", "")

flags.Var((funcVar)(func(s string) error {
c.Consul.TokenFile = config.String(s)
return nil
}), "consul-token-file", "")

flags.Var((funcDurationVar)(func(d time.Duration) error {
c.Consul.Transport.DialKeepAlive = config.TimeDuration(d)
return nil
Expand Down Expand Up @@ -700,6 +705,9 @@ Options:
-consul-token=<token>
Sets the Consul API token
-consul-token-file=<path>
Sets the path to a file containing the Consul API token
-consul-transport-dial-keep-alive=<duration>
Sets the amount of time to use for keep-alives
Expand Down
10 changes: 10 additions & 0 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,16 @@ func TestCLI_ParseFlags(t *testing.T) {
},
false,
},
{
"consul-token-file",
[]string{"-consul-token-file", "/a/very/secret/path"},
&config.Config{
Consul: &config.ConsulConfig{
TokenFile: config.String("/a/very/secret/path"),
},
},
false,
},
{
"consul-transport-dial-keep-alive",
[]string{"-consul-transport-dial-keep-alive", "30s"},
Expand Down
17 changes: 17 additions & 0 deletions config/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type ConsulConfig struct {
// Token is the token to communicate with Consul securely.
Token *string

// TokenFile is the path to a token to communicate with Consul securely.
TokenFile *string `mapstructure:"token_file"`

// Transport configures the low-level network connection details.
Transport *TransportConfig `mapstructure:"transport"`
}
Expand Down Expand Up @@ -65,6 +68,7 @@ func (c *ConsulConfig) Copy() *ConsulConfig {
}

o.Token = c.Token
o.TokenFile = c.TokenFile

if c.Transport != nil {
o.Transport = c.Transport.Copy()
Expand Down Expand Up @@ -115,6 +119,10 @@ func (c *ConsulConfig) Merge(o *ConsulConfig) *ConsulConfig {
r.Token = o.Token
}

if o.TokenFile != nil {
r.TokenFile = o.TokenFile
}

if o.Transport != nil {
r.Transport = r.Transport.Merge(o.Transport)
}
Expand Down Expand Up @@ -156,6 +164,13 @@ func (c *ConsulConfig) Finalize() {
}, "")
}

if c.TokenFile == nil {
c.TokenFile = stringFromEnv([]string{
"CONSUL_TOKEN_FILE",
"CONSUL_HTTP_TOKEN_FILE",
}, "")
}

if c.Transport == nil {
c.Transport = DefaultTransportConfig()
}
Expand All @@ -175,6 +190,7 @@ func (c *ConsulConfig) GoString() string {
"Retry:%#v, "+
"SSL:%#v, "+
"Token:%t, "+
"TokenFile:%s, "+
"Transport:%#v"+
"}",
StringGoString(c.Address),
Expand All @@ -183,6 +199,7 @@ func (c *ConsulConfig) GoString() string {
c.Retry,
c.SSL,
StringPresent(c.Token),
StringGoString(c.TokenFile),
c.Transport,
)
}
28 changes: 27 additions & 1 deletion config/consul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestConsulConfig_Copy(t *testing.T) {
Retry: &RetryConfig{Enabled: Bool(true)},
SSL: &SSLConfig{Enabled: Bool(true)},
Token: String("abcd1234"),
TokenFile: String("/a/very/secret/path"),
Transport: &TransportConfig{
DialKeepAlive: TimeDuration(20 * time.Second),
},
Expand Down Expand Up @@ -223,6 +224,30 @@ func TestConsulConfig_Merge(t *testing.T) {
&ConsulConfig{Token: String("same")},
&ConsulConfig{Token: String("same")},
},
{
"token_file_overrides",
&ConsulConfig{TokenFile: String("same")},
&ConsulConfig{TokenFile: String("different")},
&ConsulConfig{TokenFile: String("different")},
},
{
"token_file_empty_one",
&ConsulConfig{TokenFile: String("same")},
&ConsulConfig{},
&ConsulConfig{TokenFile: String("same")},
},
{
"token_file_empty_two",
&ConsulConfig{},
&ConsulConfig{TokenFile: String("same")},
&ConsulConfig{TokenFile: String("same")},
},
{
"token_file_same",
&ConsulConfig{TokenFile: String("same")},
&ConsulConfig{TokenFile: String("same")},
&ConsulConfig{TokenFile: String("same")},
},
{
"transport_overrides",
&ConsulConfig{Transport: &TransportConfig{DialKeepAlive: TimeDuration(10 * time.Second)}},
Expand Down Expand Up @@ -292,7 +317,8 @@ func TestConsulConfig_Finalize(t *testing.T) {
ServerName: String(""),
Verify: Bool(true),
},
Token: String(""),
Token: String(""),
TokenFile: String(""),
Transport: &TransportConfig{
DialKeepAlive: TimeDuration(DefaultDialKeepAlive),
DialTimeout: TimeDuration(DefaultDialTimeout),
Expand Down
5 changes: 5 additions & 0 deletions dependency/client_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type CreateConsulClientInput struct {
Address string
Namespace string
Token string
TokenFile string
AuthEnabled bool
AuthUsername string
AuthPassword string
Expand Down Expand Up @@ -116,6 +117,10 @@ func (c *ClientSet) CreateConsulClient(i *CreateConsulClientInput) error {
consulConfig.Token = i.Token
}

if i.TokenFile != "" {
consulConfig.TokenFile = i.TokenFile
}

if i.AuthEnabled {
consulConfig.HttpAuth = &consulapi.HttpBasicAuth{
Username: i.AuthUsername,
Expand Down
9 changes: 8 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,18 @@ consul {
# This is the ACL token to use when connecting to Consul. If you did not
# enable ACLs on your Consul cluster, you do not need to set this option.
#
# This option is also available via the environment variable CONSUL_TOKEN.
# This option is also available via the environment variable CONSUL_TOKEN or
# CONSUL_HTTP_TOKEN
# It is highly recommended that you do not put your token in plain-text in a
# configuration file.
token = ""
# Alternatively, you can specify a path to a file containing the token with
# this option.
# This option is also available via the environment variable CONSUL_TOKEN_FILE or
# CONSUL_HTTP_TOKEN_FILE
token_file = ""
# This controls the retry behavior when an error is returned from Consul.
# Consul Template is highly fault tolerant, meaning it does not exit in the
# face of failure. Instead, it uses exponential back-off and retry functions
Expand Down
9 changes: 9 additions & 0 deletions manager/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,14 @@ func (r *Runner) childEnv() []string {
m["CONSUL_HTTP_AUTH"] = r.config.Consul.Auth.String()
}

if config.StringPresent(r.config.Consul.Token) {
m["CONSUL_HTTP_TOKEN"] = config.StringVal(r.config.Consul.Token)
}

if config.StringPresent(r.config.Consul.TokenFile) {
m["CONSUL_HTTP_TOKEN_FILE"] = config.StringVal(r.config.Consul.TokenFile)
}

m["CONSUL_HTTP_SSL"] = strconv.FormatBool(config.BoolVal(r.config.Consul.SSL.Enabled))
m["CONSUL_HTTP_SSL_VERIFY"] = strconv.FormatBool(config.BoolVal(r.config.Consul.SSL.Verify))

Expand Down Expand Up @@ -1251,6 +1259,7 @@ func newClientSet(c *config.Config) (*dep.ClientSet, error) {
Address: config.StringVal(c.Consul.Address),
Namespace: config.StringVal(c.Consul.Namespace),
Token: config.StringVal(c.Consul.Token),
TokenFile: config.StringVal(c.Consul.TokenFile),
AuthEnabled: config.BoolVal(c.Consul.Auth.Enabled),
AuthUsername: config.StringVal(c.Consul.Auth.Username),
AuthPassword: config.StringVal(c.Consul.Auth.Password),
Expand Down

0 comments on commit fc22b48

Please sign in to comment.