config: parsing support for multiple Vault clusters in agent config (#18224)

Add the plumbing we need to accept multiple Vault clusters in Nomad agent
configuration, to support upcoming Nomad Enterprise features. The `vault` blocks
are differentiated by a new `name` field, and if the `name` is omitted it
becomes the "default" Vault configuration. All blocks with the same name are
merged together, as with the existing behavior.

Unfortunately we're still using HCL1 for parsing configuration and the `Decode`
method doesn't parse multiple blocks differentiated only by a field name without
a label. So we've had to add an extra parsing pass, similar to what we've done
for HCL1 jobspecs.

For now, all existing consumers will use the "default" Vault configuration, so
there's no user-facing behavior change in this changeset other than the contents
of the agent self API.

Ref: https://github.com/hashicorp/team-nomad/issues/404
This commit is contained in:
Tim Gross
2023-08-17 14:10:32 -04:00
committed by GitHub
parent 52f0bd4630
commit 74b796e6d0
13 changed files with 292 additions and 25 deletions

View File

@@ -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 "".

View File

@@ -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

View File

@@ -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

View File

@@ -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 = "<redacted>"
}
for _, vaultConfig := range self.Config.Vaults {
if vaultConfig.Token != "" {
vaultConfig.Token = "<redacted>"
}
}
if self.Config != nil && self.Config.ACL != nil && self.Config.ACL.ReplicationToken != "" {
self.Config.ACL.ReplicationToken = "<redacted>"

View File

@@ -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()) }

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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",

25
command/agent/testdata/extra-vault.hcl vendored Normal file
View File

@@ -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"
}

View File

@@ -82,6 +82,7 @@
"verify_server_hostname": true
},
"vault": {
"name": "default",
"address": "http://host.example.com:8200",
"create_from_role": "nomad-cluster",
"enabled": true

View File

@@ -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 {

View File

@@ -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/<create_from_role>". 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
}