VAULT-12095 Support multiple config files for Vault Agent (#18403)

* VAULT-12095 Code changes for multi-config

* VAULT-12095 typo

* VAULT-12095 make vault non-nil during update

* VAULT-12095 docs

* VAULT-12095 small refactor

* VAULT-12095 typos
This commit is contained in:
Violet Hynes 2023-01-03 12:50:19 -05:00 committed by GitHub
parent 4052c785ea
commit 0b15ad18a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 738 additions and 402 deletions

3
changelog/18403.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
agent/config: Allow config directories to be specified with -config, and allow multiple -configs to be supplied.
```

View File

@ -16,6 +16,8 @@ import (
"sync"
"time"
ctconfig "github.com/hashicorp/consul-template/config"
"github.com/hashicorp/vault/command/agent/sink/inmem"
systemd "github.com/coreos/go-systemd/daemon"
@ -186,32 +188,30 @@ func (c *AgentCommand) Run(args []string) int {
}
// Validation
if len(c.flagConfigs) != 1 {
c.UI.Error("Must specify exactly one config path using -config")
if len(c.flagConfigs) < 1 {
c.UI.Error("Must specify exactly at least one config path using -config")
return 1
}
// Load the configuration file
config, err := agentConfig.LoadConfig(c.flagConfigs[0])
config := agentConfig.NewConfig()
for _, configPath := range c.flagConfigs {
configFromPath, err := agentConfig.LoadConfig(configPath)
if err != nil {
c.UI.Error(fmt.Sprintf("Error loading configuration from %s: %s", configPath, err))
return 1
}
config = config.Merge(configFromPath)
}
err := config.ValidateConfig()
if err != nil {
c.UI.Error(fmt.Sprintf("Error loading configuration from %s: %s", c.flagConfigs[0], err))
c.UI.Error(fmt.Sprintf("Error loading configuration: %s", err))
return 1
}
// Ensure at least one config was found.
if config == nil {
c.UI.Output(wrapAtLength(
"No configuration read. Please provide the configuration with the " +
"-config flag."))
return 1
}
if config.AutoAuth == nil && config.Cache == nil {
c.UI.Error("No auto_auth or cache block found in config file")
return 1
}
if config.AutoAuth == nil {
c.UI.Info("No auto_auth block found in config file, not starting automatic authentication feature")
c.UI.Info("No auto_auth block found in config, not starting automatic authentication feature")
}
c.updateConfig(f, config)
@ -417,7 +417,12 @@ func (c *AgentCommand) Run(args []string) int {
// confuse the issue of retries for auth failures which have their own
// config and are handled a bit differently.
if os.Getenv(api.EnvVaultMaxRetries) == "" {
client.SetMaxRetries(config.Vault.Retry.NumRetries)
client.SetMaxRetries(ctconfig.DefaultRetryAttempts)
if config.Vault != nil {
if config.Vault.Retry != nil {
client.SetMaxRetries(config.Vault.Retry.NumRetries)
}
}
}
enforceConsistency := cache.EnforceConsistencyNever
@ -977,6 +982,10 @@ func (c *AgentCommand) Run(args []string) int {
// on the precedence (env var overrides file config, cli overrides env var).
// It mutates the config object supplied.
func (c *AgentCommand) updateConfig(f *FlagSets, config *agentConfig.Config) {
if config.Vault == nil {
config.Vault = &agentConfig.Vault{}
}
f.updateLogConfig(config.SharedConfig)
f.Visit(func(fl *flag.Flag) {

View File

@ -4,8 +4,10 @@ import (
"context"
"errors"
"fmt"
"io"
"net"
"os"
"path/filepath"
"strings"
"time"
@ -169,14 +171,253 @@ func NewConfig() *Config {
}
}
// Merge merges two Agent configurations.
func (c *Config) Merge(c2 *Config) *Config {
if c2 == nil {
return c
}
result := NewConfig()
result.SharedConfig = c.SharedConfig
if c2.SharedConfig != nil {
result.SharedConfig = c.SharedConfig.Merge(c2.SharedConfig)
}
result.AutoAuth = c.AutoAuth
if c2.AutoAuth != nil {
result.AutoAuth = c2.AutoAuth
}
result.Cache = c.Cache
if c2.Cache != nil {
result.Cache = c2.Cache
}
result.APIProxy = c.APIProxy
if c2.APIProxy != nil {
result.APIProxy = c2.APIProxy
}
result.DisableMlock = c.DisableMlock
if c2.DisableMlock {
result.DisableMlock = c2.DisableMlock
}
// For these, ignore the non-specific one and overwrite them all
result.DisableIdleConnsAutoAuth = c.DisableIdleConnsAutoAuth
if c2.DisableIdleConnsAutoAuth {
result.DisableIdleConnsAutoAuth = c2.DisableIdleConnsAutoAuth
}
result.DisableIdleConnsAPIProxy = c.DisableIdleConnsAPIProxy
if c2.DisableIdleConnsAPIProxy {
result.DisableIdleConnsAPIProxy = c2.DisableIdleConnsAPIProxy
}
result.DisableIdleConnsTemplating = c.DisableIdleConnsTemplating
if c2.DisableIdleConnsTemplating {
result.DisableIdleConnsTemplating = c2.DisableIdleConnsTemplating
}
result.DisableKeepAlivesAutoAuth = c.DisableKeepAlivesAutoAuth
if c2.DisableKeepAlivesAutoAuth {
result.DisableKeepAlivesAutoAuth = c2.DisableKeepAlivesAutoAuth
}
result.DisableKeepAlivesAPIProxy = c.DisableKeepAlivesAPIProxy
if c2.DisableKeepAlivesAPIProxy {
result.DisableKeepAlivesAPIProxy = c2.DisableKeepAlivesAPIProxy
}
result.DisableKeepAlivesTemplating = c.DisableKeepAlivesTemplating
if c2.DisableKeepAlivesTemplating {
result.DisableKeepAlivesTemplating = c2.DisableKeepAlivesTemplating
}
result.TemplateConfig = c.TemplateConfig
if c2.TemplateConfig != nil {
result.TemplateConfig = c2.TemplateConfig
}
for _, l := range c.Templates {
result.Templates = append(result.Templates, l)
}
for _, l := range c2.Templates {
result.Templates = append(result.Templates, l)
}
result.ExitAfterAuth = c.ExitAfterAuth
if c2.ExitAfterAuth {
result.ExitAfterAuth = c2.ExitAfterAuth
}
result.Vault = c.Vault
if c2.Vault != nil {
result.Vault = c2.Vault
}
result.PidFile = c.PidFile
if c2.PidFile != "" {
result.PidFile = c2.PidFile
}
return result
}
// ValidateConfig validates an Agent configuration after it has been fully merged together, to
// ensure that required combinations of configs are there
func (c *Config) ValidateConfig() error {
if c.APIProxy != nil && c.Cache != nil {
if c.Cache.UseAutoAuthTokenRaw != nil {
if c.APIProxy.UseAutoAuthTokenRaw != nil {
return fmt.Errorf("use_auto_auth_token defined in both api_proxy and cache config. Please remove this configuration from the cache block")
} else {
c.APIProxy.ForceAutoAuthToken = c.Cache.ForceAutoAuthToken
}
}
}
if c.Cache != nil {
if len(c.Listeners) < 1 && len(c.Templates) < 1 {
return fmt.Errorf("enabling the cache requires at least 1 template or 1 listener to be defined")
}
if c.Cache.UseAutoAuthToken {
if c.AutoAuth == nil {
return fmt.Errorf("cache.use_auto_auth_token is true but auto_auth not configured")
}
if c.AutoAuth != nil && c.AutoAuth.Method != nil && c.AutoAuth.Method.WrapTTL > 0 {
return fmt.Errorf("cache.use_auto_auth_token is true and auto_auth uses wrapping")
}
}
}
if c.APIProxy != nil {
if len(c.Listeners) < 1 {
return fmt.Errorf("configuring the api_proxy requires at least 1 listener to be defined")
}
if c.APIProxy.UseAutoAuthToken {
if c.AutoAuth == nil {
return fmt.Errorf("api_proxy.use_auto_auth_token is true but auto_auth not configured")
}
if c.AutoAuth != nil && c.AutoAuth.Method != nil && c.AutoAuth.Method.WrapTTL > 0 {
return fmt.Errorf("api_proxy.use_auto_auth_token is true and auto_auth uses wrapping")
}
}
}
if c.AutoAuth != nil {
if len(c.AutoAuth.Sinks) == 0 &&
(c.APIProxy == nil || !c.APIProxy.UseAutoAuthToken) &&
len(c.Templates) == 0 {
return fmt.Errorf("auto_auth requires at least one sink or at least one template or api_proxy.use_auto_auth_token=true")
}
}
if c.AutoAuth == nil && c.Cache == nil && len(c.Listeners) == 0 {
return fmt.Errorf("no auto_auth, cache, or listener block found in config")
}
return nil
}
// LoadConfig loads the configuration at the given path, regardless if
// its a file or directory.
// it's a file or directory.
func LoadConfig(path string) (*Config, error) {
fi, err := os.Stat(path)
if err != nil {
return nil, err
}
if fi.IsDir() {
return LoadConfigDir(path)
}
return LoadConfigFile(path)
}
// LoadConfigDir loads the configuration at the given path if it's a directory
func LoadConfigDir(dir string) (*Config, error) {
f, err := os.Open(dir)
if err != nil {
return nil, err
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
return nil, err
}
if !fi.IsDir() {
return nil, fmt.Errorf("configuration path must be a directory: %q", dir)
}
var files []string
err = nil
for err != io.EOF {
var fis []os.FileInfo
fis, err = f.Readdir(128)
if err != nil && err != io.EOF {
return nil, err
}
for _, fi := range fis {
// Ignore directories
if fi.IsDir() {
continue
}
// Only care about files that are valid to load.
name := fi.Name()
skip := true
if strings.HasSuffix(name, ".hcl") {
skip = false
} else if strings.HasSuffix(name, ".json") {
skip = false
}
if skip || isTemporaryFile(name) {
continue
}
path := filepath.Join(dir, name)
files = append(files, path)
}
}
result := NewConfig()
for _, f := range files {
config, err := LoadConfigFile(f)
if err != nil {
return nil, fmt.Errorf("error loading %q: %w", f, err)
}
if result == nil {
result = config
} else {
result = result.Merge(config)
}
}
return result, nil
}
// isTemporaryFile returns true or false depending on whether the
// provided file name is a temporary file for the following editors:
// emacs or vim.
func isTemporaryFile(name string) bool {
return strings.HasSuffix(name, "~") || // vim
strings.HasPrefix(name, ".#") || // emacs
(strings.HasPrefix(name, "#") && strings.HasSuffix(name, "#")) // emacs
}
// LoadConfigFile loads the configuration at the given path if it's a file
func LoadConfigFile(path string) (*Config, error) {
fi, err := os.Stat(path)
if err != nil {
return nil, err
}
if fi.IsDir() {
return nil, fmt.Errorf("location is a directory, not a file")
}
@ -236,16 +477,6 @@ func LoadConfig(path string) (*Config, error) {
return nil, fmt.Errorf("error parsing 'api_proxy':%w", err)
}
if result.APIProxy != nil && result.Cache != nil {
if result.Cache.UseAutoAuthTokenRaw != nil {
if result.APIProxy.UseAutoAuthTokenRaw != nil {
return nil, fmt.Errorf("use_auto_auth_token defined in both api_proxy and cache config. Please remove this configuration from the cache block")
} else {
result.APIProxy.ForceAutoAuthToken = result.Cache.ForceAutoAuthToken
}
}
}
if err := parseTemplateConfig(result, list); err != nil {
return nil, fmt.Errorf("error parsing 'template_config': %w", err)
}
@ -254,69 +485,29 @@ func LoadConfig(path string) (*Config, error) {
return nil, fmt.Errorf("error parsing 'template': %w", err)
}
if result.Cache != nil && result.APIProxy == nil && len(result.Listeners) > 0 {
if result.Cache != nil && result.APIProxy == nil {
result.APIProxy = &APIProxy{
UseAutoAuthToken: result.Cache.UseAutoAuthToken,
ForceAutoAuthToken: result.Cache.ForceAutoAuthToken,
}
}
if result.Cache != nil {
if len(result.Listeners) < 1 && len(result.Templates) < 1 {
return nil, fmt.Errorf("enabling the cache requires at least 1 template or 1 listener to be defined")
}
if result.Cache.UseAutoAuthToken {
if result.AutoAuth == nil {
return nil, fmt.Errorf("cache.use_auto_auth_token is true but auto_auth not configured")
}
if result.AutoAuth != nil && result.AutoAuth.Method != nil && result.AutoAuth.Method.WrapTTL > 0 {
return nil, fmt.Errorf("cache.use_auto_auth_token is true and auto_auth uses wrapping")
}
}
}
if result.APIProxy != nil {
if len(result.Listeners) < 1 {
return nil, fmt.Errorf("configuring the api_proxy requires at least 1 listener to be defined")
}
if result.APIProxy.UseAutoAuthToken {
if result.AutoAuth == nil {
return nil, fmt.Errorf("api_proxy.use_auto_auth_token is true but auto_auth not configured")
}
if result.AutoAuth != nil && result.AutoAuth.Method != nil && result.AutoAuth.Method.WrapTTL > 0 {
return nil, fmt.Errorf("api_proxy.use_auto_auth_token is true and auto_auth uses wrapping")
}
}
}
if result.AutoAuth != nil {
if len(result.AutoAuth.Sinks) == 0 &&
(result.APIProxy == nil || !result.APIProxy.UseAutoAuthToken) &&
len(result.Templates) == 0 {
return nil, fmt.Errorf("auto_auth requires at least one sink or at least one template or api_proxy.use_auto_auth_token=true")
}
}
err = parseVault(result, list)
if err != nil {
return nil, fmt.Errorf("error parsing 'vault':%w", err)
}
if result.Vault == nil {
result.Vault = &Vault{}
}
// Set defaults
if result.Vault.Retry == nil {
result.Vault.Retry = &Retry{}
}
switch result.Vault.Retry.NumRetries {
case 0:
result.Vault.Retry.NumRetries = ctconfig.DefaultRetryAttempts
case -1:
result.Vault.Retry.NumRetries = 0
if result.Vault != nil {
// Set defaults
if result.Vault.Retry == nil {
result.Vault.Retry = &Retry{}
}
switch result.Vault.Retry.NumRetries {
case 0:
result.Vault.Retry.NumRetries = ctconfig.DefaultRetryAttempts
case -1:
result.Vault.Retry.NumRetries = 0
}
}
if disableIdleConnsEnv := os.Getenv(DisableIdleConnsEnv); disableIdleConnsEnv != "" {

View File

@ -12,7 +12,7 @@ import (
)
func TestLoadConfigFile_AgentCache(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache.hcl")
if err != nil {
t.Fatal(err)
}
@ -104,7 +104,7 @@ func TestLoadConfigFile_AgentCache(t *testing.T) {
t.Fatal(diff)
}
config, err = LoadConfig("./test-fixtures/config-cache-embedded-type.hcl")
config, err = LoadConfigFile("./test-fixtures/config-cache-embedded-type.hcl")
if err != nil {
t.Fatal(err)
}
@ -116,8 +116,236 @@ func TestLoadConfigFile_AgentCache(t *testing.T) {
}
}
func TestLoadConfigDir_AgentCache(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-dir-cache/")
if err != nil {
t.Fatal(err)
}
expected := &Config{
SharedConfig: &configutil.SharedConfig{
PidFile: "./pidfile",
Listeners: []*configutil.Listener{
{
Type: "unix",
Address: "/path/to/socket",
TLSDisable: true,
SocketMode: "configmode",
SocketUser: "configuser",
SocketGroup: "configgroup",
},
{
Type: "tcp",
Address: "127.0.0.1:8300",
TLSDisable: true,
},
{
Type: "tcp",
Address: "127.0.0.1:3000",
Role: "metrics_only",
TLSDisable: true,
},
{
Type: "tcp",
Role: "default",
Address: "127.0.0.1:8400",
TLSKeyFile: "/path/to/cakey.pem",
TLSCertFile: "/path/to/cacert.pem",
},
},
},
AutoAuth: &AutoAuth{
Method: &Method{
Type: "aws",
MountPath: "auth/aws",
Config: map[string]interface{}{
"role": "foobar",
},
},
Sinks: []*Sink{
{
Type: "file",
DHType: "curve25519",
DHPath: "/tmp/file-foo-dhpath",
AAD: "foobar",
Config: map[string]interface{}{
"path": "/tmp/file-foo",
},
},
},
},
APIProxy: &APIProxy{
UseAutoAuthToken: true,
ForceAutoAuthToken: false,
},
Cache: &Cache{
UseAutoAuthToken: true,
UseAutoAuthTokenRaw: true,
ForceAutoAuthToken: false,
Persist: &Persist{
Type: "kubernetes",
Path: "/vault/agent-cache/",
KeepAfterImport: true,
ExitOnErr: true,
ServiceAccountTokenFile: "/tmp/serviceaccount/token",
},
},
Vault: &Vault{
Address: "http://127.0.0.1:1111",
CACert: "config_ca_cert",
CAPath: "config_ca_path",
TLSSkipVerifyRaw: interface{}("true"),
TLSSkipVerify: true,
ClientCert: "config_client_cert",
ClientKey: "config_client_key",
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
if diff := deep.Equal(config, expected); diff != nil {
t.Fatal(diff)
}
config, err = LoadConfigFile("./test-fixtures/config-dir-cache/config-cache1.hcl")
if err != nil {
t.Fatal(err)
}
config2, err := LoadConfigFile("./test-fixtures/config-dir-cache/config-cache2.hcl")
mergedConfig := config.Merge(config2)
mergedConfig.Prune()
if diff := deep.Equal(mergedConfig, expected); diff != nil {
t.Fatal(diff)
}
}
func TestLoadConfigDir_AutoAuthAndListener(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-dir-auto-auth-and-listener/")
if err != nil {
t.Fatal(err)
}
expected := &Config{
SharedConfig: &configutil.SharedConfig{
PidFile: "./pidfile",
Listeners: []*configutil.Listener{
{
Type: "tcp",
Address: "127.0.0.1:8300",
TLSDisable: true,
},
},
},
AutoAuth: &AutoAuth{
Method: &Method{
Type: "aws",
MountPath: "auth/aws",
Config: map[string]interface{}{
"role": "foobar",
},
},
Sinks: []*Sink{
{
Type: "file",
DHType: "curve25519",
DHPath: "/tmp/file-foo-dhpath",
AAD: "foobar",
Config: map[string]interface{}{
"path": "/tmp/file-foo",
},
},
},
},
}
config.Prune()
if diff := deep.Equal(config, expected); diff != nil {
t.Fatal(diff)
}
config, err = LoadConfigFile("./test-fixtures/config-dir-auto-auth-and-listener/config1.hcl")
if err != nil {
t.Fatal(err)
}
config2, err := LoadConfigFile("./test-fixtures/config-dir-auto-auth-and-listener/config2.hcl")
mergedConfig := config.Merge(config2)
mergedConfig.Prune()
if diff := deep.Equal(mergedConfig, expected); diff != nil {
t.Fatal(diff)
}
}
func TestLoadConfigDir_VaultBlock(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-dir-vault-block/")
if err != nil {
t.Fatal(err)
}
expected := &Config{
SharedConfig: &configutil.SharedConfig{
PidFile: "./pidfile",
},
Vault: &Vault{
Address: "http://127.0.0.1:1111",
CACert: "config_ca_cert",
CAPath: "config_ca_path",
TLSSkipVerifyRaw: interface{}("true"),
TLSSkipVerify: true,
ClientCert: "config_client_cert",
ClientKey: "config_client_key",
Retry: &Retry{
NumRetries: 12,
},
},
AutoAuth: &AutoAuth{
Method: &Method{
Type: "aws",
MountPath: "auth/aws",
Config: map[string]interface{}{
"role": "foobar",
},
},
Sinks: []*Sink{
{
Type: "file",
DHType: "curve25519",
DHPath: "/tmp/file-foo-dhpath",
AAD: "foobar",
Config: map[string]interface{}{
"path": "/tmp/file-foo",
},
},
},
},
}
config.Prune()
if diff := deep.Equal(config, expected); diff != nil {
t.Fatal(diff)
}
config, err = LoadConfigFile("./test-fixtures/config-dir-vault-block/config1.hcl")
if err != nil {
t.Fatal(err)
}
config2, err := LoadConfigFile("./test-fixtures/config-dir-vault-block/config2.hcl")
mergedConfig := config.Merge(config2)
mergedConfig.Prune()
if diff := deep.Equal(mergedConfig, expected); diff != nil {
t.Fatal(diff)
}
}
func TestLoadConfigFile_AgentCache_NoListeners(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-no-listeners.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-no-listeners.hcl")
if err != nil {
t.Fatal(err)
}
@ -146,6 +374,10 @@ func TestLoadConfigFile_AgentCache_NoListeners(t *testing.T) {
},
},
},
APIProxy: &APIProxy{
UseAutoAuthToken: true,
ForceAutoAuthToken: false,
},
Cache: &Cache{
UseAutoAuthToken: true,
UseAutoAuthTokenRaw: true,
@ -194,7 +426,7 @@ func TestLoadConfigFile(t *testing.T) {
}
}()
config, err := LoadConfig("./test-fixtures/config.hcl")
config, err := LoadConfigFile("./test-fixtures/config.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -237,11 +469,6 @@ func TestLoadConfigFile(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -249,7 +476,7 @@ func TestLoadConfigFile(t *testing.T) {
t.Fatal(diff)
}
config, err = LoadConfig("./test-fixtures/config-embedded-type.hcl")
config, err = LoadConfigFile("./test-fixtures/config-embedded-type.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -261,7 +488,7 @@ func TestLoadConfigFile(t *testing.T) {
}
func TestLoadConfigFile_Method_Wrapping(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-method-wrapping.hcl")
config, err := LoadConfigFile("./test-fixtures/config-method-wrapping.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -290,11 +517,6 @@ func TestLoadConfigFile_Method_Wrapping(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -304,7 +526,7 @@ func TestLoadConfigFile_Method_Wrapping(t *testing.T) {
}
func TestLoadConfigFile_Method_InitialBackoff(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-method-initial-backoff.hcl")
config, err := LoadConfigFile("./test-fixtures/config-method-initial-backoff.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -334,11 +556,6 @@ func TestLoadConfigFile_Method_InitialBackoff(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -348,7 +565,7 @@ func TestLoadConfigFile_Method_InitialBackoff(t *testing.T) {
}
func TestLoadConfigFile_Method_ExitOnErr(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-method-exit-on-err.hcl")
config, err := LoadConfigFile("./test-fixtures/config-method-exit-on-err.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -378,11 +595,6 @@ func TestLoadConfigFile_Method_ExitOnErr(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -392,7 +604,7 @@ func TestLoadConfigFile_Method_ExitOnErr(t *testing.T) {
}
func TestLoadConfigFile_AgentCache_NoAutoAuth(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-no-auto_auth.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-no-auto_auth.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -410,11 +622,6 @@ func TestLoadConfigFile_AgentCache_NoAutoAuth(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -424,63 +631,98 @@ func TestLoadConfigFile_AgentCache_NoAutoAuth(t *testing.T) {
}
func TestLoadConfigFile_Bad_AgentCache_InconsisentAutoAuth(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-cache-inconsistent-auto_auth.hcl")
config, err := LoadConfigFile("./test-fixtures/bad-config-cache-inconsistent-auto_auth.hcl")
if err != nil {
t.Fatalf("LoadConfigFile should not return an error for this config, err: %v", err)
}
if config == nil {
t.Fatal("config was nil")
}
err = config.ValidateConfig()
if err == nil {
t.Fatal("LoadConfig should return an error when use_auto_auth_token=true and no auto_auth section present")
t.Fatal("ValidateConfig should return an error when use_auto_auth_token=true and no auto_auth section present")
}
}
func TestLoadConfigFile_Bad_AgentCache_ForceAutoAuthNoMethod(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-cache-force-auto_auth.hcl")
config, err := LoadConfigFile("./test-fixtures/bad-config-cache-force-token-no-auth-method.hcl")
if err != nil {
t.Fatalf("LoadConfigFile should not return an error for this config, err: %v", err)
}
if config == nil {
t.Fatal("config was nil")
}
err = config.ValidateConfig()
if err == nil {
t.Fatal("LoadConfig should return an error when use_auto_auth_token=force and no auto_auth section present")
t.Fatal("ValidateConfig should return an error when use_auto_auth_token=force and no auto_auth section present")
}
}
func TestLoadConfigFile_Bad_AgentCache_NoListeners(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-cache-no-listeners.hcl")
if err == nil {
t.Fatal("LoadConfig should return an error when cache section present and no listeners present and no templates defined")
_, err := LoadConfigFile("./test-fixtures/bad-config-cache-no-listeners.hcl")
if err != nil {
t.Fatalf("LoadConfigFile should return an error for this config")
}
}
func TestLoadConfigFile_Bad_AutoAuth_Wrapped_Multiple_Sinks(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-auto_auth-wrapped-multiple-sinks.hcl")
_, err := LoadConfigFile("./test-fixtures/bad-config-auto_auth-wrapped-multiple-sinks.hcl")
if err == nil {
t.Fatal("LoadConfig should return an error when auth_auth.method.wrap_ttl nonzero and multiple sinks defined")
t.Fatalf("LoadConfigFile should return an error for this config, err: %v", err)
}
}
func TestLoadConfigFile_Bad_AutoAuth_Nosinks_Nocache_Notemplates(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-auto_auth-nosinks-nocache-notemplates.hcl")
config, err := LoadConfigFile("./test-fixtures/bad-config-auto_auth-nosinks-nocache-notemplates.hcl")
if err != nil {
t.Fatalf("LoadConfigFile should not return an error for this config, err: %v", err)
}
if config == nil {
t.Fatal("config was nil")
}
err = config.ValidateConfig()
if err == nil {
t.Fatal("LoadConfig should return an error when auto_auth configured and there are no sinks, caches or templates")
t.Fatal("ValidateConfig should return an error when auto_auth configured and there are no sinks, caches or templates")
}
}
func TestLoadConfigFile_Bad_AutoAuth_Both_Wrapping_Types(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-method-wrapping-and-sink-wrapping.hcl")
_, err := LoadConfigFile("./test-fixtures/bad-config-method-wrapping-and-sink-wrapping.hcl")
if err == nil {
t.Fatal("LoadConfig should return an error when auth_auth.method.wrap_ttl nonzero and sinks.wrap_ttl nonzero")
t.Fatalf("LoadConfigFile should return an error for this config")
}
}
func TestLoadConfigFile_Bad_AgentCache_AutoAuth_Method_wrapping(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-cache-auto_auth-method-wrapping.hcl")
config, err := LoadConfigFile("./test-fixtures/bad-config-cache-auto_auth-method-wrapping.hcl")
if err != nil {
t.Fatalf("LoadConfigFile should not return an error for this config, err: %v", err)
}
if config == nil {
t.Fatal("config was nil")
}
err = config.ValidateConfig()
if err == nil {
t.Fatal("LoadConfig should return an error when auth_auth.method.wrap_ttl nonzero and cache.use_auto_auth_token=true")
t.Fatal("ValidateConfig should return an error when auth_auth.method.wrap_ttl nonzero and cache.use_auto_auth_token=true")
}
}
func TestLoadConfigFile_Bad_APIProxy_And_Cache_Same_Config(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-api_proxy-cache.hcl")
config, err := LoadConfigFile("./test-fixtures/bad-config-api_proxy-cache.hcl")
if err != nil {
t.Fatalf("LoadConfigFile should not return an error for this config, err: %v", err)
}
if config == nil {
t.Fatal("config was nil")
}
err = config.ValidateConfig()
if err == nil {
t.Fatal("LoadConfig should return an error when cache and api_proxy try and configure the same value")
t.Fatal("ValidateConfig should return an error when cache and api_proxy try and configure the same value")
}
}
func TestLoadConfigFile_AgentCache_AutoAuth_NoSink(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-no-sink.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-auto_auth-no-sink.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -514,11 +756,6 @@ func TestLoadConfigFile_AgentCache_AutoAuth_NoSink(t *testing.T) {
UseAutoAuthTokenRaw: true,
ForceAutoAuthToken: false,
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -528,7 +765,7 @@ func TestLoadConfigFile_AgentCache_AutoAuth_NoSink(t *testing.T) {
}
func TestLoadConfigFile_AgentCache_AutoAuth_Force(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-force.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-auto_auth-force.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -562,11 +799,6 @@ func TestLoadConfigFile_AgentCache_AutoAuth_Force(t *testing.T) {
UseAutoAuthTokenRaw: "force",
ForceAutoAuthToken: true,
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -576,7 +808,7 @@ func TestLoadConfigFile_AgentCache_AutoAuth_Force(t *testing.T) {
}
func TestLoadConfigFile_AgentCache_AutoAuth_True(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-true.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-auto_auth-true.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -610,11 +842,6 @@ func TestLoadConfigFile_AgentCache_AutoAuth_True(t *testing.T) {
UseAutoAuthTokenRaw: "true",
ForceAutoAuthToken: false,
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -624,7 +851,7 @@ func TestLoadConfigFile_AgentCache_AutoAuth_True(t *testing.T) {
}
func TestLoadConfigFile_Agent_AutoAuth_APIProxyAllConfig(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-api_proxy-auto_auth-all-api_proxy-config.hcl")
config, err := LoadConfigFile("./test-fixtures/config-api_proxy-auto_auth-all-api_proxy-config.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -656,11 +883,6 @@ func TestLoadConfigFile_Agent_AutoAuth_APIProxyAllConfig(t *testing.T) {
EnforceConsistency: "always",
WhenInconsistent: "forward",
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -670,7 +892,7 @@ func TestLoadConfigFile_Agent_AutoAuth_APIProxyAllConfig(t *testing.T) {
}
func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-false.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-auto_auth-false.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -715,11 +937,6 @@ func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) {
UseAutoAuthTokenRaw: "false",
ForceAutoAuthToken: false,
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -729,7 +946,7 @@ func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) {
}
func TestLoadConfigFile_AgentCache_Persist(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-cache-persist-false.hcl")
config, err := LoadConfigFile("./test-fixtures/config-cache-persist-false.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
@ -755,11 +972,6 @@ func TestLoadConfigFile_AgentCache_Persist(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -769,7 +981,7 @@ func TestLoadConfigFile_AgentCache_Persist(t *testing.T) {
}
func TestLoadConfigFile_AgentCache_PersistMissingType(t *testing.T) {
_, err := LoadConfig("./test-fixtures/config-cache-persist-empty-type.hcl")
_, err := LoadConfigFile("./test-fixtures/config-cache-persist-empty-type.hcl")
if err == nil || os.IsNotExist(err) {
t.Fatal("expected error or file is missing")
}
@ -797,7 +1009,7 @@ func TestLoadConfigFile_TemplateConfig(t *testing.T) {
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
config, err := LoadConfig(tc.fixturePath)
config, err := LoadConfigFile(tc.fixturePath)
if err != nil {
t.Fatal(err)
}
@ -896,7 +1108,7 @@ func TestLoadConfigFile_Template(t *testing.T) {
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
config, err := LoadConfig(tc.fixturePath)
config, err := LoadConfigFile(tc.fixturePath)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -926,11 +1138,6 @@ func TestLoadConfigFile_Template(t *testing.T) {
},
},
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
Templates: tc.expectedTemplates,
}
@ -1007,7 +1214,7 @@ func TestLoadConfigFile_Template_NoSinks(t *testing.T) {
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
config, err := LoadConfig(tc.fixturePath)
config, err := LoadConfigFile(tc.fixturePath)
if err != nil {
t.Fatalf("err: %s", err)
}
@ -1028,11 +1235,6 @@ func TestLoadConfigFile_Template_NoSinks(t *testing.T) {
Sinks: nil,
},
Templates: tc.expectedTemplates,
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -1044,7 +1246,7 @@ func TestLoadConfigFile_Template_NoSinks(t *testing.T) {
}
func TestLoadConfigFile_Vault_Retry(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-vault-retry.hcl")
config, err := LoadConfigFile("./test-fixtures/config-vault-retry.hcl")
if err != nil {
t.Fatal(err)
}
@ -1089,7 +1291,7 @@ func TestLoadConfigFile_Vault_Retry(t *testing.T) {
}
func TestLoadConfigFile_Vault_Retry_Empty(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-vault-retry-empty.hcl")
config, err := LoadConfigFile("./test-fixtures/config-vault-retry-empty.hcl")
if err != nil {
t.Fatal(err)
}
@ -1134,7 +1336,7 @@ func TestLoadConfigFile_Vault_Retry_Empty(t *testing.T) {
}
func TestLoadConfigFile_EnforceConsistency(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-consistency.hcl")
config, err := LoadConfigFile("./test-fixtures/config-consistency.hcl")
if err != nil {
t.Fatal(err)
}
@ -1155,11 +1357,6 @@ func TestLoadConfigFile_EnforceConsistency(t *testing.T) {
EnforceConsistency: "always",
WhenInconsistent: "retry",
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -1169,7 +1366,7 @@ func TestLoadConfigFile_EnforceConsistency(t *testing.T) {
}
func TestLoadConfigFile_EnforceConsistency_APIProxy(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-consistency-apiproxy.hcl")
config, err := LoadConfigFile("./test-fixtures/config-consistency-apiproxy.hcl")
if err != nil {
t.Fatal(err)
}
@ -1189,11 +1386,6 @@ func TestLoadConfigFile_EnforceConsistency_APIProxy(t *testing.T) {
EnforceConsistency: "always",
WhenInconsistent: "retry",
},
Vault: &Vault{
Retry: &Retry{
NumRetries: 12,
},
},
}
config.Prune()
@ -1203,7 +1395,7 @@ func TestLoadConfigFile_EnforceConsistency_APIProxy(t *testing.T) {
}
func TestLoadConfigFile_Disable_Idle_Conns_All(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-all.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-all.hcl")
if err != nil {
t.Fatal(err)
}
@ -1252,7 +1444,7 @@ func TestLoadConfigFile_Disable_Idle_Conns_All(t *testing.T) {
}
func TestLoadConfigFile_Disable_Idle_Conns_Auto_Auth(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-auto-auth.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-auto-auth.hcl")
if err != nil {
t.Fatal(err)
}
@ -1301,7 +1493,7 @@ func TestLoadConfigFile_Disable_Idle_Conns_Auto_Auth(t *testing.T) {
}
func TestLoadConfigFile_Disable_Idle_Conns_Templating(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-templating.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-templating.hcl")
if err != nil {
t.Fatal(err)
}
@ -1350,7 +1542,7 @@ func TestLoadConfigFile_Disable_Idle_Conns_Templating(t *testing.T) {
}
func TestLoadConfigFile_Disable_Idle_Conns_Caching(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-caching.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-caching.hcl")
if err != nil {
t.Fatal(err)
}
@ -1399,7 +1591,7 @@ func TestLoadConfigFile_Disable_Idle_Conns_Caching(t *testing.T) {
}
func TestLoadConfigFile_Disable_Idle_Conns_Proxying(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-proxying.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-proxying.hcl")
if err != nil {
t.Fatal(err)
}
@ -1448,7 +1640,7 @@ func TestLoadConfigFile_Disable_Idle_Conns_Proxying(t *testing.T) {
}
func TestLoadConfigFile_Disable_Idle_Conns_Empty(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-empty.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-empty.hcl")
if err != nil {
t.Fatal(err)
}
@ -1503,7 +1695,7 @@ func TestLoadConfigFile_Disable_Idle_Conns_Env(t *testing.T) {
if err != nil {
t.Fatal(err)
}
config, err := LoadConfig("./test-fixtures/config-disable-idle-connections-empty.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-idle-connections-empty.hcl")
if err != nil {
t.Fatal(err)
}
@ -1552,14 +1744,14 @@ func TestLoadConfigFile_Disable_Idle_Conns_Env(t *testing.T) {
}
func TestLoadConfigFile_Bad_Value_Disable_Idle_Conns(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-disable-idle-connections.hcl")
_, err := LoadConfigFile("./test-fixtures/bad-config-disable-idle-connections.hcl")
if err == nil {
t.Fatal("should have error, it didn't")
}
}
func TestLoadConfigFile_Disable_Keep_Alives_All(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-all.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-all.hcl")
if err != nil {
t.Fatal(err)
}
@ -1608,7 +1800,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_All(t *testing.T) {
}
func TestLoadConfigFile_Disable_Keep_Alives_Auto_Auth(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-auto-auth.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-auto-auth.hcl")
if err != nil {
t.Fatal(err)
}
@ -1657,7 +1849,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_Auto_Auth(t *testing.T) {
}
func TestLoadConfigFile_Disable_Keep_Alives_Templating(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-templating.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-templating.hcl")
if err != nil {
t.Fatal(err)
}
@ -1706,7 +1898,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_Templating(t *testing.T) {
}
func TestLoadConfigFile_Disable_Keep_Alives_Caching(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-caching.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-caching.hcl")
if err != nil {
t.Fatal(err)
}
@ -1755,7 +1947,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_Caching(t *testing.T) {
}
func TestLoadConfigFile_Disable_Keep_Alives_Proxying(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-proxying.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-proxying.hcl")
if err != nil {
t.Fatal(err)
}
@ -1804,7 +1996,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_Proxying(t *testing.T) {
}
func TestLoadConfigFile_Disable_Keep_Alives_Empty(t *testing.T) {
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-empty.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-empty.hcl")
if err != nil {
t.Fatal(err)
}
@ -1859,7 +2051,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_Env(t *testing.T) {
if err != nil {
t.Fatal(err)
}
config, err := LoadConfig("./test-fixtures/config-disable-keep-alives-empty.hcl")
config, err := LoadConfigFile("./test-fixtures/config-disable-keep-alives-empty.hcl")
if err != nil {
t.Fatal(err)
}
@ -1908,7 +2100,7 @@ func TestLoadConfigFile_Disable_Keep_Alives_Env(t *testing.T) {
}
func TestLoadConfigFile_Bad_Value_Disable_Keep_Alives(t *testing.T) {
_, err := LoadConfig("./test-fixtures/bad-config-disable-keep-alives.hcl")
_, err := LoadConfigFile("./test-fixtures/bad-config-disable-keep-alives.hcl")
if err == nil {
t.Fatal("should have error, it didn't")
}

View File

@ -0,0 +1,20 @@
pid_file = "./pidfile"
auto_auth {
method {
type = "aws"
config = {
role = "foobar"
}
}
sink {
type = "file"
config = {
path = "/tmp/file-foo"
}
aad = "foobar"
dh_type = "curve25519"
dh_path = "/tmp/file-foo-dhpath"
}
}

View File

@ -0,0 +1,6 @@
pid_file = "./pidfile"
listener "tcp" {
address = "127.0.0.1:8300"
tls_disable = true
}

View File

@ -0,0 +1,47 @@
pid_file = "./pidfile"
auto_auth {
method {
type = "aws"
config = {
role = "foobar"
}
}
sink {
type = "file"
config = {
path = "/tmp/file-foo"
}
aad = "foobar"
dh_type = "curve25519"
dh_path = "/tmp/file-foo-dhpath"
}
}
listener "unix" {
address = "/path/to/socket"
tls_disable = true
socket_mode = "configmode"
socket_user = "configuser"
socket_group = "configgroup"
}
listener "tcp" {
address = "127.0.0.1:8300"
tls_disable = true
}
listener {
type = "tcp"
address = "127.0.0.1:3000"
tls_disable = true
role = "metrics_only"
}
listener "tcp" {
role = "default"
address = "127.0.0.1:8400"
tls_key_file = "/path/to/cakey.pem"
tls_cert_file = "/path/to/cacert.pem"
}

View File

@ -0,0 +1,19 @@
cache {
use_auto_auth_token = true
persist = {
type = "kubernetes"
path = "/vault/agent-cache/"
keep_after_import = true
exit_on_err = true
service_account_token_file = "/tmp/serviceaccount/token"
}
}
vault {
address = "http://127.0.0.1:1111"
ca_cert = "config_ca_cert"
ca_path = "config_ca_path"
tls_skip_verify = "true"
client_cert = "config_client_cert"
client_key = "config_client_key"
}

View File

@ -0,0 +1,8 @@
vault {
address = "http://127.0.0.1:1111"
ca_cert = "config_ca_cert"
ca_path = "config_ca_path"
tls_skip_verify = "true"
client_cert = "config_client_cert"
client_key = "config_client_key"
}

View File

@ -0,0 +1,20 @@
pid_file = "./pidfile"
auto_auth {
method {
type = "aws"
config = {
role = "foobar"
}
}
sink {
type = "file"
config = {
path = "/tmp/file-foo"
}
aad = "foobar"
dh_type = "curve25519"
dh_path = "/tmp/file-foo-dhpath"
}
}

View File

@ -264,9 +264,9 @@ func newRunnerConfig(sc *ServerConfig, templates ctconfig.TemplateConfigs) (*ctc
ServerName: pointerutil.StringPtr(""),
}
// We need to assign something to Vault.Retry or it will use its default of 12 retries.
// If Vault.Retry isn't specified, use the default of 12 retries.
// This retry value will be respected regardless of if we use the cache.
var attempts int
attempts := ctconfig.DefaultRetryAttempts
if sc.AgentConfig.Vault != nil && sc.AgentConfig.Vault.Retry != nil {
attempts = sc.AgentConfig.Vault.Retry.NumRetries
}

View File

@ -61,191 +61,6 @@ func testAgentCommand(tb testing.TB, logger hclog.Logger) (*cli.MockUi, *AgentCo
}
}
/*
func TestAgent_Cache_UnixListener(t *testing.T) {
logger := logging.NewVaultLogger(hclog.Trace)
coreConfig := &vault.CoreConfig{
Logger: logger.Named("core"),
CredentialBackends: map[string]logical.Factory{
"jwt": vaultjwt.Factory,
},
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
defer cluster.Cleanup()
vault.TestWaitActive(t, cluster.Cores[0].Core)
client := cluster.Cores[0].Client
defer os.Setenv(api.EnvVaultAddress, os.Getenv(api.EnvVaultAddress))
os.Setenv(api.EnvVaultAddress, client.Address())
defer os.Setenv(api.EnvVaultCACert, os.Getenv(api.EnvVaultCACert))
os.Setenv(api.EnvVaultCACert, fmt.Sprintf("%s/ca_cert.pem", cluster.TempDir))
// Setup Vault
err := client.Sys().EnableAuthWithOptions("jwt", &api.EnableAuthOptions{
Type: "jwt",
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("auth/jwt/config", map[string]interface{}{
"bound_issuer": "https://team-vault.auth0.com/",
"jwt_validation_pubkeys": agent.TestECDSAPubKey,
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write("auth/jwt/role/test", map[string]interface{}{
"role_type": "jwt",
"bound_subject": "r3qXcK2bix9eFECzsU3Sbmh0K16fatW6@clients",
"bound_audiences": "https://vault.plugin.auth.jwt.test",
"user_claim": "https://vault/user",
"groups_claim": "https://vault/groups",
"policies": "test",
"period": "3s",
})
if err != nil {
t.Fatal(err)
}
inf, err := ioutil.TempFile("", "auth.jwt.test.")
if err != nil {
t.Fatal(err)
}
in := inf.Name()
inf.Close()
os.Remove(in)
t.Logf("input: %s", in)
sink1f, err := ioutil.TempFile("", "sink1.jwt.test.")
if err != nil {
t.Fatal(err)
}
sink1 := sink1f.Name()
sink1f.Close()
os.Remove(sink1)
t.Logf("sink1: %s", sink1)
sink2f, err := ioutil.TempFile("", "sink2.jwt.test.")
if err != nil {
t.Fatal(err)
}
sink2 := sink2f.Name()
sink2f.Close()
os.Remove(sink2)
t.Logf("sink2: %s", sink2)
conff, err := ioutil.TempFile("", "conf.jwt.test.")
if err != nil {
t.Fatal(err)
}
conf := conff.Name()
conff.Close()
os.Remove(conf)
t.Logf("config: %s", conf)
jwtToken, _ := agent.GetTestJWT(t)
if err := ioutil.WriteFile(in, []byte(jwtToken), 0600); err != nil {
t.Fatal(err)
} else {
logger.Trace("wrote test jwt", "path", in)
}
socketff, err := ioutil.TempFile("", "cache.socket.")
if err != nil {
t.Fatal(err)
}
socketf := socketff.Name()
socketff.Close()
os.Remove(socketf)
t.Logf("socketf: %s", socketf)
config := `
auto_auth {
method {
type = "jwt"
config = {
role = "test"
path = "%s"
}
}
sink {
type = "file"
config = {
path = "%s"
}
}
sink "file" {
config = {
path = "%s"
}
}
}
cache {
use_auto_auth_token = true
listener "unix" {
address = "%s"
tls_disable = true
}
}
`
config = fmt.Sprintf(config, in, sink1, sink2, socketf)
if err := ioutil.WriteFile(conf, []byte(config), 0600); err != nil {
t.Fatal(err)
} else {
logger.Trace("wrote test config", "path", conf)
}
_, cmd := testAgentCommand(t, logger)
cmd.client = client
// Kill the command 5 seconds after it starts
go func() {
select {
case <-cmd.ShutdownCh:
case <-time.After(5 * time.Second):
cmd.ShutdownCh <- struct{}{}
}
}()
originalVaultAgentAddress := os.Getenv(api.EnvVaultAgentAddr)
// Create a client that talks to the agent
os.Setenv(api.EnvVaultAgentAddr, socketf)
testClient, err := api.NewClient(api.DefaultConfig())
if err != nil {
t.Fatal(err)
}
os.Setenv(api.EnvVaultAgentAddr, originalVaultAgentAddress)
// Start the agent
go cmd.Run([]string{"-config", conf})
// Give some time for the auto-auth to complete
time.Sleep(1 * time.Second)
// Invoke lookup self through the agent
secret, err := testClient.Auth().Token().LookupSelf()
if err != nil {
t.Fatal(err)
}
if secret == nil || secret.Data == nil || secret.Data["id"].(string) == "" {
t.Fatalf("failed to perform lookup self through agent")
}
}
*/
func TestAgent_ExitAfterAuth(t *testing.T) {
t.Run("via_config", func(t *testing.T) {
testAgentExitAfterAuth(t, false)
@ -2254,7 +2069,7 @@ cache {}
func TestAgent_LogFile_CliOverridesConfig(t *testing.T) {
// Create basic config
configFile := populateTempFile(t, "agent-config.hcl", BasicHclConfig)
cfg, err := agentConfig.LoadConfig(configFile.Name())
cfg, err := agentConfig.LoadConfigFile(configFile.Name())
if err != nil {
t.Fatal("Cannot load config to test update/merge", err)
}
@ -2282,7 +2097,7 @@ func TestAgent_LogFile_CliOverridesConfig(t *testing.T) {
func TestAgent_LogFile_Config(t *testing.T) {
configFile := populateTempFile(t, "agent-config.hcl", BasicHclConfig)
cfg, err := agentConfig.LoadConfig(configFile.Name())
cfg, err := agentConfig.LoadConfigFile(configFile.Name())
if err != nil {
t.Fatal("Cannot load config to test update/merge", err)
}

View File

@ -361,6 +361,12 @@ To run Vault Agent:
$ vault agent -h
```
As with Vault, the `-config` flag can be used in three different ways:
- Use the flag once to name the path to a single specific configuration file.
- Use the flag multiple times to name multiple configuration files, which will be composed at runtime.
- Use the flag to name a directory of configuration files, the contents of which will be composed at runtime.
## Example Configuration
An example configuration, with very contrived values, follows: