From 361e515a5d9e7f9a82eafa0ae55e5a11f5f5748f Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Wed, 6 Oct 2021 22:21:01 -0700 Subject: [PATCH 01/13] agent: Use an in-process listener with cache Uses a bufconn listener between consul-template and vault-agent, when cache and templates are in use. This means no listeners need to be defined in vault-agent for just templating. Always routes consul-template through the vault-agent cache (instead of only when persistent cache is enabled). --- command/agent.go | 27 +- command/agent/config/config.go | 17 +- command/agent/config/config_test.go | 72 ++++- .../config-cache-no-listeners.hcl | 45 ++++ command/agent/template/template.go | 29 +- command/agent/template/template_test.go | 255 +++++------------- go.mod | 5 +- go.sum | 10 +- internalshared/listenerutil/bufconn.go | 34 +++ 9 files changed, 262 insertions(+), 232 deletions(-) create mode 100644 command/agent/config/test-fixtures/config-cache-no-listeners.hcl create mode 100644 internalshared/listenerutil/bufconn.go diff --git a/command/agent.go b/command/agent.go index 30f387a722753..8ffab4c03b951 100644 --- a/command/agent.go +++ b/command/agent.go @@ -2,6 +2,7 @@ package command import ( "context" + "crypto/tls" "flag" "fmt" "io" @@ -40,6 +41,8 @@ import ( "github.com/hashicorp/vault/command/agent/sink/inmem" "github.com/hashicorp/vault/command/agent/template" "github.com/hashicorp/vault/command/agent/winsvc" + "github.com/hashicorp/vault/internalshared/configutil" + "github.com/hashicorp/vault/internalshared/listenerutil" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/logical" @@ -470,7 +473,7 @@ func (c *AgentCommand) Run(args []string) int { var leaseCache *cache.LeaseCache var previousToken string // Parse agent listener configurations - if config.Cache != nil && len(config.Listeners) != 0 { + if config.Cache != nil { cacheLogger := c.logger.Named("cache") // Create the API proxier @@ -666,11 +669,25 @@ func (c *AgentCommand) Run(args []string) int { cacheHandler := cache.Handler(ctx, cacheLogger, leaseCache, inmemSink, proxyVaultToken) var listeners []net.Listener + + // If there are templates, add an in-process listener + if len(config.Templates) > 0 { + config.Listeners = append(config.Listeners, &configutil.Listener{Type: "bufconn"}) + } for i, lnConfig := range config.Listeners { - ln, tlsConf, err := cache.StartListener(lnConfig) - if err != nil { - c.UI.Error(fmt.Sprintf("Error starting listener: %v", err)) - return 1 + var ln net.Listener + var tlsConf *tls.Config + + if lnConfig.Type == "bufconn" { + inProcListener := listenerutil.NewBufConnListener() + config.Cache.InProcDialer = inProcListener + ln = inProcListener + } else { + ln, tlsConf, err = cache.StartListener(lnConfig) + if err != nil { + c.UI.Error(fmt.Sprintf("Error starting listener: %v", err)) + return 1 + } } listeners = append(listeners, ln) diff --git a/command/agent/config/config.go b/command/agent/config/config.go index 9438bd327444d..889c1fea4b74b 100644 --- a/command/agent/config/config.go +++ b/command/agent/config/config.go @@ -65,12 +65,13 @@ type Vault struct { // Cache contains any configuration needed for Cache mode type Cache struct { - UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"` - UseAutoAuthToken bool `hcl:"-"` - ForceAutoAuthToken bool `hcl:"-"` - EnforceConsistency string `hcl:"enforce_consistency"` - WhenInconsistent string `hcl:"when_inconsistent"` - Persist *Persist `hcl:"persist"` + UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"` + UseAutoAuthToken bool `hcl:"-"` + ForceAutoAuthToken bool `hcl:"-"` + EnforceConsistency string `hcl:"enforce_consistency"` + WhenInconsistent string `hcl:"when_inconsistent"` + Persist *Persist `hcl:"persist"` + InProcDialer ctconfig.TransportDialer `hcl:"-"` } // Persist contains configuration needed for persistent caching @@ -196,8 +197,8 @@ func LoadConfig(path string) (*Config, error) { } if result.Cache != nil { - if len(result.Listeners) < 1 { - return nil, fmt.Errorf("at least one listener required when cache enabled") + if len(result.Listeners) < 1 && len(result.Templates) < 1 { + return nil, fmt.Errorf("at least one listener required when cache enabled and no templates defined") } if result.Cache.UseAutoAuthToken { diff --git a/command/agent/config/config_test.go b/command/agent/config/config_test.go index 0db8cf91954f7..27c48d1afef6b 100644 --- a/command/agent/config/config_test.go +++ b/command/agent/config/config_test.go @@ -105,6 +105,74 @@ func TestLoadConfigFile_AgentCache(t *testing.T) { } } +func TestLoadConfigFile_AgentCache_NoListeners(t *testing.T) { + config, err := LoadConfig("./test-fixtures/config-cache-no-listeners.hcl") + if err != nil { + t.Fatal(err) + } + + expected := &Config{ + SharedConfig: &configutil.SharedConfig{ + PidFile: "./pidfile", + }, + 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", + }, + }, + }, + }, + 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, + }, + }, + Templates: []*ctconfig.TemplateConfig{ + { + Source: pointerutil.StringPtr("/path/on/disk/to/template.ctmpl"), + Destination: pointerutil.StringPtr("/path/on/disk/where/template/will/render.txt"), + }, + }, + } + + config.Prune() + if diff := deep.Equal(config, expected); diff != nil { + t.Fatal(diff) + } +} + func TestLoadConfigFile(t *testing.T) { if err := os.Setenv("TEST_AAD_ENV", "aad"); err != nil { t.Fatal(err) @@ -270,7 +338,7 @@ func TestLoadConfigFile_Bad_AgentCache_ForceAutoAuthNoMethod(t *testing.T) { 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") + t.Fatal("LoadConfig should return an error when cache section present and no listeners present and no templates defined") } } @@ -536,7 +604,6 @@ func TestLoadConfigFile_AgentCache_PersistMissingType(t *testing.T) { } func TestLoadConfigFile_TemplateConfig(t *testing.T) { - testCases := map[string]struct { fixturePath string expectedTemplateConfig TemplateConfig @@ -586,7 +653,6 @@ func TestLoadConfigFile_TemplateConfig(t *testing.T) { } }) } - } // TestLoadConfigFile_Template tests template definitions in Vault Agent diff --git a/command/agent/config/test-fixtures/config-cache-no-listeners.hcl b/command/agent/config/test-fixtures/config-cache-no-listeners.hcl new file mode 100644 index 0000000000000..d7176e0aa539a --- /dev/null +++ b/command/agent/config/test-fixtures/config-cache-no-listeners.hcl @@ -0,0 +1,45 @@ +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" + } +} + +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" +} + +template { + source = "/path/on/disk/to/template.ctmpl" + destination = "/path/on/disk/where/template/will/render.txt" +} diff --git a/command/agent/template/template.go b/command/agent/template/template.go index 102481e2dc9e9..a57ffd482b451 100644 --- a/command/agent/template/template.go +++ b/command/agent/template/template.go @@ -264,10 +264,7 @@ func newRunnerConfig(sc *ServerConfig, templates ctconfig.TemplateConfigs) (*ctc } // Use the cache if available or fallback to the Vault server values. - // For now we're only routing templating through the cache when persistence - // is enabled. The templating engine and the cache have some inconsistencies - // that need to be fixed for 1.7x/1.8 - if sc.AgentConfig.Cache != nil && sc.AgentConfig.Cache.Persist != nil && len(sc.AgentConfig.Listeners) != 0 { + if sc.AgentConfig.Cache != nil { attempts = 0 // If we don't want exit on template retry failure (i.e. unlimited @@ -283,23 +280,17 @@ func newRunnerConfig(sc *ServerConfig, templates ctconfig.TemplateConfigs) (*ctc attempts = ctconfig.DefaultRetryAttempts } - scheme := "unix://" - if sc.AgentConfig.Listeners[0].Type == "tcp" { - scheme = "https://" - if sc.AgentConfig.Listeners[0].TLSDisable { - scheme = "http://" - } + if sc.AgentConfig.Cache.InProcDialer == nil { + return nil, fmt.Errorf("missing in-process dialer configuration") } - address := fmt.Sprintf("%s%s", scheme, sc.AgentConfig.Listeners[0].Address) - conf.Vault.Address = &address - - // Skip verification if its using the cache because they're part of the same agent. - if scheme == "https://" { - if sc.AgentConfig.Listeners[0].TLSRequireAndVerifyClientCert { - return nil, errors.New("template server cannot use local cache when mTLS is enabled") - } - conf.Vault.SSL.Verify = pointerutil.BoolPtr(false) + if conf.Vault.Transport == nil { + conf.Vault.Transport = &ctconfig.TransportConfig{} } + conf.Vault.Transport.CustomDialer = sc.AgentConfig.Cache.InProcDialer + // The in-process dialer ignores the address passed in, but we're still + // setting it here to satisfy the http client + conf.Vault.Address = pointerutil.StringPtr("http://localhost") + } else if strings.HasPrefix(sc.AgentConfig.Vault.Address, "https") || sc.AgentConfig.Vault.CACert != "" { skipVerify := sc.AgentConfig.Vault.TLSSkipVerify verify := !skipVerify diff --git a/command/agent/template/template_test.go b/command/agent/template/template_test.go index af26f15e3f54b..d4de5c870fffb 100644 --- a/command/agent/template/template_test.go +++ b/command/agent/template/template_test.go @@ -15,8 +15,11 @@ import ( "github.com/hashicorp/go-hclog" "github.com/hashicorp/vault/command/agent/config" "github.com/hashicorp/vault/internalshared/configutil" + "github.com/hashicorp/vault/internalshared/listenerutil" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/helper/pointerutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // TestNewServer is a simple test to make sure NewServer returns a Server and @@ -77,44 +80,7 @@ func newAgentConfig(listeners []*configutil.Listener, enableCache, enablePersise return agentConfig } -func TestCacheConfigUnix(t *testing.T) { - listeners := []*configutil.Listener{ - { - Type: "unix", - Address: "foobar", - 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:8400", - TLSKeyFile: "/path/to/cakey.pem", - TLSCertFile: "/path/to/cacert.pem", - }, - } - - agentConfig := newAgentConfig(listeners, true, true) - serverConfig := ServerConfig{AgentConfig: agentConfig} - - ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - expected := "unix://foobar" - if *ctConfig.Vault.Address != expected { - t.Fatalf("expected %s, got %s", expected, *ctConfig.Vault.Address) - } -} - -func TestCacheConfigHTTP(t *testing.T) { +func TestCacheConfig(t *testing.T) { listeners := []*configutil.Listener{ { Type: "tcp", @@ -137,132 +103,69 @@ func TestCacheConfigHTTP(t *testing.T) { }, } - agentConfig := newAgentConfig(listeners, true, true) - serverConfig := ServerConfig{AgentConfig: agentConfig} - - ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - expected := "http://127.0.0.1:8300" - if *ctConfig.Vault.Address != expected { - t.Fatalf("expected %s, got %s", expected, *ctConfig.Vault.Address) - } -} - -func TestCacheConfigHTTPS(t *testing.T) { - listeners := []*configutil.Listener{ - { - Type: "tcp", - Address: "127.0.0.1:8300", - TLSKeyFile: "/path/to/cakey.pem", - TLSCertFile: "/path/to/cacert.pem", + cases := map[string]struct { + cacheEnabled bool + persistentCacheEnabled bool + setDialer bool + expectedErr string + expectCustomDialer bool + }{ + "persistent_cache": { + cacheEnabled: true, + persistentCacheEnabled: true, + setDialer: true, + expectedErr: "", + expectCustomDialer: true, }, - { - Type: "unix", - Address: "foobar", - TLSDisable: true, - SocketMode: "configmode", - SocketUser: "configuser", - SocketGroup: "configgroup", + "memory_cache": { + cacheEnabled: true, + persistentCacheEnabled: false, + setDialer: true, + expectedErr: "", + expectCustomDialer: true, }, - { - Type: "tcp", - Address: "127.0.0.1:8400", - TLSDisable: true, + "no_cache": { + cacheEnabled: false, + persistentCacheEnabled: false, + setDialer: false, + expectedErr: "", + expectCustomDialer: false, }, - } - - agentConfig := newAgentConfig(listeners, true, true) - serverConfig := ServerConfig{AgentConfig: agentConfig} - - ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - expected := "https://127.0.0.1:8300" - if *ctConfig.Vault.Address != expected { - t.Fatalf("expected %s, got %s", expected, *ctConfig.Vault.Address) - } - - if *ctConfig.Vault.SSL.Verify { - t.Fatalf("expected %t, got %t", true, *ctConfig.Vault.SSL.Verify) - } -} - -func TestCacheConfigNoCache(t *testing.T) { - listeners := []*configutil.Listener{ - { - Type: "tcp", - Address: "127.0.0.1:8300", - TLSKeyFile: "/path/to/cakey.pem", - TLSCertFile: "/path/to/cacert.pem", - }, - { - Type: "unix", - Address: "foobar", - TLSDisable: true, - SocketMode: "configmode", - SocketUser: "configuser", - SocketGroup: "configgroup", - }, - { - Type: "tcp", - Address: "127.0.0.1:8400", - TLSDisable: true, + "cache_no_dialer": { + cacheEnabled: true, + persistentCacheEnabled: false, + setDialer: false, + expectedErr: "missing in-process dialer configuration", + expectCustomDialer: false, }, } - agentConfig := newAgentConfig(listeners, false, false) - serverConfig := ServerConfig{AgentConfig: agentConfig} - - ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - expected := "http://127.0.0.1:1111" - if *ctConfig.Vault.Address != expected { - t.Fatalf("expected %s, got %s", expected, *ctConfig.Vault.Address) - } -} - -func TestCacheConfigNoPersistentCache(t *testing.T) { - listeners := []*configutil.Listener{ - { - Type: "tcp", - Address: "127.0.0.1:8300", - TLSKeyFile: "/path/to/cakey.pem", - TLSCertFile: "/path/to/cacert.pem", - }, - { - Type: "unix", - Address: "foobar", - TLSDisable: true, - SocketMode: "configmode", - SocketUser: "configuser", - SocketGroup: "configgroup", - }, - { - Type: "tcp", - Address: "127.0.0.1:8400", - TLSDisable: true, - }, - } + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + agentConfig := newAgentConfig(listeners, tc.cacheEnabled, tc.persistentCacheEnabled) + if tc.setDialer && tc.cacheEnabled { + bListener := listenerutil.NewBufConnListener() + defer bListener.Close() + agentConfig.Cache.InProcDialer = bListener + } + serverConfig := ServerConfig{AgentConfig: agentConfig} - agentConfig := newAgentConfig(listeners, true, false) - serverConfig := ServerConfig{AgentConfig: agentConfig} + ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) + if len(tc.expectedErr) > 0 { + require.Error(t, err, tc.expectedErr) + return + } - ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) + require.NotNil(t, ctConfig) + assert.Equal(t, tc.expectCustomDialer, ctConfig.Vault.Transport.CustomDialer != nil) - expected := "http://127.0.0.1:1111" - if *ctConfig.Vault.Address != expected { - t.Fatalf("expected %s, got %s", expected, *ctConfig.Vault.Address) + if tc.expectCustomDialer { + assert.Equal(t, "http://localhost", *ctConfig.Vault.Address) + } else { + assert.Equal(t, "http://127.0.0.1:1111", *ctConfig.Vault.Address) + } + }) } } @@ -270,6 +173,9 @@ func TestCacheConfigNoListener(t *testing.T) { listeners := []*configutil.Listener{} agentConfig := newAgentConfig(listeners, true, true) + bListener := listenerutil.NewBufConnListener() + defer bListener.Close() + agentConfig.Cache.InProcDialer = bListener serverConfig := ServerConfig{AgentConfig: agentConfig} ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) @@ -277,43 +183,8 @@ func TestCacheConfigNoListener(t *testing.T) { t.Fatalf("unexpected error: %s", err) } - expected := "http://127.0.0.1:1111" - if *ctConfig.Vault.Address != expected { - t.Fatalf("expected %s, got %s", expected, *ctConfig.Vault.Address) - } -} - -func TestCacheConfigRejectMTLS(t *testing.T) { - listeners := []*configutil.Listener{ - { - Type: "tcp", - Address: "127.0.0.1:8300", - TLSKeyFile: "/path/to/cakey.pem", - TLSCertFile: "/path/to/cacert.pem", - TLSRequireAndVerifyClientCert: true, - }, - { - Type: "unix", - Address: "foobar", - TLSDisable: true, - SocketMode: "configmode", - SocketUser: "configuser", - SocketGroup: "configgroup", - }, - { - Type: "tcp", - Address: "127.0.0.1:8400", - TLSDisable: true, - }, - } - - agentConfig := newAgentConfig(listeners, true, true) - serverConfig := ServerConfig{AgentConfig: agentConfig} - - _, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) - if err == nil { - t.Fatal("expected error, got none") - } + assert.Equal(t, "http://localhost", *ctConfig.Vault.Address) + assert.NotNil(t, ctConfig.Vault.Transport.CustomDialer) } func TestServerRun(t *testing.T) { diff --git a/go.mod b/go.mod index 9743be8db8a37..f9909ad2f347f 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,8 @@ replace github.com/hashicorp/vault/sdk => ./sdk replace go.etcd.io/etcd/client/pkg/v3 v3.5.0 => go.etcd.io/etcd/client/pkg/v3 v3.0.0-20210928084031-3df272774672 +replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211001014530-1148ff14aa78 + require ( cloud.google.com/go v0.56.0 cloud.google.com/go/spanner v1.5.1 @@ -162,6 +164,7 @@ require ( github.com/rboyer/safeio v0.2.1 github.com/ryanuber/columnize v2.1.0+incompatible github.com/ryanuber/go-glob v1.0.0 + github.com/ryboe/q v1.0.14 // indirect github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da github.com/sasha-s/go-deadlock v0.2.0 github.com/sethvargo/go-limiter v0.7.1 @@ -188,7 +191,7 @@ require ( go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 diff --git a/go.sum b/go.sum index e2b12fc39b74d..d6f74b9aa8261 100644 --- a/go.sum +++ b/go.sum @@ -567,8 +567,6 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/cap v0.1.0 h1:uBDfu9NDvmotza/mJW6vtQId+VYid9ztlTnDCW6YUWU= github.com/hashicorp/cap v0.1.0/go.mod h1:VfBvK2ULRyqsuqAnjgZl7HJ7/CGMC7ro4H5eXiZuun8= -github.com/hashicorp/consul-template v0.27.0 h1:UwDPC7+SsHIkEWDul+Z4JfBEz3N2S4l7YwAHMAGLhQk= -github.com/hashicorp/consul-template v0.27.0/go.mod h1:/3Z8sazWqkRMZ9vxlstVp/7hOnL8UInzzFTnNHPHWKo= github.com/hashicorp/consul/api v1.4.0 h1:jfESivXnO5uLdH650JU/6AnjRoHrLhULq0FnC3Kp9EY= github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -1092,6 +1090,8 @@ github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUW github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/ryboe/q v1.0.14 h1:sjSjEXz86Dn9vLHaosaLXj6iNoljfKuUeSCSkiNkvJs= +github.com/ryboe/q v1.0.14/go.mod h1:yHEXUGvMyyQipX7WljCYWgzDuY6iOg0+VTSn5QZ2Pxk= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y= @@ -1179,6 +1179,8 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tvoran/consul-template v0.27.2-0.20211001014530-1148ff14aa78 h1:dEx3WvHwWB19NzaLwU/HviLtkFa2dwlbf3hRLZeHKvE= +github.com/tvoran/consul-template v0.27.2-0.20211001014530-1148ff14aa78/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= @@ -1283,8 +1285,9 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1361,7 +1364,6 @@ golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c/go.mod h1:iQL9McJNjoIa5mjH6nYTCTZXUN6RP+XW3eib7Ya3XcI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/internalshared/listenerutil/bufconn.go b/internalshared/listenerutil/bufconn.go new file mode 100644 index 0000000000000..9d49ca7e9d4bd --- /dev/null +++ b/internalshared/listenerutil/bufconn.go @@ -0,0 +1,34 @@ +package listenerutil + +import ( + "net" + + "google.golang.org/grpc/test/bufconn" +) + +type BufConnListener struct { + listener *bufconn.Listener +} + +func NewBufConnListener() *BufConnListener { + buffer := 1024 * 1024 + listener := bufconn.Listen(buffer) + + return &BufConnListener{listener: listener} +} + +func (bcl *BufConnListener) Accept() (net.Conn, error) { + return bcl.listener.Accept() +} + +func (bcl *BufConnListener) Close() error { + return bcl.listener.Close() +} + +func (bcl *BufConnListener) Dial(network, addr string) (net.Conn, error) { + return bcl.listener.Dial() +} + +func (bcl *BufConnListener) Addr() net.Addr { + return bcl.listener.Addr() +} From 07d6fc24e269adcafbf8b091fc498691f43b6a6f Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Wed, 6 Oct 2021 22:31:42 -0700 Subject: [PATCH 02/13] changelog --- changelog/12762.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/12762.txt diff --git a/changelog/12762.txt b/changelog/12762.txt new file mode 100644 index 0000000000000..ad1ca5c5230df --- /dev/null +++ b/changelog/12762.txt @@ -0,0 +1,3 @@ +```release-note:improvement +agent/cache: Use an in-process listener between consul-template and vault-agent when caching and templates are in use +``` From db7d50d06d1460dd8ac31c691d61329bb2044c9f Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 8 Oct 2021 14:52:11 -0700 Subject: [PATCH 03/13] Update command/agent/config/config.go Co-authored-by: Tom Proctor --- command/agent/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/agent/config/config.go b/command/agent/config/config.go index 889c1fea4b74b..427367433b8d6 100644 --- a/command/agent/config/config.go +++ b/command/agent/config/config.go @@ -198,7 +198,7 @@ func LoadConfig(path string) (*Config, error) { if result.Cache != nil { if len(result.Listeners) < 1 && len(result.Templates) < 1 { - return nil, fmt.Errorf("at least one listener required when cache enabled and no templates defined") + return nil, fmt.Errorf("the cache is enabled but not usable because no listeners or templates are defined") } if result.Cache.UseAutoAuthToken { From ed3526ebb04c2791ee8e6512a6c70a6cb4f81663 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 8 Oct 2021 15:45:22 -0700 Subject: [PATCH 04/13] BufConnListenerDialer and doc strings --- command/agent.go | 2 +- command/agent/template/template_test.go | 4 +-- internalshared/listenerutil/bufconn.go | 34 ++++++++++++++++++------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/command/agent.go b/command/agent.go index 8ffab4c03b951..1100ec0b8dbd7 100644 --- a/command/agent.go +++ b/command/agent.go @@ -679,7 +679,7 @@ func (c *AgentCommand) Run(args []string) int { var tlsConf *tls.Config if lnConfig.Type == "bufconn" { - inProcListener := listenerutil.NewBufConnListener() + inProcListener := listenerutil.NewBufConnListenerDialer() config.Cache.InProcDialer = inProcListener ln = inProcListener } else { diff --git a/command/agent/template/template_test.go b/command/agent/template/template_test.go index d4de5c870fffb..fe1571c1f92d6 100644 --- a/command/agent/template/template_test.go +++ b/command/agent/template/template_test.go @@ -144,7 +144,7 @@ func TestCacheConfig(t *testing.T) { t.Run(name, func(t *testing.T) { agentConfig := newAgentConfig(listeners, tc.cacheEnabled, tc.persistentCacheEnabled) if tc.setDialer && tc.cacheEnabled { - bListener := listenerutil.NewBufConnListener() + bListener := listenerutil.NewBufConnListenerDialer() defer bListener.Close() agentConfig.Cache.InProcDialer = bListener } @@ -173,7 +173,7 @@ func TestCacheConfigNoListener(t *testing.T) { listeners := []*configutil.Listener{} agentConfig := newAgentConfig(listeners, true, true) - bListener := listenerutil.NewBufConnListener() + bListener := listenerutil.NewBufConnListenerDialer() defer bListener.Close() agentConfig.Cache.InProcDialer = bListener serverConfig := ServerConfig{AgentConfig: agentConfig} diff --git a/internalshared/listenerutil/bufconn.go b/internalshared/listenerutil/bufconn.go index 9d49ca7e9d4bd..993f47206cecc 100644 --- a/internalshared/listenerutil/bufconn.go +++ b/internalshared/listenerutil/bufconn.go @@ -3,32 +3,48 @@ package listenerutil import ( "net" + ctconfig "github.com/hashicorp/consul-template/config" "google.golang.org/grpc/test/bufconn" ) -type BufConnListener struct { +var ( + _ net.Listener = (*BufConnListenerDialer)(nil) + _ ctconfig.TransportDialer = (*BufConnListenerDialer)(nil) +) + +// BufConnListenerDialer implements both a net.Listener and consul +// TransportDialer, to serve both ends of an in-process connection (Dial and +// Accept). +type BufConnListenerDialer struct { listener *bufconn.Listener } -func NewBufConnListener() *BufConnListener { +// NewBufConnListenerDialer returns a new BufConnListenerDialer +func NewBufConnListenerDialer() *BufConnListenerDialer { buffer := 1024 * 1024 listener := bufconn.Listen(buffer) - return &BufConnListener{listener: listener} + return &BufConnListenerDialer{listener: listener} } -func (bcl *BufConnListener) Accept() (net.Conn, error) { +// Accept incoming connections to the bufconn listener +func (bcl *BufConnListenerDialer) Accept() (net.Conn, error) { return bcl.listener.Accept() } -func (bcl *BufConnListener) Close() error { +// Close the bufconn +func (bcl *BufConnListenerDialer) Close() error { return bcl.listener.Close() } -func (bcl *BufConnListener) Dial(network, addr string) (net.Conn, error) { - return bcl.listener.Dial() +// Addr returns the net.Addr of the bufconn listener +func (bcl *BufConnListenerDialer) Addr() net.Addr { + return bcl.listener.Addr() } -func (bcl *BufConnListener) Addr() net.Addr { - return bcl.listener.Addr() +// Dial and connect to the listening end of the bufconn (satisfies +// consul-template's TransportDialer interface). This is essentially the client +// side of the bufconn connection. +func (bcl *BufConnListenerDialer) Dial(network, addr string) (net.Conn, error) { + return bcl.listener.Dial() } From 4bf6c9934692bc14e81ca7ee464e8996efa76750 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Tue, 12 Oct 2021 15:43:01 -0700 Subject: [PATCH 05/13] update consul-template dep --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0399d6cd90a6f..351011a0e66d4 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ replace github.com/hashicorp/vault/sdk => ./sdk replace go.etcd.io/etcd/client/pkg/v3 v3.5.0 => go.etcd.io/etcd/client/pkg/v3 v3.0.0-20210928084031-3df272774672 -replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211001014530-1148ff14aa78 +replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211012192322-e61ddbd05d86 require ( cloud.google.com/go v0.56.0 diff --git a/go.sum b/go.sum index fed1b74921c3b..c63affb3e0ab0 100644 --- a/go.sum +++ b/go.sum @@ -1186,8 +1186,8 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tvoran/consul-template v0.27.2-0.20211001014530-1148ff14aa78 h1:dEx3WvHwWB19NzaLwU/HviLtkFa2dwlbf3hRLZeHKvE= -github.com/tvoran/consul-template v0.27.2-0.20211001014530-1148ff14aa78/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= +github.com/tvoran/consul-template v0.27.2-0.20211012192322-e61ddbd05d86 h1:dx1eIlbal5MzOcDvOAz+CMgIVV/eLld4VLPNJQ+IhD0= +github.com/tvoran/consul-template v0.27.2-0.20211012192322-e61ddbd05d86/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= From 8e260332bfe80c60c4ec9aeb4a62e636aed7a303 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Wed, 13 Oct 2021 12:08:01 -0700 Subject: [PATCH 06/13] limit BufConnListenerDialer to dialing functions Uses a local transportDialer interface in config.Cache{}. Adds DialContext() to BufConnListenerDialer. --- command/agent.go | 5 +-- command/agent/config/config.go | 26 ++++++++++---- command/agent/template/template_test.go | 9 ++--- go.mod | 2 +- go.sum | 4 +-- internalshared/listenerutil/bufconn.go | 48 +++++++++---------------- 6 files changed, 47 insertions(+), 47 deletions(-) diff --git a/command/agent.go b/command/agent.go index 1100ec0b8dbd7..b8c2f6e7e8f2e 100644 --- a/command/agent.go +++ b/command/agent.go @@ -51,6 +51,7 @@ import ( "github.com/mitchellh/cli" "github.com/oklog/run" "github.com/posener/complete" + "google.golang.org/grpc/test/bufconn" ) var ( @@ -679,8 +680,8 @@ func (c *AgentCommand) Run(args []string) int { var tlsConf *tls.Config if lnConfig.Type == "bufconn" { - inProcListener := listenerutil.NewBufConnListenerDialer() - config.Cache.InProcDialer = inProcListener + inProcListener := bufconn.Listen(1024 * 1024) + config.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(inProcListener) ln = inProcListener } else { ln, tlsConf, err = cache.StartListener(lnConfig) diff --git a/command/agent/config/config.go b/command/agent/config/config.go index 427367433b8d6..abe469e0f30a9 100644 --- a/command/agent/config/config.go +++ b/command/agent/config/config.go @@ -1,9 +1,11 @@ package config import ( + "context" "errors" "fmt" "io/ioutil" + "net" "os" "strings" "time" @@ -63,15 +65,25 @@ type Vault struct { Retry *Retry `hcl:"retry"` } +// transportDialer is an interface that allows passing a custom dialer function +// to an HTTP client's transport config +type transportDialer interface { + // Dial is intended to match https://pkg.go.dev/net#Dialer.Dial + Dial(network, address string) (net.Conn, error) + + // DialContext is intended to match https://pkg.go.dev/net#Dialer.DialContext + DialContext(ctx context.Context, network, address string) (net.Conn, error) +} + // Cache contains any configuration needed for Cache mode type Cache struct { - UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"` - UseAutoAuthToken bool `hcl:"-"` - ForceAutoAuthToken bool `hcl:"-"` - EnforceConsistency string `hcl:"enforce_consistency"` - WhenInconsistent string `hcl:"when_inconsistent"` - Persist *Persist `hcl:"persist"` - InProcDialer ctconfig.TransportDialer `hcl:"-"` + UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"` + UseAutoAuthToken bool `hcl:"-"` + ForceAutoAuthToken bool `hcl:"-"` + EnforceConsistency string `hcl:"enforce_consistency"` + WhenInconsistent string `hcl:"when_inconsistent"` + Persist *Persist `hcl:"persist"` + InProcDialer transportDialer `hcl:"-"` } // Persist contains configuration needed for persistent caching diff --git a/command/agent/template/template_test.go b/command/agent/template/template_test.go index fe1571c1f92d6..9f304325ba2e7 100644 --- a/command/agent/template/template_test.go +++ b/command/agent/template/template_test.go @@ -20,6 +20,7 @@ import ( "github.com/hashicorp/vault/sdk/helper/pointerutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/grpc/test/bufconn" ) // TestNewServer is a simple test to make sure NewServer returns a Server and @@ -144,9 +145,9 @@ func TestCacheConfig(t *testing.T) { t.Run(name, func(t *testing.T) { agentConfig := newAgentConfig(listeners, tc.cacheEnabled, tc.persistentCacheEnabled) if tc.setDialer && tc.cacheEnabled { - bListener := listenerutil.NewBufConnListenerDialer() + bListener := bufconn.Listen(1024 * 1024) defer bListener.Close() - agentConfig.Cache.InProcDialer = bListener + agentConfig.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(bListener) } serverConfig := ServerConfig{AgentConfig: agentConfig} @@ -173,9 +174,9 @@ func TestCacheConfigNoListener(t *testing.T) { listeners := []*configutil.Listener{} agentConfig := newAgentConfig(listeners, true, true) - bListener := listenerutil.NewBufConnListenerDialer() + bListener := bufconn.Listen(1024 * 1024) defer bListener.Close() - agentConfig.Cache.InProcDialer = bListener + agentConfig.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(bListener) serverConfig := ServerConfig{AgentConfig: agentConfig} ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) diff --git a/go.mod b/go.mod index 351011a0e66d4..405817002db64 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ replace github.com/hashicorp/vault/sdk => ./sdk replace go.etcd.io/etcd/client/pkg/v3 v3.5.0 => go.etcd.io/etcd/client/pkg/v3 v3.0.0-20210928084031-3df272774672 -replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211012192322-e61ddbd05d86 +replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211013180249-9860065fbe7f require ( cloud.google.com/go v0.56.0 diff --git a/go.sum b/go.sum index c63affb3e0ab0..d04086d2ac0ad 100644 --- a/go.sum +++ b/go.sum @@ -1186,8 +1186,8 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tvoran/consul-template v0.27.2-0.20211012192322-e61ddbd05d86 h1:dx1eIlbal5MzOcDvOAz+CMgIVV/eLld4VLPNJQ+IhD0= -github.com/tvoran/consul-template v0.27.2-0.20211012192322-e61ddbd05d86/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= +github.com/tvoran/consul-template v0.27.2-0.20211013180249-9860065fbe7f h1:wsbCGJyOn+1kg9TH2qOqIqPez8utzBnE5TxfSDEbJnA= +github.com/tvoran/consul-template v0.27.2-0.20211013180249-9860065fbe7f/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= diff --git a/internalshared/listenerutil/bufconn.go b/internalshared/listenerutil/bufconn.go index 993f47206cecc..1c87474bbd793 100644 --- a/internalshared/listenerutil/bufconn.go +++ b/internalshared/listenerutil/bufconn.go @@ -1,50 +1,36 @@ package listenerutil import ( + "context" "net" - ctconfig "github.com/hashicorp/consul-template/config" "google.golang.org/grpc/test/bufconn" ) -var ( - _ net.Listener = (*BufConnListenerDialer)(nil) - _ ctconfig.TransportDialer = (*BufConnListenerDialer)(nil) -) - -// BufConnListenerDialer implements both a net.Listener and consul -// TransportDialer, to serve both ends of an in-process connection (Dial and -// Accept). +// BufConnListenerDialer implements consul-template's TransportDialer using a +// bufconn listener, to provide a way to Dial the in-memory listener type BufConnListenerDialer struct { listener *bufconn.Listener } -// NewBufConnListenerDialer returns a new BufConnListenerDialer -func NewBufConnListenerDialer() *BufConnListenerDialer { - buffer := 1024 * 1024 - listener := bufconn.Listen(buffer) - - return &BufConnListenerDialer{listener: listener} -} - -// Accept incoming connections to the bufconn listener -func (bcl *BufConnListenerDialer) Accept() (net.Conn, error) { - return bcl.listener.Accept() -} - -// Close the bufconn -func (bcl *BufConnListenerDialer) Close() error { - return bcl.listener.Close() +// NewBufConnListenerDialer returns a new BufConnListenerDialer using an +// existing bufconn.Listener +func NewBufConnListenerDialer(bcl *bufconn.Listener) *BufConnListenerDialer { + return &BufConnListenerDialer{ + listener: bcl, + } } -// Addr returns the net.Addr of the bufconn listener -func (bcl *BufConnListenerDialer) Addr() net.Addr { - return bcl.listener.Addr() -} - -// Dial and connect to the listening end of the bufconn (satisfies +// Dial connects to the listening end of the bufconn (satisfies // consul-template's TransportDialer interface). This is essentially the client // side of the bufconn connection. func (bcl *BufConnListenerDialer) Dial(network, addr string) (net.Conn, error) { return bcl.listener.Dial() } + +// DialContext connects to the listening end of the bufconn (satisfies +// consul-template's TransportDialer interface). This is essentially the client +// side of the bufconn connection. +func (bcl *BufConnListenerDialer) DialContext(_ context.Context, network, addr string) (net.Conn, error) { + return bcl.Dial(network, addr) +} From faed61b471044b214117453e05121beff4abe1fb Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Wed, 13 Oct 2021 13:05:54 -0700 Subject: [PATCH 07/13] use the actual bufconn DialContext() --- internalshared/listenerutil/bufconn.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internalshared/listenerutil/bufconn.go b/internalshared/listenerutil/bufconn.go index 1c87474bbd793..e93a33151132e 100644 --- a/internalshared/listenerutil/bufconn.go +++ b/internalshared/listenerutil/bufconn.go @@ -31,6 +31,6 @@ func (bcl *BufConnListenerDialer) Dial(network, addr string) (net.Conn, error) { // DialContext connects to the listening end of the bufconn (satisfies // consul-template's TransportDialer interface). This is essentially the client // side of the bufconn connection. -func (bcl *BufConnListenerDialer) DialContext(_ context.Context, network, addr string) (net.Conn, error) { - return bcl.Dial(network, addr) +func (bcl *BufConnListenerDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + return bcl.listener.DialContext(ctx) } From 6c2d54388452c5d36777982f1e5a6f0cea9606d9 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Wed, 13 Oct 2021 15:35:09 -0700 Subject: [PATCH 08/13] update consul-template dep --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 405817002db64..f21ee313747e4 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ replace github.com/hashicorp/vault/sdk => ./sdk replace go.etcd.io/etcd/client/pkg/v3 v3.5.0 => go.etcd.io/etcd/client/pkg/v3 v3.0.0-20210928084031-3df272774672 -replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211013180249-9860065fbe7f +replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211013221426-03d3cade0c6b require ( cloud.google.com/go v0.56.0 diff --git a/go.sum b/go.sum index d04086d2ac0ad..276acfe875ead 100644 --- a/go.sum +++ b/go.sum @@ -1186,8 +1186,8 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tvoran/consul-template v0.27.2-0.20211013180249-9860065fbe7f h1:wsbCGJyOn+1kg9TH2qOqIqPez8utzBnE5TxfSDEbJnA= -github.com/tvoran/consul-template v0.27.2-0.20211013180249-9860065fbe7f/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= +github.com/tvoran/consul-template v0.27.2-0.20211013221426-03d3cade0c6b h1:G9OjqHQLalcEWw9n+GzGgZlCmaPbeizxd7Ch11qMGnw= +github.com/tvoran/consul-template v0.27.2-0.20211013221426-03d3cade0c6b/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= From 5f98b620a2221612c0c89fb2f0d8004b54bfaf13 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 15 Oct 2021 10:59:17 -0700 Subject: [PATCH 09/13] Update consul-template dep Remove the pointer to my fork --- go.mod | 4 +--- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index f21ee313747e4..1f4b8adb0b687 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,6 @@ replace github.com/hashicorp/vault/sdk => ./sdk replace go.etcd.io/etcd/client/pkg/v3 v3.5.0 => go.etcd.io/etcd/client/pkg/v3 v3.0.0-20210928084031-3df272774672 -replace github.com/hashicorp/consul-template => github.com/tvoran/consul-template v0.27.2-0.20211013221426-03d3cade0c6b - require ( cloud.google.com/go v0.56.0 cloud.google.com/go/spanner v1.5.1 @@ -61,7 +59,7 @@ require ( github.com/google/go-github v17.0.0+incompatible github.com/google/go-metrics-stackdriver v0.2.0 github.com/gorilla/mux v1.7.3 // indirect - github.com/hashicorp/consul-template v0.27.1 + github.com/hashicorp/consul-template v0.27.2-0.20211014231529-4ff55381f1c4 github.com/hashicorp/consul/api v1.11.0 github.com/hashicorp/errwrap v1.1.0 github.com/hashicorp/go-cleanhttp v0.5.2 diff --git a/go.sum b/go.sum index 276acfe875ead..6861f57e55897 100644 --- a/go.sum +++ b/go.sum @@ -566,6 +566,8 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/cap v0.1.0 h1:uBDfu9NDvmotza/mJW6vtQId+VYid9ztlTnDCW6YUWU= github.com/hashicorp/cap v0.1.0/go.mod h1:VfBvK2ULRyqsuqAnjgZl7HJ7/CGMC7ro4H5eXiZuun8= +github.com/hashicorp/consul-template v0.27.2-0.20211014231529-4ff55381f1c4 h1:Heoq6IaSKwqOzAJMDg33LRu0GmNxVswQkIcREBFQD2E= +github.com/hashicorp/consul-template v0.27.2-0.20211014231529-4ff55381f1c4/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= github.com/hashicorp/consul/api v1.11.0 h1:Hw/G8TtRvOElqxVIhBzXciiSTbapq8hZ2XKZsXk5ZCE= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= @@ -1186,8 +1188,6 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tvoran/consul-template v0.27.2-0.20211013221426-03d3cade0c6b h1:G9OjqHQLalcEWw9n+GzGgZlCmaPbeizxd7Ch11qMGnw= -github.com/tvoran/consul-template v0.27.2-0.20211013221426-03d3cade0c6b/go.mod h1:cAi5bOqno7Ao5sFHu7O80wMOPnqcF5ADrTApWU4Lqx4= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= From 4b9e72aba9e84285687e8327db7a2b31ed91a670 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 15 Oct 2021 12:07:31 -0700 Subject: [PATCH 10/13] review feedback Use a "bufconn" const, remove unused parameters. --- command/agent.go | 4 ++-- command/agent/template/template.go | 5 +++-- internalshared/listenerutil/bufconn.go | 6 ++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/command/agent.go b/command/agent.go index b8c2f6e7e8f2e..c21d30ef37089 100644 --- a/command/agent.go +++ b/command/agent.go @@ -673,13 +673,13 @@ func (c *AgentCommand) Run(args []string) int { // If there are templates, add an in-process listener if len(config.Templates) > 0 { - config.Listeners = append(config.Listeners, &configutil.Listener{Type: "bufconn"}) + config.Listeners = append(config.Listeners, &configutil.Listener{Type: listenerutil.BufConnType}) } for i, lnConfig := range config.Listeners { var ln net.Listener var tlsConf *tls.Config - if lnConfig.Type == "bufconn" { + if lnConfig.Type == listenerutil.BufConnType { inProcListener := bufconn.Listen(1024 * 1024) config.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(inProcListener) ln = inProcListener diff --git a/command/agent/template/template.go b/command/agent/template/template.go index a57ffd482b451..3ad546787c811 100644 --- a/command/agent/template/template.go +++ b/command/agent/template/template.go @@ -288,8 +288,9 @@ func newRunnerConfig(sc *ServerConfig, templates ctconfig.TemplateConfigs) (*ctc } conf.Vault.Transport.CustomDialer = sc.AgentConfig.Cache.InProcDialer // The in-process dialer ignores the address passed in, but we're still - // setting it here to satisfy the http client - conf.Vault.Address = pointerutil.StringPtr("http://localhost") + // setting it here to override the setting at the top of this function, + // and to prevent the vault/http client from defaulting to https. + conf.Vault.Address = pointerutil.StringPtr("http://127.0.0.1:8200") } else if strings.HasPrefix(sc.AgentConfig.Vault.Address, "https") || sc.AgentConfig.Vault.CACert != "" { skipVerify := sc.AgentConfig.Vault.TLSSkipVerify diff --git a/internalshared/listenerutil/bufconn.go b/internalshared/listenerutil/bufconn.go index e93a33151132e..232b092c91144 100644 --- a/internalshared/listenerutil/bufconn.go +++ b/internalshared/listenerutil/bufconn.go @@ -7,6 +7,8 @@ import ( "google.golang.org/grpc/test/bufconn" ) +const BufConnType = "bufconn" + // BufConnListenerDialer implements consul-template's TransportDialer using a // bufconn listener, to provide a way to Dial the in-memory listener type BufConnListenerDialer struct { @@ -24,13 +26,13 @@ func NewBufConnListenerDialer(bcl *bufconn.Listener) *BufConnListenerDialer { // Dial connects to the listening end of the bufconn (satisfies // consul-template's TransportDialer interface). This is essentially the client // side of the bufconn connection. -func (bcl *BufConnListenerDialer) Dial(network, addr string) (net.Conn, error) { +func (bcl *BufConnListenerDialer) Dial(_, _ string) (net.Conn, error) { return bcl.listener.Dial() } // DialContext connects to the listening end of the bufconn (satisfies // consul-template's TransportDialer interface). This is essentially the client // side of the bufconn connection. -func (bcl *BufConnListenerDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { +func (bcl *BufConnListenerDialer) DialContext(ctx context.Context, _, _ string) (net.Conn, error) { return bcl.listener.DialContext(ctx) } From 497cc19cc7f5fd46cdc7efe5d2cdd532d7a665e7 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 15 Oct 2021 14:15:37 -0700 Subject: [PATCH 11/13] rename to BufConnWrapper and fix tests --- command/agent.go | 2 +- command/agent/template/template_test.go | 8 ++++---- internalshared/listenerutil/bufconn.go | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/command/agent.go b/command/agent.go index c21d30ef37089..2870227a30d56 100644 --- a/command/agent.go +++ b/command/agent.go @@ -681,7 +681,7 @@ func (c *AgentCommand) Run(args []string) int { if lnConfig.Type == listenerutil.BufConnType { inProcListener := bufconn.Listen(1024 * 1024) - config.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(inProcListener) + config.Cache.InProcDialer = listenerutil.NewBufConnWrapper(inProcListener) ln = inProcListener } else { ln, tlsConf, err = cache.StartListener(lnConfig) diff --git a/command/agent/template/template_test.go b/command/agent/template/template_test.go index 9f304325ba2e7..9f0464730e11e 100644 --- a/command/agent/template/template_test.go +++ b/command/agent/template/template_test.go @@ -147,7 +147,7 @@ func TestCacheConfig(t *testing.T) { if tc.setDialer && tc.cacheEnabled { bListener := bufconn.Listen(1024 * 1024) defer bListener.Close() - agentConfig.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(bListener) + agentConfig.Cache.InProcDialer = listenerutil.NewBufConnWrapper(bListener) } serverConfig := ServerConfig{AgentConfig: agentConfig} @@ -162,7 +162,7 @@ func TestCacheConfig(t *testing.T) { assert.Equal(t, tc.expectCustomDialer, ctConfig.Vault.Transport.CustomDialer != nil) if tc.expectCustomDialer { - assert.Equal(t, "http://localhost", *ctConfig.Vault.Address) + assert.Equal(t, "http://127.0.0.1:8200", *ctConfig.Vault.Address) } else { assert.Equal(t, "http://127.0.0.1:1111", *ctConfig.Vault.Address) } @@ -176,7 +176,7 @@ func TestCacheConfigNoListener(t *testing.T) { agentConfig := newAgentConfig(listeners, true, true) bListener := bufconn.Listen(1024 * 1024) defer bListener.Close() - agentConfig.Cache.InProcDialer = listenerutil.NewBufConnListenerDialer(bListener) + agentConfig.Cache.InProcDialer = listenerutil.NewBufConnWrapper(bListener) serverConfig := ServerConfig{AgentConfig: agentConfig} ctConfig, err := newRunnerConfig(&serverConfig, ctconfig.TemplateConfigs{}) @@ -184,7 +184,7 @@ func TestCacheConfigNoListener(t *testing.T) { t.Fatalf("unexpected error: %s", err) } - assert.Equal(t, "http://localhost", *ctConfig.Vault.Address) + assert.Equal(t, "http://127.0.0.1:8200", *ctConfig.Vault.Address) assert.NotNil(t, ctConfig.Vault.Transport.CustomDialer) } diff --git a/internalshared/listenerutil/bufconn.go b/internalshared/listenerutil/bufconn.go index 232b092c91144..d3d9d653c576d 100644 --- a/internalshared/listenerutil/bufconn.go +++ b/internalshared/listenerutil/bufconn.go @@ -9,16 +9,16 @@ import ( const BufConnType = "bufconn" -// BufConnListenerDialer implements consul-template's TransportDialer using a +// BufConnWrapper implements consul-template's TransportDialer using a // bufconn listener, to provide a way to Dial the in-memory listener -type BufConnListenerDialer struct { +type BufConnWrapper struct { listener *bufconn.Listener } -// NewBufConnListenerDialer returns a new BufConnListenerDialer using an +// NewBufConnWrapper returns a new BufConnWrapper using an // existing bufconn.Listener -func NewBufConnListenerDialer(bcl *bufconn.Listener) *BufConnListenerDialer { - return &BufConnListenerDialer{ +func NewBufConnWrapper(bcl *bufconn.Listener) *BufConnWrapper { + return &BufConnWrapper{ listener: bcl, } } @@ -26,13 +26,13 @@ func NewBufConnListenerDialer(bcl *bufconn.Listener) *BufConnListenerDialer { // Dial connects to the listening end of the bufconn (satisfies // consul-template's TransportDialer interface). This is essentially the client // side of the bufconn connection. -func (bcl *BufConnListenerDialer) Dial(_, _ string) (net.Conn, error) { +func (bcl *BufConnWrapper) Dial(_, _ string) (net.Conn, error) { return bcl.listener.Dial() } // DialContext connects to the listening end of the bufconn (satisfies // consul-template's TransportDialer interface). This is essentially the client // side of the bufconn connection. -func (bcl *BufConnListenerDialer) DialContext(ctx context.Context, _, _ string) (net.Conn, error) { +func (bcl *BufConnWrapper) DialContext(ctx context.Context, _, _ string) (net.Conn, error) { return bcl.listener.DialContext(ctx) } From f1d3b5a352f58193218db8009f342773ef199cac Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 15 Oct 2021 16:46:58 -0700 Subject: [PATCH 12/13] update changelog --- changelog/12762.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/12762.txt b/changelog/12762.txt index ad1ca5c5230df..6c90c4817f13a 100644 --- a/changelog/12762.txt +++ b/changelog/12762.txt @@ -1,3 +1,3 @@ ```release-note:improvement -agent/cache: Use an in-process listener between consul-template and vault-agent when caching and templates are in use +agent/cache: Use an in-process listener between consul-template and vault-agent when caching is enabled and either templates or a listener is defined ``` From 185efd6852e6423d9612aff3d465f16c68049f93 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 15 Oct 2021 16:51:29 -0700 Subject: [PATCH 13/13] Update command/agent/config/config.go Co-authored-by: Ben Ash <32777270+benashz@users.noreply.github.com> --- command/agent/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/agent/config/config.go b/command/agent/config/config.go index 8ae755347a49b..7a105573da4f8 100644 --- a/command/agent/config/config.go +++ b/command/agent/config/config.go @@ -217,7 +217,7 @@ func LoadConfig(path string) (*Config, error) { if result.Cache != nil { if len(result.Listeners) < 1 && len(result.Templates) < 1 { - return nil, fmt.Errorf("the cache is enabled but not usable because no listeners or templates are defined") + return nil, fmt.Errorf("enabling the cache requires at least 1 template or 1 listener to be defined") } if result.Cache.UseAutoAuthToken {