diff --git a/client/config/config.go b/client/config/config.go index d9e9b409d..316ba2449 100644 --- a/client/config/config.go +++ b/client/config/config.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/nomad/client/lib/numalib" "github.com/hashicorp/nomad/client/state" "github.com/hashicorp/nomad/command/agent/host" + "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/helper/bufconndialer" "github.com/hashicorp/nomad/helper/pluginutils/loader" "github.com/hashicorp/nomad/helper/pointer" @@ -171,9 +172,14 @@ type Config struct { // ConsulConfig is this Agent's Consul configuration ConsulConfig *structsc.ConsulConfig - // VaultConfig is this Agent's Vault configuration + // VaultConfig is this Agent's default Vault configuration VaultConfig *structsc.VaultConfig + // VaultConfigs is a map of Vault configurations, here to support features + // in Nomad Enterprise. The default Vault config pointer above will be found + // in this map under the name "default" + VaultConfigs map[string]*structsc.VaultConfig + // StatsCollectionInterval is the interval at which the Nomad client // collects resource usage stats StatsCollectionInterval time.Duration @@ -748,6 +754,7 @@ func (c *Config) Copy() *Config { nc.HostVolumes = structs.CopyMapStringClientHostVolumeConfig(nc.HostVolumes) nc.ConsulConfig = c.ConsulConfig.Copy() nc.VaultConfig = c.VaultConfig.Copy() + nc.VaultConfigs = helper.DeepCopyMap(c.VaultConfigs) nc.TemplateConfig = c.TemplateConfig.Copy() nc.ReservableCores = slices.Clone(c.ReservableCores) nc.Artifact = c.Artifact.Copy() @@ -756,7 +763,7 @@ func (c *Config) Copy() *Config { // DefaultConfig returns the default configuration func DefaultConfig() *Config { - return &Config{ + cfg := &Config{ Version: version.GetVersion(), VaultConfig: structsc.DefaultVaultConfig(), ConsulConfig: structsc.DefaultConsulConfig(), @@ -798,6 +805,10 @@ func DefaultConfig() *Config { MaxDynamicPort: structs.DefaultMinDynamicPort, MinDynamicPort: structs.DefaultMaxDynamicPort, } + + cfg.VaultConfigs = map[string]*structsc.VaultConfig{ + "default": cfg.VaultConfig} + return cfg } // Read returns the specified configuration value or "". diff --git a/client/config/testing.go b/client/config/testing.go index 166f10839..8382549f4 100644 --- a/client/config/testing.go +++ b/client/config/testing.go @@ -69,6 +69,7 @@ func TestClientConfig(t testing.T) (*Config, func()) { conf.CgroupParent = "testing.slice" conf.VaultConfig.Enabled = pointer.Of(false) + conf.VaultConfigs["default"].Enabled = pointer.Of(false) conf.DevMode = true // Loosen GC threshold diff --git a/command/agent/agent.go b/command/agent/agent.go index f53b57a3e..95ad815e1 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -507,7 +507,11 @@ func convertServerConfig(agentConfig *Config) (*nomad.Config, error) { // Add the Consul and Vault configs conf.ConsulConfig = agentConfig.Consul + conf.VaultConfig = agentConfig.Vault + for _, vaultConfig := range agentConfig.Vaults { + conf.VaultConfigs[vaultConfig.Name] = vaultConfig + } // Set the TLS config conf.TLSConfig = agentConfig.TLSConfig @@ -799,7 +803,11 @@ func convertClientConfig(agentConfig *Config) (*clientconfig.Config, error) { } conf.ConsulConfig = agentConfig.Consul + conf.VaultConfig = agentConfig.Vault + for _, vaultConfig := range agentConfig.Vaults { + conf.VaultConfigs[vaultConfig.Name] = vaultConfig + } // Set up Telemetry configuration conf.StatsCollectionInterval = agentConfig.Telemetry.collectionInterval diff --git a/command/agent/agent_endpoint.go b/command/agent/agent_endpoint.go index 526420e47..b1a49d840 100644 --- a/command/agent/agent_endpoint.go +++ b/command/agent/agent_endpoint.go @@ -89,6 +89,11 @@ func (s *HTTPServer) AgentSelfRequest(resp http.ResponseWriter, req *http.Reques if self.Config != nil && self.Config.Vault != nil && self.Config.Vault.Token != "" { self.Config.Vault.Token = "" } + for _, vaultConfig := range self.Config.Vaults { + if vaultConfig.Token != "" { + vaultConfig.Token = "" + } + } if self.Config != nil && self.Config.ACL != nil && self.Config.ACL.ReplicationToken != "" { self.Config.ACL.ReplicationToken = "" diff --git a/command/agent/command.go b/command/agent/command.go index 86da797eb..3edf97b80 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -77,6 +77,7 @@ func (c *Command) readConfig() *Config { ACL: &ACLConfig{}, Audit: &config.AuditConfig{}, } + cmdConfig.Vaults = map[string]*config.VaultConfig{"default": cmdConfig.Vault} flags := flag.NewFlagSet("agent", flag.ContinueOnError) flags.Usage = func() { c.Ui.Error(c.Help()) } diff --git a/command/agent/config.go b/command/agent/config.go index ccc86ad21..abf3eb69f 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -136,9 +136,17 @@ type Config struct { // discover the current Nomad servers. Consul *config.ConsulConfig `hcl:"consul"` - // Vault contains the configuration for the Vault Agent and + // Vault contains the configuration for the default Vault Agent and // parameters necessary to derive tokens. - Vault *config.VaultConfig `hcl:"vault"` + // + // TODO(tgross): we'll probably want to remove this field once we've added a + // selector so that we don't have to maintain it + Vault *config.VaultConfig + + // Vaults is a map derived from multiple `vault` blocks, here to support + // features in Nomad Enterprise. The default Vault config pointer above will + // be found in this map under the name "default" + Vaults map[string]*config.VaultConfig // UI is used to configure the web UI UI *config.UIConfig `hcl:"ui"` @@ -1264,7 +1272,7 @@ func DevConfig(mode *devModeConfig) *Config { // DefaultConfig is the baseline configuration for Nomad. func DefaultConfig() *Config { - return &Config{ + cfg := &Config{ LogLevel: "INFO", Region: "global", Datacenter: "dc1", @@ -1355,6 +1363,9 @@ func DefaultConfig() *Config { DisableUpdateCheck: pointer.Of(false), Limits: config.DefaultLimits(), } + + cfg.Vaults = map[string]*config.VaultConfig{"default": cfg.Vault} + return cfg } // Listener can be used to get a new listener using a custom bind address. @@ -1522,13 +1533,9 @@ func (c *Config) Merge(b *Config) *Config { result.Consul = result.Consul.Merge(b.Consul) } - // Apply the Vault Configuration - if result.Vault == nil && b.Vault != nil { - vaultConfig := *b.Vault - result.Vault = &vaultConfig - } else if b.Vault != nil { - result.Vault = result.Vault.Merge(b.Vault) - } + // Apply the Vault Configurations and overwrite the default Vault config + result.Vaults = mergeVaultConfigs(result.Vaults, b.Vaults) + result.Vault = result.Vaults["default"] // Apply the UI Configuration if result.UI == nil && b.UI != nil { @@ -1579,6 +1586,21 @@ func (c *Config) Merge(b *Config) *Config { return &result } +func mergeVaultConfigs(left, right map[string]*config.VaultConfig) map[string]*config.VaultConfig { + merged := helper.DeepCopyMap(left) + if left == nil { + merged = map[string]*config.VaultConfig{} + } + for name, rConfig := range right { + if lConfig, ok := left[name]; ok { + merged[name] = lConfig.Merge(rConfig) + } else { + merged[name] = rConfig.Copy() + } + } + return merged +} + // Copy returns a deep copy safe for mutation. func (c *Config) Copy() *Config { if c == nil { @@ -1597,6 +1619,7 @@ func (c *Config) Copy() *Config { nc.DisableUpdateCheck = pointer.Copy(c.DisableUpdateCheck) nc.Consul = c.Consul.Copy() nc.Vault = c.Vault.Copy() + nc.Vaults = helper.DeepCopyMap(c.Vaults) nc.UI = c.UI.Copy() nc.NomadConfig = c.NomadConfig.Copy() diff --git a/command/agent/config_parse.go b/command/agent/config_parse.go index e5d02b75b..13ad29360 100644 --- a/command/agent/config_parse.go +++ b/command/agent/config_parse.go @@ -12,9 +12,11 @@ import ( "time" "github.com/hashicorp/hcl" + "github.com/hashicorp/hcl/hcl/ast" client "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/nomad/structs/config" + "github.com/mitchellh/mapstructure" ) // ParseConfigFile returns an agent.Config from parsed from a file. @@ -57,6 +59,7 @@ func ParseConfigFile(path string) (*Config, error) { Autopilot: &config.AutopilotConfig{}, Telemetry: &Telemetry{}, Vault: &config.VaultConfig{}, + Vaults: map[string]*config.VaultConfig{}, } err = hcl.Decode(c, buf.String()) @@ -156,6 +159,23 @@ func ParseConfigFile(path string) (*Config, error) { return nil, err } + // Re-parse the file to extract the multiple Vault configurations, which we + // need to parse by hand because we don't have a label on the block + root, err := hcl.Parse(buf.String()) + if err != nil { + return nil, fmt.Errorf("failed to parse HCL file %s: %w", path, err) + } + list, ok := root.Node.(*ast.ObjectList) + if !ok { + return nil, fmt.Errorf("error parsing: root should be an object") + } + matches := list.Filter("vault") + if len(matches.Items) > 0 { + if err := parseVaults(c, matches); err != nil { + return nil, fmt.Errorf("error parsing 'vault': %w", err) + } + } + // report unexpected keys err = extraKeys(c) if err != nil { @@ -261,6 +281,10 @@ func extraKeys(c *Config) error { helper.RemoveEqualFold(&c.ExtraKeysHCL, "telemetry") } + // The `vault` blocks are parsed separately from the Decode method, so it + // will incorrectly report them as extra keys + helper.RemoveEqualFold(&c.ExtraKeysHCL, "vault") + return helper.UnusedKeys(c) } @@ -293,3 +317,35 @@ func finalizeClientTemplateConfig(config *Config) { config.Client.TemplateConfig = nil } } + +// parseVaults decodes the `vault` blocks. The hcl.Decode method can't parse +// these correctly as HCL1 because they don't have labels, which would result in +// all the blocks getting merged regardless of name. +func parseVaults(c *Config, list *ast.ObjectList) error { + if len(list.Items) == 0 { + return nil + } + + for _, obj := range list.Items { + var m map[string]interface{} + if err := hcl.DecodeObject(&m, obj.Val); err != nil { + return err + } + v := &config.VaultConfig{} + err := mapstructure.WeakDecode(m, v) + if err != nil { + return err + } + if v.Name == "" { + v.Name = "default" + } + if exist, ok := c.Vaults[v.Name]; ok { + c.Vaults[v.Name] = exist.Merge(v) + } else { + c.Vaults[v.Name] = v + } + } + + c.Vault = c.Vaults["default"] + return nil +} diff --git a/command/agent/config_parse_test.go b/command/agent/config_parse_test.go index 43db00c30..192e0c3fc 100644 --- a/command/agent/config_parse_test.go +++ b/command/agent/config_parse_test.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/nomad/helper/pointer" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs/config" + "github.com/shoenig/test/must" "github.com/stretchr/testify/require" ) @@ -235,6 +236,7 @@ var basicConfig = &Config{ TimeoutHCL: "5s", }, Vault: &config.VaultConfig{ + Name: "default", Addr: "127.0.0.1:9500", AllowUnauthenticated: &trueValue, ConnectionRetryIntv: config.DefaultVaultConnectRetryIntv, @@ -249,6 +251,24 @@ var basicConfig = &Config{ TaskTokenTTL: "1s", Token: "12345", }, + Vaults: map[string]*config.VaultConfig{ + "default": { + Name: "default", + Addr: "127.0.0.1:9500", + AllowUnauthenticated: &trueValue, + ConnectionRetryIntv: config.DefaultVaultConnectRetryIntv, + Enabled: &falseValue, + Role: "test_role", + TLSCaFile: "/path/to/ca/file", + TLSCaPath: "/path/to/ca", + TLSCertFile: "/path/to/cert/file", + TLSKeyFile: "/path/to/key/file", + TLSServerName: "foobar", + TLSSkipVerify: &trueValue, + TaskTokenTTL: "1s", + Token: "12345", + }, + }, TLSConfig: &config.TLSConfig{ EnableHTTP: true, EnableRPC: true, @@ -360,6 +380,7 @@ var pluginConfig = &Config{ DisableAnonymousSignature: false, Consul: nil, Vault: nil, + Vaults: map[string]*config.VaultConfig{}, TLSConfig: nil, HTTPAPIResponseHeaders: map[string]string{}, Sentinel: nil, @@ -512,6 +533,7 @@ func TestConfig_Parse(t *testing.T) { oldDefault := &Config{ Consul: config.DefaultConsulConfig(), Vault: config.DefaultVaultConfig(), + Vaults: map[string]*config.VaultConfig{"default": config.DefaultVaultConfig()}, Autopilot: config.DefaultAutopilotConfig(), } actual = oldDefault.Merge(actual) @@ -552,6 +574,7 @@ func (c *Config) addDefaults() { } if c.Vault == nil { c.Vault = config.DefaultVaultConfig() + c.Vaults = map[string]*config.VaultConfig{"default": c.Vault} } if c.Telemetry == nil { c.Telemetry = &Telemetry{} @@ -694,10 +717,20 @@ var sample0 = &Config{ ClientAutoJoin: pointer.Of(false), }, Vault: &config.VaultConfig{ + Name: "default", Enabled: pointer.Of(true), Role: "nomad-cluster", Addr: "http://host.example.com:8200", }, + Vaults: map[string]*config.VaultConfig{ + "default": { + Name: "default", + Enabled: pointer.Of(true), + Role: "nomad-cluster", + Addr: "http://host.example.com:8200", + }, + }, + TLSConfig: &config.TLSConfig{ EnableHTTP: true, EnableRPC: true, @@ -790,10 +823,19 @@ var sample1 = &Config{ ClientAutoJoin: pointer.Of(false), }, Vault: &config.VaultConfig{ + Name: "default", Enabled: pointer.Of(true), Role: "nomad-cluster", Addr: "http://host.example.com:8200", }, + Vaults: map[string]*config.VaultConfig{ + "default": { + Name: "default", + Enabled: pointer.Of(true), + Role: "nomad-cluster", + Addr: "http://host.example.com:8200", + }, + }, TLSConfig: &config.TLSConfig{ EnableHTTP: true, EnableRPC: true, @@ -904,3 +946,51 @@ func permutations(arr []string) [][]string { helper(arr, len(arr)) return res } + +func TestConfig_MultipleVault(t *testing.T) { + + // verify the default Vault config is set from the list + cfg := DefaultConfig() + must.Eq(t, "default", cfg.Vault.Name) + must.Equal(t, config.DefaultVaultConfig(), cfg.Vault) + must.Nil(t, cfg.Vault.Enabled) // unset + must.Eq(t, "https://vault.service.consul:8200", cfg.Vault.Addr) + must.Eq(t, "", cfg.Vault.Token) + + must.MapLen(t, 1, cfg.Vaults) + must.Equal(t, cfg.Vault, cfg.Vaults["default"]) + must.True(t, cfg.Vault == cfg.Vaults["default"]) // must be same pointer + + // merge in the user's configuration + fc, err := LoadConfig("testdata/basic.hcl") + must.NoError(t, err) + cfg = cfg.Merge(fc) + + must.Eq(t, "default", cfg.Vault.Name) + must.NotNil(t, cfg.Vault.Enabled, must.Sprint("override should set to non-nil")) + must.False(t, *cfg.Vault.Enabled) + must.Eq(t, "127.0.0.1:9500", cfg.Vault.Addr) + must.Eq(t, "12345", cfg.Vault.Token) + + must.MapLen(t, 1, cfg.Vaults) + must.Equal(t, cfg.Vault, cfg.Vaults["default"]) + + // add an extra Vault config and override fields in the default + fc, err = LoadConfig("testdata/extra-vault.hcl") + must.NoError(t, err) + + cfg = cfg.Merge(fc) + + must.Eq(t, "default", cfg.Vault.Name) + must.True(t, *cfg.Vault.Enabled) + must.Eq(t, "127.0.0.1:9500", cfg.Vault.Addr) + must.Eq(t, "abracadabra", cfg.Vault.Token) + + must.MapLen(t, 2, cfg.Vaults) + must.Equal(t, cfg.Vault, cfg.Vaults["default"]) + + must.Eq(t, "alternate", cfg.Vaults["alternate"].Name) + must.True(t, *cfg.Vaults["alternate"].Enabled) + must.Eq(t, "127.0.0.1:9501", cfg.Vaults["alternate"].Addr) + must.Eq(t, "xyzzy", cfg.Vaults["alternate"].Token) +} diff --git a/command/agent/config_test.go b/command/agent/config_test.go index c631a610e..291ffd6a0 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -184,6 +184,7 @@ func TestConfig_Merge(t *testing.T) { "Access-Control-Allow-Origin": "*", }, Vault: &config.VaultConfig{ + Name: "default", Token: "1", AllowUnauthenticated: &falseValue, TaskTokenTTL: "1", @@ -195,6 +196,21 @@ func TestConfig_Merge(t *testing.T) { TLSSkipVerify: &falseValue, TLSServerName: "1", }, + Vaults: map[string]*config.VaultConfig{ + "default": { + Name: "default", + Token: "1", + AllowUnauthenticated: &falseValue, + TaskTokenTTL: "1", + Addr: "1", + TLSCaFile: "1", + TLSCaPath: "1", + TLSCertFile: "1", + TLSKeyFile: "1", + TLSSkipVerify: &falseValue, + TLSServerName: "1", + }, + }, Consul: &config.ConsulConfig{ ServerServiceName: "1", ClientServiceName: "1", @@ -393,6 +409,7 @@ func TestConfig_Merge(t *testing.T) { "Access-Control-Allow-Methods": "GET, POST, OPTIONS", }, Vault: &config.VaultConfig{ + Name: "default", Token: "2", AllowUnauthenticated: &trueValue, TaskTokenTTL: "2", @@ -404,6 +421,21 @@ func TestConfig_Merge(t *testing.T) { TLSSkipVerify: &trueValue, TLSServerName: "2", }, + Vaults: map[string]*config.VaultConfig{ + "default": { + Name: "default", + Token: "2", + AllowUnauthenticated: &trueValue, + TaskTokenTTL: "2", + Addr: "2", + TLSCaFile: "2", + TLSCaPath: "2", + TLSCertFile: "2", + TLSKeyFile: "2", + TLSSkipVerify: &trueValue, + TLSServerName: "2", + }, + }, Consul: &config.ConsulConfig{ ServerServiceName: "2", ClientServiceName: "2", diff --git a/command/agent/testdata/extra-vault.hcl b/command/agent/testdata/extra-vault.hcl new file mode 100644 index 000000000..0909dd59a --- /dev/null +++ b/command/agent/testdata/extra-vault.hcl @@ -0,0 +1,25 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +# this unnamed (default) config should merge cleanly onto the basic config +vault { + enabled = true + token = "abracadabra" +} + +# this alternate config should be added as an extra vault config +vault { + name = "alternate" + address = "127.0.0.1:9501" + allow_unauthenticated = true + task_token_ttl = "5s" + enabled = true + token = "xyzzy" + ca_file = "/path/to/ca/file" + ca_path = "/path/to/ca" + cert_file = "/path/to/cert/file" + key_file = "/path/to/key/file" + tls_server_name = "barbaz" + tls_skip_verify = true + create_from_role = "test_role2" +} diff --git a/command/agent/testdata/sample0.json b/command/agent/testdata/sample0.json index a7cc60f49..9a93d870e 100644 --- a/command/agent/testdata/sample0.json +++ b/command/agent/testdata/sample0.json @@ -82,6 +82,7 @@ "verify_server_hostname": true }, "vault": { + "name": "default", "address": "http://host.example.com:8200", "create_from_role": "nomad-cluster", "enabled": true diff --git a/nomad/config.go b/nomad/config.go index da84a80c5..e477912d4 100644 --- a/nomad/config.go +++ b/nomad/config.go @@ -14,6 +14,7 @@ import ( "golang.org/x/exp/slices" "github.com/hashicorp/memberlist" + "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/helper/pointer" "github.com/hashicorp/nomad/helper/uuid" "github.com/hashicorp/nomad/nomad/deploymentwatcher" @@ -310,9 +311,14 @@ type Config struct { // ConsulConfig is this Agent's Consul configuration ConsulConfig *config.ConsulConfig - // VaultConfig is this Agent's Vault configuration + // VaultConfig is this Agent's default Vault configuration VaultConfig *config.VaultConfig + // VaultConfigs is a map of Vault configurations, here to support features + // in Nomad Enterprise. The default Vault config pointer above will be found + // in this map under the name "default" + VaultConfigs map[string]*config.VaultConfig + // RPCHoldTimeout is how long an RPC can be "held" before it is errored. // This is used to paper over a loss of leadership by instead holding RPCs, // so that the caller experiences a slow response rather than an error. @@ -442,6 +448,7 @@ func (c *Config) Copy() *Config { nc.EnabledSchedulers = slices.Clone(c.EnabledSchedulers) nc.ConsulConfig = c.ConsulConfig.Copy() nc.VaultConfig = c.VaultConfig.Copy() + nc.VaultConfigs = helper.DeepCopyMap(c.VaultConfigs) nc.TLSConfig = c.TLSConfig.Copy() nc.SentinelConfig = c.SentinelConfig.Copy() nc.AutopilotConfig = c.AutopilotConfig.Copy() @@ -541,6 +548,8 @@ func DefaultConfig() *Config { JobTrackedVersions: structs.JobDefaultTrackedVersions, } + c.VaultConfigs = map[string]*config.VaultConfig{"default": c.VaultConfig} + // Enable all known schedulers by default c.EnabledSchedulers = make([]string, 0, len(scheduler.BuiltinSchedulers)) for name := range scheduler.BuiltinSchedulers { diff --git a/nomad/structs/config/vault.go b/nomad/structs/config/vault.go index b6038f82a..a92d97fd7 100644 --- a/nomad/structs/config/vault.go +++ b/nomad/structs/config/vault.go @@ -25,21 +25,22 @@ const ( // // - Create child tokens with policy subsets of the Server's token. type VaultConfig struct { + Name string `mapstructure:"name"` // Enabled enables or disables Vault support. - Enabled *bool `hcl:"enabled"` + Enabled *bool `mapstructure:"enabled"` // Token is the Vault token given to Nomad such that it can // derive child tokens. Nomad will renew this token at half its lease // lifetime. - Token string `hcl:"token"` + Token string `mapstructure:"token"` // Role sets the role in which to create tokens from. The Token given to // Nomad does not have to be created from this role but must have "update" // capability on "auth/token/create/". If this value is // unset and the token is created from a role, the value is defaulted to the // role the token is from. - Role string `hcl:"create_from_role"` + Role string `mapstructure:"create_from_role"` // Namespace sets the Vault namespace used for all calls against the // Vault API. If this is unset, then Nomad does not use Vault namespaces. @@ -48,16 +49,16 @@ type VaultConfig struct { // AllowUnauthenticated allows users to submit jobs requiring Vault tokens // without providing a Vault token proving they have access to these // policies. - AllowUnauthenticated *bool `hcl:"allow_unauthenticated"` + AllowUnauthenticated *bool `mapstructure:"allow_unauthenticated"` // TaskTokenTTL is the TTL of the tokens created by Nomad Servers and used // by the client. There should be a minimum time value such that the client // does not have to renew with Vault at a very high frequency - TaskTokenTTL string `hcl:"task_token_ttl"` + TaskTokenTTL string `mapstructure:"task_token_ttl"` // Addr is the address of the local Vault agent. This should be a complete // URL such as "http://vault.example.com" - Addr string `hcl:"address"` + Addr string `mapstructure:"address"` // ConnectionRetryIntv is the interval to wait before re-attempting to // connect to Vault. @@ -65,29 +66,30 @@ type VaultConfig struct { // TLSCaFile is the path to a PEM-encoded CA cert file to use to verify the // Vault server SSL certificate. - TLSCaFile string `hcl:"ca_file"` + TLSCaFile string `mapstructure:"ca_file"` // TLSCaFile is the path to a directory of PEM-encoded CA cert files to // verify the Vault server SSL certificate. - TLSCaPath string `hcl:"ca_path"` + TLSCaPath string `mapstructure:"ca_path"` // TLSCertFile is the path to the certificate for Vault communication - TLSCertFile string `hcl:"cert_file"` + TLSCertFile string `mapstructure:"cert_file"` // TLSKeyFile is the path to the private key for Vault communication - TLSKeyFile string `hcl:"key_file"` + TLSKeyFile string `mapstructure:"key_file"` // TLSSkipVerify enables or disables SSL verification - TLSSkipVerify *bool `hcl:"tls_skip_verify"` + TLSSkipVerify *bool `mapstructure:"tls_skip_verify"` // TLSServerName, if set, is used to set the SNI host when connecting via TLS. - TLSServerName string `hcl:"tls_server_name"` + TLSServerName string `mapstructure:"tls_server_name"` } // DefaultVaultConfig returns the canonical defaults for the Nomad // `vault` configuration. func DefaultVaultConfig() *VaultConfig { return &VaultConfig{ + Name: "default", Addr: "https://vault.service.consul:8200", ConnectionRetryIntv: DefaultVaultConnectRetryIntv, AllowUnauthenticated: pointer.Of(true), @@ -109,6 +111,9 @@ func (c *VaultConfig) AllowsUnauthenticated() bool { func (c *VaultConfig) Merge(b *VaultConfig) *VaultConfig { result := *c + if b.Name != "" { + c.Name = b.Name + } if b.Enabled != nil { result.Enabled = b.Enabled }