mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	Create configutil and move some common config and setup functions there (#8362)
This commit is contained in:
		| @@ -12,7 +12,7 @@ require ( | |||||||
| 	github.com/hashicorp/go-retryablehttp v0.6.2 | 	github.com/hashicorp/go-retryablehttp v0.6.2 | ||||||
| 	github.com/hashicorp/go-rootcerts v1.0.1 | 	github.com/hashicorp/go-rootcerts v1.0.1 | ||||||
| 	github.com/hashicorp/hcl v1.0.0 | 	github.com/hashicorp/hcl v1.0.0 | ||||||
| 	github.com/hashicorp/vault/sdk v0.1.14-0.20200215195600-2ca765f0a500 | 	github.com/hashicorp/vault/sdk v0.1.14-0.20200310200459-8f075a2701b4 | ||||||
| 	github.com/mitchellh/mapstructure v1.1.2 | 	github.com/mitchellh/mapstructure v1.1.2 | ||||||
| 	golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 | 	golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 | ||||||
| 	golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 | 	golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 | ||||||
|   | |||||||
| @@ -3,12 +3,12 @@ package okta | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/hashicorp/go-cleanhttp" |  | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-cleanhttp" | ||||||
| 	oktaold "github.com/chrismalek/oktasdk-go/okta" | 	oktaold "github.com/chrismalek/oktasdk-go/okta" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/tokenutil" | 	"github.com/hashicorp/vault/sdk/helper/tokenutil" | ||||||
|   | |||||||
| @@ -2,12 +2,13 @@ package database | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"strings" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	"github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| 	"strings" |  | ||||||
| 	"testing" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|   | |||||||
| @@ -482,15 +482,8 @@ func (c *AgentCommand) Run(args []string) int { | |||||||
| 			// Parse 'require_request_header' listener config option, and wrap | 			// Parse 'require_request_header' listener config option, and wrap | ||||||
| 			// the request handler if necessary | 			// the request handler if necessary | ||||||
| 			muxHandler := cacheHandler | 			muxHandler := cacheHandler | ||||||
| 			if v, ok := lnConfig.Config[agentConfig.RequireRequestHeader]; ok { | 			if lnConfig.RequireRequestHeader { | ||||||
| 				switch v { |  | ||||||
| 				case true: |  | ||||||
| 				muxHandler = verifyRequestHeader(muxHandler) | 				muxHandler = verifyRequestHeader(muxHandler) | ||||||
| 				case false /* noop */ : |  | ||||||
| 				default: |  | ||||||
| 					c.UI.Error(fmt.Sprintf("Invalid value for 'require_request_header': %v", v)) |  | ||||||
| 					return 1 |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Create a muxer and add paths relevant for the lease cache layer | 			// Create a muxer and add paths relevant for the lease cache layer | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								command/agent/cache/listener.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								command/agent/cache/listener.go
									
									
									
									
										vendored
									
									
								
							| @@ -7,16 +7,13 @@ import ( | |||||||
|  |  | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/command/agent/config" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" | 	"github.com/hashicorp/vault/command/server" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/listenerutil" | 	"github.com/hashicorp/vault/internalshared/listenerutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func StartListener(lnConfig *config.Listener) (net.Listener, *tls.Config, error) { | func StartListener(lnConfig *configutil.Listener) (net.Listener, *tls.Config, error) { | ||||||
| 	addr, ok := lnConfig.Config["address"].(string) | 	addr := lnConfig.Address | ||||||
| 	if !ok { |  | ||||||
| 		return nil, nil, fmt.Errorf("invalid address") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var ln net.Listener | 	var ln net.Listener | ||||||
| 	var err error | 	var err error | ||||||
| @@ -41,13 +38,13 @@ func StartListener(lnConfig *config.Listener) (net.Listener, *tls.Config, error) | |||||||
|  |  | ||||||
| 	case "unix": | 	case "unix": | ||||||
| 		var uConfig *listenerutil.UnixSocketsConfig | 		var uConfig *listenerutil.UnixSocketsConfig | ||||||
| 		if lnConfig.Config["socket_mode"] != nil && | 		if lnConfig.SocketMode != "" && | ||||||
| 			lnConfig.Config["socket_user"] != nil && | 			lnConfig.SocketUser != "" && | ||||||
| 			lnConfig.Config["socket_group"] != nil { | 			lnConfig.SocketGroup != "" { | ||||||
| 			uConfig = &listenerutil.UnixSocketsConfig{ | 			uConfig = &listenerutil.UnixSocketsConfig{ | ||||||
| 				Mode:  lnConfig.Config["socket_mode"].(string), | 				Mode:  lnConfig.SocketMode, | ||||||
| 				User:  lnConfig.Config["socket_user"].(string), | 				User:  lnConfig.SocketUser, | ||||||
| 				Group: lnConfig.Config["socket_group"].(string), | 				Group: lnConfig.SocketGroup, | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		ln, err = listenerutil.UnixSocketListener(addr, uConfig) | 		ln, err = listenerutil.UnixSocketListener(addr, uConfig) | ||||||
| @@ -60,10 +57,13 @@ func StartListener(lnConfig *config.Listener) (net.Listener, *tls.Config, error) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	props := map[string]string{"addr": ln.Addr().String()} | 	props := map[string]string{"addr": ln.Addr().String()} | ||||||
| 	ln, props, _, tlsConf, err := listenerutil.WrapTLS(ln, props, lnConfig.Config, nil) | 	tlsConf, _, err := listenerutil.TLSConfig(lnConfig, props, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, nil, err | 		return nil, nil, err | ||||||
| 	} | 	} | ||||||
|  | 	if tlsConf != nil { | ||||||
|  | 		ln = tls.NewListener(ln, tlsConf) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return ln, tlsConf, nil | 	return ln, tlsConf, nil | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								command/agent/cache/testing.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								command/agent/cache/testing.go
									
									
									
									
										vendored
									
									
								
							| @@ -72,11 +72,11 @@ type mockTokenVerifierProxier struct { | |||||||
| func (p *mockTokenVerifierProxier) Send(ctx context.Context, req *SendRequest) (*SendResponse, error) { | func (p *mockTokenVerifierProxier) Send(ctx context.Context, req *SendRequest) (*SendResponse, error) { | ||||||
| 	p.currentToken = req.Token | 	p.currentToken = req.Token | ||||||
| 	resp := newTestSendResponse(http.StatusOK, | 	resp := newTestSendResponse(http.StatusOK, | ||||||
| 		`{"data": {"id": "` + p.currentToken + `"}}`) | 		`{"data": {"id": "`+p.currentToken+`"}}`) | ||||||
|  |  | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *mockTokenVerifierProxier) GetCurrentRequestToken() (string) { | func (p *mockTokenVerifierProxier) GetCurrentRequestToken() string { | ||||||
| 	return p.currentToken | 	return p.currentToken | ||||||
| } | } | ||||||
| @@ -14,16 +14,17 @@ import ( | |||||||
| 	"github.com/hashicorp/hcl" | 	"github.com/hashicorp/hcl" | ||||||
| 	"github.com/hashicorp/hcl/hcl/ast" | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/parseutil" | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
| 	"github.com/mitchellh/mapstructure" | 	"github.com/mitchellh/mapstructure" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Config is the configuration for the vault server. | // Config is the configuration for the vault server. | ||||||
| type Config struct { | type Config struct { | ||||||
|  | 	*configutil.SharedConfig `hcl:"-"` | ||||||
|  |  | ||||||
| 	AutoAuth      *AutoAuth                  `hcl:"auto_auth"` | 	AutoAuth      *AutoAuth                  `hcl:"auto_auth"` | ||||||
| 	ExitAfterAuth bool                       `hcl:"exit_after_auth"` | 	ExitAfterAuth bool                       `hcl:"exit_after_auth"` | ||||||
| 	PidFile       string                     `hcl:"pid_file"` |  | ||||||
| 	Listeners     []*Listener                `hcl:"listeners"` |  | ||||||
| 	Cache         *Cache                     `hcl:"cache"` | 	Cache         *Cache                     `hcl:"cache"` | ||||||
| 	Vault         *Vault                     `hcl:"vault"` | 	Vault         *Vault                     `hcl:"vault"` | ||||||
| 	Templates     []*ctconfig.TemplateConfig `hcl:"templates"` | 	Templates     []*ctconfig.TemplateConfig `hcl:"templates"` | ||||||
| @@ -48,15 +49,6 @@ type Cache struct { | |||||||
| 	ForceAutoAuthToken  bool        `hcl:"-"` | 	ForceAutoAuthToken  bool        `hcl:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // Listener contains configuration for any Vault Agent listeners |  | ||||||
| type Listener struct { |  | ||||||
| 	Type   string |  | ||||||
| 	Config map[string]interface{} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // RequireRequestHeader is a listener configuration option |  | ||||||
| const RequireRequestHeader = "require_request_header" |  | ||||||
|  |  | ||||||
| // AutoAuth is the configured authentication method and sinks | // AutoAuth is the configured authentication method and sinks | ||||||
| type AutoAuth struct { | type AutoAuth struct { | ||||||
| 	Method *Method `hcl:"-"` | 	Method *Method `hcl:"-"` | ||||||
| @@ -89,6 +81,12 @@ type Sink struct { | |||||||
| 	Config     map[string]interface{} | 	Config     map[string]interface{} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func NewConfig() *Config { | ||||||
|  | 	return &Config{ | ||||||
|  | 		SharedConfig: new(configutil.SharedConfig), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // LoadConfig loads the configuration at the given path, regardless if | // LoadConfig loads the configuration at the given path, regardless if | ||||||
| // its a file or directory. | // its a file or directory. | ||||||
| func LoadConfig(path string) (*Config, error) { | func LoadConfig(path string) (*Config, error) { | ||||||
| @@ -114,29 +112,31 @@ func LoadConfig(path string) (*Config, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Start building the result | 	// Start building the result | ||||||
| 	var result Config | 	result := NewConfig() | ||||||
| 	if err := hcl.DecodeObject(&result, obj); err != nil { | 	if err := hcl.DecodeObject(result, obj); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	sharedConfig, err := configutil.ParseConfig(string(d)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	result.SharedConfig = sharedConfig | ||||||
|  |  | ||||||
| 	list, ok := obj.Node.(*ast.ObjectList) | 	list, ok := obj.Node.(*ast.ObjectList) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, fmt.Errorf("error parsing: file doesn't contain a root object") | 		return nil, fmt.Errorf("error parsing: file doesn't contain a root object") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := parseAutoAuth(&result, list); err != nil { | 	if err := parseAutoAuth(result, list); err != nil { | ||||||
| 		return nil, errwrap.Wrapf("error parsing 'auto_auth': {{err}}", err) | 		return nil, errwrap.Wrapf("error parsing 'auto_auth': {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := parseListeners(&result, list); err != nil { | 	if err := parseCache(result, list); err != nil { | ||||||
| 		return nil, errwrap.Wrapf("error parsing 'listeners': {{err}}", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := parseCache(&result, list); err != nil { |  | ||||||
| 		return nil, errwrap.Wrapf("error parsing 'cache':{{err}}", err) | 		return nil, errwrap.Wrapf("error parsing 'cache':{{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := parseTemplates(&result, list); err != nil { | 	if err := parseTemplates(result, list); err != nil { | ||||||
| 		return nil, errwrap.Wrapf("error parsing 'template': {{err}}", err) | 		return nil, errwrap.Wrapf("error parsing 'template': {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -161,12 +161,12 @@ func LoadConfig(path string) (*Config, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = parseVault(&result, list) | 	err = parseVault(result, list) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, errwrap.Wrapf("error parsing 'vault':{{err}}", err) | 		return nil, errwrap.Wrapf("error parsing 'vault':{{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return &result, nil | 	return result, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func parseVault(result *Config, list *ast.ObjectList) error { | func parseVault(result *Config, list *ast.ObjectList) error { | ||||||
| @@ -245,47 +245,6 @@ func parseCache(result *Config, list *ast.ObjectList) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func parseListeners(result *Config, list *ast.ObjectList) error { |  | ||||||
| 	name := "listener" |  | ||||||
|  |  | ||||||
| 	listenerList := list.Filter(name) |  | ||||||
|  |  | ||||||
| 	var listeners []*Listener |  | ||||||
| 	for _, item := range listenerList.Items { |  | ||||||
| 		var lnConfig map[string]interface{} |  | ||||||
| 		err := hcl.DecodeObject(&lnConfig, item.Val) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var lnType string |  | ||||||
| 		switch { |  | ||||||
| 		case lnConfig["type"] != nil: |  | ||||||
| 			lnType = lnConfig["type"].(string) |  | ||||||
| 			delete(lnConfig, "type") |  | ||||||
| 		case len(item.Keys) == 1: |  | ||||||
| 			lnType = strings.ToLower(item.Keys[0].Token.Value().(string)) |  | ||||||
| 		default: |  | ||||||
| 			return errors.New("listener type must be specified") |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		switch lnType { |  | ||||||
| 		case "unix", "tcp": |  | ||||||
| 		default: |  | ||||||
| 			return fmt.Errorf("invalid listener type %q", lnType) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		listeners = append(listeners, &Listener{ |  | ||||||
| 			Type:   lnType, |  | ||||||
| 			Config: lnConfig, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.Listeners = listeners |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func parseAutoAuth(result *Config, list *ast.ObjectList) error { | func parseAutoAuth(result *Config, list *ast.ObjectList) error { | ||||||
| 	name := "auto_auth" | 	name := "auto_auth" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/go-test/deep" | 	"github.com/go-test/deep" | ||||||
| 	ctconfig "github.com/hashicorp/consul-template/config" | 	ctconfig "github.com/hashicorp/consul-template/config" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/pointerutil" | 	"github.com/hashicorp/vault/sdk/helper/pointerutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -17,6 +18,30 @@ func TestLoadConfigFile_AgentCache(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	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:8400", | ||||||
|  | 					TLSKeyFile:  "/path/to/cakey.pem", | ||||||
|  | 					TLSCertFile: "/path/to/cacert.pem", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -26,7 +51,7 @@ func TestLoadConfigFile_AgentCache(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			Sinks: []*Sink{ | 			Sinks: []*Sink{ | ||||||
| 				&Sink{ | 				{ | ||||||
| 					Type:   "file", | 					Type:   "file", | ||||||
| 					DHType: "curve25519", | 					DHType: "curve25519", | ||||||
| 					DHPath: "/tmp/file-foo-dhpath", | 					DHPath: "/tmp/file-foo-dhpath", | ||||||
| @@ -42,33 +67,6 @@ func TestLoadConfigFile_AgentCache(t *testing.T) { | |||||||
| 			UseAutoAuthTokenRaw: true, | 			UseAutoAuthTokenRaw: true, | ||||||
| 			ForceAutoAuthToken:  false, | 			ForceAutoAuthToken:  false, | ||||||
| 		}, | 		}, | ||||||
| 		Listeners: []*Listener{ |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "unix", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":      "/path/to/socket", |  | ||||||
| 					"tls_disable":  true, |  | ||||||
| 					"socket_mode":  "configmode", |  | ||||||
| 					"socket_user":  "configuser", |  | ||||||
| 					"socket_group": "configgroup", |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":     "127.0.0.1:8300", |  | ||||||
| 					"tls_disable": true, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":       "127.0.0.1:8400", |  | ||||||
| 					"tls_key_file":  "/path/to/cakey.pem", |  | ||||||
| 					"tls_cert_file": "/path/to/cacert.pem", |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		Vault: &Vault{ | 		Vault: &Vault{ | ||||||
| 			Address:          "http://127.0.0.1:1111", | 			Address:          "http://127.0.0.1:1111", | ||||||
| 			CACert:           "config_ca_cert", | 			CACert:           "config_ca_cert", | ||||||
| @@ -78,9 +76,11 @@ func TestLoadConfigFile_AgentCache(t *testing.T) { | |||||||
| 			ClientCert:       "config_client_cert", | 			ClientCert:       "config_client_cert", | ||||||
| 			ClientKey:        "config_client_key", | 			ClientKey:        "config_client_key", | ||||||
| 		}, | 		}, | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
|  | 	config.Listeners[1].RawConfig = nil | ||||||
|  | 	config.Listeners[2].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -91,6 +91,9 @@ func TestLoadConfigFile_AgentCache(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	expected.Vault.TLSSkipVerifyRaw = interface{}(true) | 	expected.Vault.TLSSkipVerifyRaw = interface{}(true) | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
|  | 	config.Listeners[1].RawConfig = nil | ||||||
|  | 	config.Listeners[2].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -112,6 +115,9 @@ func TestLoadConfigFile(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -122,7 +128,7 @@ func TestLoadConfigFile(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			Sinks: []*Sink{ | 			Sinks: []*Sink{ | ||||||
| 				&Sink{ | 				{ | ||||||
| 					Type:   "file", | 					Type:   "file", | ||||||
| 					DHType: "curve25519", | 					DHType: "curve25519", | ||||||
| 					DHPath: "/tmp/file-foo-dhpath", | 					DHPath: "/tmp/file-foo-dhpath", | ||||||
| @@ -131,7 +137,7 @@ func TestLoadConfigFile(t *testing.T) { | |||||||
| 						"path": "/tmp/file-foo", | 						"path": "/tmp/file-foo", | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 				&Sink{ | 				{ | ||||||
| 					Type:    "file", | 					Type:    "file", | ||||||
| 					WrapTTL: 5 * time.Minute, | 					WrapTTL: 5 * time.Minute, | ||||||
| 					DHType:  "curve25519", | 					DHType:  "curve25519", | ||||||
| @@ -143,7 +149,6 @@ func TestLoadConfigFile(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| @@ -167,6 +172,9 @@ func TestLoadConfigFile_Method_Wrapping(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -177,7 +185,7 @@ func TestLoadConfigFile_Method_Wrapping(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			Sinks: []*Sink{ | 			Sinks: []*Sink{ | ||||||
| 				&Sink{ | 				{ | ||||||
| 					Type: "file", | 					Type: "file", | ||||||
| 					Config: map[string]interface{}{ | 					Config: map[string]interface{}{ | ||||||
| 						"path": "/tmp/file-foo", | 						"path": "/tmp/file-foo", | ||||||
| @@ -185,7 +193,6 @@ func TestLoadConfigFile_Method_Wrapping(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| @@ -201,18 +208,19 @@ func TestLoadConfigFile_AgentCache_NoAutoAuth(t *testing.T) { | |||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Cache: &Cache{}, | 		Cache: &Cache{}, | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":     "127.0.0.1:8300", |  | ||||||
| 					"tls_disable": true, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 			PidFile: "./pidfile", | 			PidFile: "./pidfile", | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
|  | 					Type:       "tcp", | ||||||
|  | 					Address:    "127.0.0.1:8300", | ||||||
|  | 					TLSDisable: true, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -267,6 +275,16 @@ func TestLoadConfigFile_AgentCache_AutoAuth_NoSink(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
|  | 					Type:       "tcp", | ||||||
|  | 					Address:    "127.0.0.1:8300", | ||||||
|  | 					TLSDisable: true, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -281,18 +299,9 @@ func TestLoadConfigFile_AgentCache_AutoAuth_NoSink(t *testing.T) { | |||||||
| 			UseAutoAuthTokenRaw: true, | 			UseAutoAuthTokenRaw: true, | ||||||
| 			ForceAutoAuthToken:  false, | 			ForceAutoAuthToken:  false, | ||||||
| 		}, | 		}, | ||||||
| 		Listeners: []*Listener{ |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":     "127.0.0.1:8300", |  | ||||||
| 					"tls_disable": true, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -305,6 +314,16 @@ func TestLoadConfigFile_AgentCache_AutoAuth_Force(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
|  | 					Type:       "tcp", | ||||||
|  | 					Address:    "127.0.0.1:8300", | ||||||
|  | 					TLSDisable: true, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -319,18 +338,9 @@ func TestLoadConfigFile_AgentCache_AutoAuth_Force(t *testing.T) { | |||||||
| 			UseAutoAuthTokenRaw: "force", | 			UseAutoAuthTokenRaw: "force", | ||||||
| 			ForceAutoAuthToken:  true, | 			ForceAutoAuthToken:  true, | ||||||
| 		}, | 		}, | ||||||
| 		Listeners: []*Listener{ |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":     "127.0.0.1:8300", |  | ||||||
| 					"tls_disable": true, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -343,6 +353,16 @@ func TestLoadConfigFile_AgentCache_AutoAuth_True(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
|  | 					Type:       "tcp", | ||||||
|  | 					Address:    "127.0.0.1:8300", | ||||||
|  | 					TLSDisable: true, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -357,18 +377,9 @@ func TestLoadConfigFile_AgentCache_AutoAuth_True(t *testing.T) { | |||||||
| 			UseAutoAuthTokenRaw: "true", | 			UseAutoAuthTokenRaw: "true", | ||||||
| 			ForceAutoAuthToken:  false, | 			ForceAutoAuthToken:  false, | ||||||
| 		}, | 		}, | ||||||
| 		Listeners: []*Listener{ |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":     "127.0.0.1:8300", |  | ||||||
| 					"tls_disable": true, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -381,6 +392,16 @@ func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
|  | 					Type:       "tcp", | ||||||
|  | 					Address:    "127.0.0.1:8300", | ||||||
|  | 					TLSDisable: true, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  | 		}, | ||||||
| 		AutoAuth: &AutoAuth{ | 		AutoAuth: &AutoAuth{ | ||||||
| 			Method: &Method{ | 			Method: &Method{ | ||||||
| 				Type:      "aws", | 				Type:      "aws", | ||||||
| @@ -390,7 +411,7 @@ func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			Sinks: []*Sink{ | 			Sinks: []*Sink{ | ||||||
| 				&Sink{ | 				{ | ||||||
| 					Type:   "file", | 					Type:   "file", | ||||||
| 					DHType: "curve25519", | 					DHType: "curve25519", | ||||||
| 					DHPath: "/tmp/file-foo-dhpath", | 					DHPath: "/tmp/file-foo-dhpath", | ||||||
| @@ -406,18 +427,9 @@ func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) { | |||||||
| 			UseAutoAuthTokenRaw: "false", | 			UseAutoAuthTokenRaw: "false", | ||||||
| 			ForceAutoAuthToken:  false, | 			ForceAutoAuthToken:  false, | ||||||
| 		}, | 		}, | ||||||
| 		Listeners: []*Listener{ |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address":     "127.0.0.1:8300", |  | ||||||
| 					"tls_disable": true, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if diff := deep.Equal(config, expected); diff != nil { | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
| 		t.Fatal(diff) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| @@ -494,6 +506,9 @@ func TestLoadConfigFile_Template(t *testing.T) { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			expected := &Config{ | 			expected := &Config{ | ||||||
|  | 				SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 					PidFile: "./pidfile", | ||||||
|  | 				}, | ||||||
| 				AutoAuth: &AutoAuth{ | 				AutoAuth: &AutoAuth{ | ||||||
| 					Method: &Method{ | 					Method: &Method{ | ||||||
| 						Type:      "aws", | 						Type:      "aws", | ||||||
| @@ -504,7 +519,7 @@ func TestLoadConfigFile_Template(t *testing.T) { | |||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
| 					Sinks: []*Sink{ | 					Sinks: []*Sink{ | ||||||
| 						&Sink{ | 						{ | ||||||
| 							Type:   "file", | 							Type:   "file", | ||||||
| 							DHType: "curve25519", | 							DHType: "curve25519", | ||||||
| 							DHPath: "/tmp/file-foo-dhpath", | 							DHPath: "/tmp/file-foo-dhpath", | ||||||
| @@ -516,7 +531,6 @@ func TestLoadConfigFile_Template(t *testing.T) { | |||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 				Templates: tc.expectedTemplates, | 				Templates: tc.expectedTemplates, | ||||||
| 				PidFile:   "./pidfile", |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if diff := deep.Equal(config, expected); diff != nil { | 			if diff := deep.Equal(config, expected); diff != nil { | ||||||
|   | |||||||
| @@ -547,7 +547,7 @@ func testSealMigrationTransitToShamir(t *testing.T, setup teststorage.ClusterSet | |||||||
| 	// Create a Shamir seal. | 	// Create a Shamir seal. | ||||||
| 	logger := cluster.Logger.Named("shamir") | 	logger := cluster.Logger.Named("shamir") | ||||||
| 	shamirSeal := vault.NewDefaultSeal(&vaultseal.Access{ | 	shamirSeal := vault.NewDefaultSeal(&vaultseal.Access{ | ||||||
| 		Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 		Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 			Logger: logger, | 			Logger: logger, | ||||||
| 		}), | 		}), | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -20,33 +20,25 @@ import ( | |||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	monitoring "cloud.google.com/go/monitoring/apiv3" |  | ||||||
| 	"github.com/armon/go-metrics" |  | ||||||
| 	"github.com/armon/go-metrics/circonus" |  | ||||||
| 	"github.com/armon/go-metrics/datadog" |  | ||||||
| 	"github.com/armon/go-metrics/prometheus" |  | ||||||
| 	stackdriver "github.com/google/go-metrics-stackdriver" |  | ||||||
| 	stackdrivervault "github.com/google/go-metrics-stackdriver/vault" |  | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	"github.com/hashicorp/go-hclog" | 	"github.com/hashicorp/go-hclog" | ||||||
| 	log "github.com/hashicorp/go-hclog" | 	log "github.com/hashicorp/go-hclog" | ||||||
| 	wrapping "github.com/hashicorp/go-kms-wrapping" | 	wrapping "github.com/hashicorp/go-kms-wrapping" | ||||||
| 	aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead" | 	aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead" | ||||||
| 	"github.com/hashicorp/go-multierror" | 	"github.com/hashicorp/go-multierror" | ||||||
| 	"github.com/hashicorp/go-sockaddr" |  | ||||||
| 	"github.com/hashicorp/vault/audit" | 	"github.com/hashicorp/vault/audit" | ||||||
| 	"github.com/hashicorp/vault/command/server" | 	"github.com/hashicorp/vault/command/server" | ||||||
| 	serverseal "github.com/hashicorp/vault/command/server/seal" |  | ||||||
| 	"github.com/hashicorp/vault/helper/builtinplugins" | 	"github.com/hashicorp/vault/helper/builtinplugins" | ||||||
| 	"github.com/hashicorp/vault/helper/metricsutil" | 	"github.com/hashicorp/vault/helper/metricsutil" | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
| 	vaulthttp "github.com/hashicorp/vault/http" | 	vaulthttp "github.com/hashicorp/vault/http" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/gatedwriter" | 	"github.com/hashicorp/vault/internalshared/gatedwriter" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/listenerutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/reloadutil" | 	"github.com/hashicorp/vault/internalshared/reloadutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/logging" | 	"github.com/hashicorp/vault/sdk/helper/logging" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/mlock" | 	"github.com/hashicorp/vault/sdk/helper/mlock" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/parseutil" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/useragent" | 	"github.com/hashicorp/vault/sdk/helper/useragent" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| 	"github.com/hashicorp/vault/sdk/physical" | 	"github.com/hashicorp/vault/sdk/physical" | ||||||
| @@ -59,7 +51,6 @@ import ( | |||||||
| 	"github.com/posener/complete" | 	"github.com/posener/complete" | ||||||
| 	"go.uber.org/atomic" | 	"go.uber.org/atomic" | ||||||
| 	"golang.org/x/net/http/httpproxy" | 	"golang.org/x/net/http/httpproxy" | ||||||
| 	"google.golang.org/api/option" |  | ||||||
| 	"google.golang.org/grpc/grpclog" | 	"google.golang.org/grpc/grpclog" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -130,14 +121,6 @@ type ServerCommand struct { | |||||||
| 	flagExitOnCoreShutdown bool | 	flagExitOnCoreShutdown bool | ||||||
| } | } | ||||||
|  |  | ||||||
| type ServerListener struct { |  | ||||||
| 	net.Listener |  | ||||||
| 	config                       map[string]interface{} |  | ||||||
| 	maxRequestSize               int64 |  | ||||||
| 	maxRequestDuration           time.Duration |  | ||||||
| 	unauthenticatedMetricsAccess bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *ServerCommand) Synopsis() string { | func (c *ServerCommand) Synopsis() string { | ||||||
| 	return "Start a Vault server" | 	return "Start a Vault server" | ||||||
| } | } | ||||||
| @@ -497,9 +480,10 @@ func (c *ServerCommand) runRecoveryMode() int { | |||||||
|  |  | ||||||
| 	var barrierSeal vault.Seal | 	var barrierSeal vault.Seal | ||||||
| 	var sealConfigError error | 	var sealConfigError error | ||||||
|  | 	var wrapper wrapping.Wrapper | ||||||
|  |  | ||||||
| 	if len(config.Seals) == 0 { | 	if len(config.Seals) == 0 { | ||||||
| 		config.Seals = append(config.Seals, &server.Seal{Type: wrapping.Shamir}) | 		config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.Shamir}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(config.Seals) > 1 { | 	if len(config.Seals) > 1 { | ||||||
| @@ -516,13 +500,17 @@ func (c *ServerCommand) runRecoveryMode() int { | |||||||
| 		sealType = configSeal.Type | 		sealType = configSeal.Type | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	infoKeys = append(infoKeys, "Seal Type") | ||||||
|  | 	info["Seal Type"] = sealType | ||||||
|  |  | ||||||
| 	var seal vault.Seal | 	var seal vault.Seal | ||||||
| 	sealLogger := c.logger.Named(sealType) | 	defaultSeal := vault.NewDefaultSeal(&vaultseal.Access{ | ||||||
| 	seal, sealConfigError = serverseal.ConfigureSeal(configSeal, &infoKeys, &info, sealLogger, vault.NewDefaultSeal(&vaultseal.Access{ | 		Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 		Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ |  | ||||||
| 			Logger: c.logger.Named("shamir"), | 			Logger: c.logger.Named("shamir"), | ||||||
| 		}), | 		}), | ||||||
| 	})) | 	}) | ||||||
|  | 	sealLogger := c.logger.ResetNamed(fmt.Sprintf("seal.%s", sealType)) | ||||||
|  | 	wrapper, sealConfigError = configutil.ConfigureWrapper(configSeal, &infoKeys, &info, sealLogger) | ||||||
| 	if sealConfigError != nil { | 	if sealConfigError != nil { | ||||||
| 		if !errwrap.ContainsType(sealConfigError, new(logical.KeyNotFoundError)) { | 		if !errwrap.ContainsType(sealConfigError, new(logical.KeyNotFoundError)) { | ||||||
| 			c.UI.Error(fmt.Sprintf( | 			c.UI.Error(fmt.Sprintf( | ||||||
| @@ -530,12 +518,13 @@ func (c *ServerCommand) runRecoveryMode() int { | |||||||
| 			return 1 | 			return 1 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if seal == nil { | 	if wrapper == nil { | ||||||
| 		c.UI.Error(fmt.Sprintf( | 		seal = defaultSeal | ||||||
| 			"After configuring seal nil returned, seal type was %s", sealType)) | 	} else { | ||||||
| 		return 1 | 		seal = vault.NewAutoSeal(&vaultseal.Access{ | ||||||
|  | 			Wrapper: wrapper, | ||||||
|  | 		}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	barrierSeal = seal | 	barrierSeal = seal | ||||||
|  |  | ||||||
| 	// Ensure that the seal finalizer is called, even if using verify-only | 	// Ensure that the seal finalizer is called, even if using verify-only | ||||||
| @@ -579,17 +568,17 @@ func (c *ServerCommand) runRecoveryMode() int { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Initialize the listeners | 	// Initialize the listeners | ||||||
| 	lns := make([]ServerListener, 0, len(config.Listeners)) | 	lns := make([]listenerutil.Listener, 0, len(config.Listeners)) | ||||||
| 	for _, lnConfig := range config.Listeners { | 	for _, lnConfig := range config.Listeners { | ||||||
| 		ln, _, _, err := server.NewListener(lnConfig.Type, lnConfig.Config, c.gatedWriter, c.UI) | 		ln, _, _, err := server.NewListener(lnConfig, c.gatedWriter, c.UI) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			c.UI.Error(fmt.Sprintf("Error initializing listener of type %s: %s", lnConfig.Type, err)) | 			c.UI.Error(fmt.Sprintf("Error initializing listener of type %s: %s", lnConfig.Type, err)) | ||||||
| 			return 1 | 			return 1 | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		lns = append(lns, ServerListener{ | 		lns = append(lns, listenerutil.Listener{ | ||||||
| 			Listener: ln, | 			Listener: ln, | ||||||
| 			config:   lnConfig.Config, | 			Config:   lnConfig, | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -628,8 +617,7 @@ func (c *ServerCommand) runRecoveryMode() int { | |||||||
| 	for _, ln := range lns { | 	for _, ln := range lns { | ||||||
| 		handler := vaulthttp.Handler(&vault.HandlerProperties{ | 		handler := vaulthttp.Handler(&vault.HandlerProperties{ | ||||||
| 			Core:                  core, | 			Core:                  core, | ||||||
| 			MaxRequestSize:        ln.maxRequestSize, | 			ListenerConfig:        ln.Config, | ||||||
| 			MaxRequestDuration:    ln.maxRequestDuration, |  | ||||||
| 			DisablePrintableCheck: config.DisablePrintableCheck, | 			DisablePrintableCheck: config.DisablePrintableCheck, | ||||||
| 			RecoveryMode:          c.flagRecovery, | 			RecoveryMode:          c.flagRecovery, | ||||||
| 			RecoveryToken:         atomic.NewString(""), | 			RecoveryToken:         atomic.NewString(""), | ||||||
| @@ -805,6 +793,7 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
|  |  | ||||||
| 	// Load the configuration | 	// Load the configuration | ||||||
| 	var config *server.Config | 	var config *server.Config | ||||||
|  | 	var err error | ||||||
| 	if c.flagDev { | 	if c.flagDev { | ||||||
| 		var devStorageType string | 		var devStorageType string | ||||||
| 		switch { | 		switch { | ||||||
| @@ -819,9 +808,13 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 		default: | 		default: | ||||||
| 			devStorageType = "inmem" | 			devStorageType = "inmem" | ||||||
| 		} | 		} | ||||||
| 		config = server.DevConfig(devStorageType) | 		config, err = server.DevConfig(devStorageType) | ||||||
|  | 		if err != nil { | ||||||
|  | 			c.UI.Error(err.Error()) | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
| 		if c.flagDevListenAddr != "" { | 		if c.flagDevListenAddr != "" { | ||||||
| 			config.Listeners[0].Config["address"] = c.flagDevListenAddr | 			config.Listeners[0].Address = c.flagDevListenAddr | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -918,11 +911,19 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 				"in a Docker container, provide the IPC_LOCK cap to the container.")) | 				"in a Docker container, provide the IPC_LOCK cap to the container.")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	metricsHelper, metricSink, err := c.setupTelemetry(config) | 	inmemMetrics, metricSink, prometheusEnabled, err := configutil.SetupTelemetry(&configutil.SetupTelemetryOpts{ | ||||||
|  | 		Config:      config.Telemetry, | ||||||
|  | 		Ui:          c.UI, | ||||||
|  | 		ServiceName: "vault", | ||||||
|  | 		DisplayName: "Vault", | ||||||
|  | 		UserAgent:   useragent.String(), | ||||||
|  | 		ClusterName: config.ClusterName, | ||||||
|  | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.UI.Error(fmt.Sprintf("Error initializing telemetry: %s", err)) | 		c.UI.Error(fmt.Sprintf("Error initializing telemetry: %s", err)) | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
|  | 	metricsHelper := metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled) | ||||||
|  |  | ||||||
| 	// Initialize the backend | 	// Initialize the backend | ||||||
| 	factory, exists := c.PhysicalBackends[config.Storage.Type] | 	factory, exists := c.PhysicalBackends[config.Storage.Type] | ||||||
| @@ -1010,18 +1011,20 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 	var unwrapSeal vault.Seal | 	var unwrapSeal vault.Seal | ||||||
|  |  | ||||||
| 	var sealConfigError error | 	var sealConfigError error | ||||||
|  | 	var wrapper wrapping.Wrapper | ||||||
|  | 	var barrierWrapper wrapping.Wrapper | ||||||
| 	if c.flagDevAutoSeal { | 	if c.flagDevAutoSeal { | ||||||
| 		barrierSeal = vault.NewAutoSeal(vaultseal.NewTestSeal(nil)) | 		barrierSeal = vault.NewAutoSeal(vaultseal.NewTestSeal(nil)) | ||||||
| 	} else { | 	} else { | ||||||
| 		// Handle the case where no seal is provided | 		// Handle the case where no seal is provided | ||||||
| 		switch len(config.Seals) { | 		switch len(config.Seals) { | ||||||
| 		case 0: | 		case 0: | ||||||
| 			config.Seals = append(config.Seals, &server.Seal{Type: wrapping.Shamir}) | 			config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.Shamir}) | ||||||
| 		case 1: | 		case 1: | ||||||
| 			// If there's only one seal and it's disabled assume they want to | 			// If there's only one seal and it's disabled assume they want to | ||||||
| 			// migrate to a shamir seal and simply didn't provide it | 			// migrate to a shamir seal and simply didn't provide it | ||||||
| 			if config.Seals[0].Disabled { | 			if config.Seals[0].Disabled { | ||||||
| 				config.Seals = append(config.Seals, &server.Seal{Type: wrapping.Shamir}) | 				config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.Shamir}) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		for _, configSeal := range config.Seals { | 		for _, configSeal := range config.Seals { | ||||||
| @@ -1034,13 +1037,14 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var seal vault.Seal | 			var seal vault.Seal | ||||||
| 			sealLogger := c.logger.Named(sealType) | 			sealLogger := c.logger.ResetNamed(fmt.Sprintf("seal.%s", sealType)) | ||||||
| 			allLoggers = append(allLoggers, sealLogger) | 			allLoggers = append(allLoggers, sealLogger) | ||||||
| 			seal, sealConfigError = serverseal.ConfigureSeal(configSeal, &infoKeys, &info, sealLogger, vault.NewDefaultSeal(&vaultseal.Access{ | 			defaultSeal := vault.NewDefaultSeal(&vaultseal.Access{ | ||||||
| 				Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 				Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 					Logger: c.logger.Named("shamir"), | 					Logger: c.logger.Named("shamir"), | ||||||
| 				}), | 				}), | ||||||
| 			})) | 			}) | ||||||
|  | 			wrapper, sealConfigError = configutil.ConfigureWrapper(configSeal, &infoKeys, &info, sealLogger) | ||||||
| 			if sealConfigError != nil { | 			if sealConfigError != nil { | ||||||
| 				if !errwrap.ContainsType(sealConfigError, new(logical.KeyNotFoundError)) { | 				if !errwrap.ContainsType(sealConfigError, new(logical.KeyNotFoundError)) { | ||||||
| 					c.UI.Error(fmt.Sprintf( | 					c.UI.Error(fmt.Sprintf( | ||||||
| @@ -1048,16 +1052,19 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 					return 1 | 					return 1 | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if seal == nil { | 			if wrapper == nil { | ||||||
| 				c.UI.Error(fmt.Sprintf( | 				seal = defaultSeal | ||||||
| 					"After configuring seal nil returned, seal type was %s", sealType)) | 			} else { | ||||||
| 				return 1 | 				seal = vault.NewAutoSeal(&vaultseal.Access{ | ||||||
|  | 					Wrapper: wrapper, | ||||||
|  | 				}) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if configSeal.Disabled { | 			if configSeal.Disabled { | ||||||
| 				unwrapSeal = seal | 				unwrapSeal = seal | ||||||
| 			} else { | 			} else { | ||||||
| 				barrierSeal = seal | 				barrierSeal = seal | ||||||
|  | 				barrierWrapper = wrapper | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Ensure that the seal finalizer is called, even if using verify-only | 			// Ensure that the seal finalizer is called, even if using verify-only | ||||||
| @@ -1077,7 +1084,7 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// prepare a secure random reader for core | 	// prepare a secure random reader for core | ||||||
| 	secureRandomReader, err := createSecureRandomReaderFunc(config, &barrierSeal) | 	secureRandomReader, err := configutil.CreateSecureRandomReaderFunc(config.SharedConfig, barrierWrapper) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.UI.Error(err.Error()) | 		c.UI.Error(err.Error()) | ||||||
| 		return 1 | 		return 1 | ||||||
| @@ -1233,7 +1240,7 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if coreConfig.RedirectAddr == "" && c.flagDev { | 	if coreConfig.RedirectAddr == "" && c.flagDev { | ||||||
| 		coreConfig.RedirectAddr = fmt.Sprintf("http://%s", config.Listeners[0].Config["address"]) | 		coreConfig.RedirectAddr = fmt.Sprintf("http://%s", config.Listeners[0].Address) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// After the redirect bits are sorted out, if no cluster address was | 	// After the redirect bits are sorted out, if no cluster address was | ||||||
| @@ -1248,7 +1255,7 @@ func (c *ServerCommand) Run(args []string) int { | |||||||
| 		case coreConfig.ClusterAddr == "" && coreConfig.RedirectAddr != "": | 		case coreConfig.ClusterAddr == "" && coreConfig.RedirectAddr != "": | ||||||
| 			addrToUse = coreConfig.RedirectAddr | 			addrToUse = coreConfig.RedirectAddr | ||||||
| 		case c.flagDev: | 		case c.flagDev: | ||||||
| 			addrToUse = fmt.Sprintf("http://%s", config.Listeners[0].Config["address"]) | 			addrToUse = fmt.Sprintf("http://%s", config.Listeners[0].Address) | ||||||
| 		default: | 		default: | ||||||
| 			goto CLUSTER_SYNTHESIS_COMPLETE | 			goto CLUSTER_SYNTHESIS_COMPLETE | ||||||
| 		} | 		} | ||||||
| @@ -1366,10 +1373,10 @@ CLUSTER_SYNTHESIS_COMPLETE: | |||||||
| 	clusterAddrs := []*net.TCPAddr{} | 	clusterAddrs := []*net.TCPAddr{} | ||||||
|  |  | ||||||
| 	// Initialize the listeners | 	// Initialize the listeners | ||||||
| 	lns := make([]ServerListener, 0, len(config.Listeners)) | 	lns := make([]listenerutil.Listener, 0, len(config.Listeners)) | ||||||
| 	c.reloadFuncsLock.Lock() | 	c.reloadFuncsLock.Lock() | ||||||
| 	for i, lnConfig := range config.Listeners { | 	for i, lnConfig := range config.Listeners { | ||||||
| 		ln, props, reloadFunc, err := server.NewListener(lnConfig.Type, lnConfig.Config, c.gatedWriter, c.UI) | 		ln, props, reloadFunc, err := server.NewListener(lnConfig, c.gatedWriter, c.UI) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			c.UI.Error(fmt.Sprintf("Error initializing listener of type %s: %s", lnConfig.Type, err)) | 			c.UI.Error(fmt.Sprintf("Error initializing listener of type %s: %s", lnConfig.Type, err)) | ||||||
| 			return 1 | 			return 1 | ||||||
| @@ -1382,12 +1389,9 @@ CLUSTER_SYNTHESIS_COMPLETE: | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !disableClustering && lnConfig.Type == "tcp" { | 		if !disableClustering && lnConfig.Type == "tcp" { | ||||||
| 			var addrRaw interface{} | 			addr := lnConfig.ClusterAddress | ||||||
| 			var addr string | 			if addr != "" { | ||||||
| 			var ok bool | 				tcpAddr, err := net.ResolveTCPAddr("tcp", lnConfig.ClusterAddress) | ||||||
| 			if addrRaw, ok = lnConfig.Config["cluster_address"]; ok { |  | ||||||
| 				addr = addrRaw.(string) |  | ||||||
| 				tcpAddr, err := net.ResolveTCPAddr("tcp", addr) |  | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					c.UI.Error(fmt.Sprintf("Error resolving cluster_address: %s", err)) | 					c.UI.Error(fmt.Sprintf("Error resolving cluster_address: %s", err)) | ||||||
| 					return 1 | 					return 1 | ||||||
| @@ -1409,59 +1413,19 @@ CLUSTER_SYNTHESIS_COMPLETE: | |||||||
| 			props["cluster address"] = addr | 			props["cluster address"] = addr | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var maxRequestSize int64 = vaulthttp.DefaultMaxRequestSize | 		if lnConfig.MaxRequestSize == 0 { | ||||||
| 		if valRaw, ok := lnConfig.Config["max_request_size"]; ok { | 			lnConfig.MaxRequestSize = vaulthttp.DefaultMaxRequestSize | ||||||
| 			val, err := parseutil.ParseInt(valRaw) |  | ||||||
| 			if err != nil { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse max_request_size value %v", valRaw)) |  | ||||||
| 				return 1 |  | ||||||
| 		} | 		} | ||||||
|  | 		props["max_request_size"] = fmt.Sprintf("%d", lnConfig.MaxRequestSize) | ||||||
|  |  | ||||||
| 			if val >= 0 { | 		if lnConfig.MaxRequestDuration == 0 { | ||||||
| 				maxRequestSize = val | 			lnConfig.MaxRequestDuration = vault.DefaultMaxRequestDuration | ||||||
| 		} | 		} | ||||||
| 		} | 		props["max_request_duration"] = fmt.Sprintf("%s", lnConfig.MaxRequestDuration.String()) | ||||||
| 		props["max_request_size"] = fmt.Sprintf("%d", maxRequestSize) |  | ||||||
|  |  | ||||||
| 		maxRequestDuration := vault.DefaultMaxRequestDuration | 		lns = append(lns, listenerutil.Listener{ | ||||||
| 		if valRaw, ok := lnConfig.Config["max_request_duration"]; ok { |  | ||||||
| 			val, err := parseutil.ParseDurationSecond(valRaw) |  | ||||||
| 			if err != nil { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse max_request_duration value %v", valRaw)) |  | ||||||
| 				return 1 |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if val >= 0 { |  | ||||||
| 				maxRequestDuration = val |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		props["max_request_duration"] = fmt.Sprintf("%s", maxRequestDuration.String()) |  | ||||||
|  |  | ||||||
| 		var unauthenticatedMetricsAccess bool |  | ||||||
| 		if telemetryRaw, ok := lnConfig.Config["telemetry"]; ok { |  | ||||||
| 			telemetry, ok := telemetryRaw.([]map[string]interface{}) |  | ||||||
| 			if !ok { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse telemetry sink value %v", telemetryRaw)) |  | ||||||
| 				return 1 |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			for _, item := range telemetry { |  | ||||||
| 				if valRaw, ok := item["unauthenticated_metrics_access"]; ok { |  | ||||||
| 					unauthenticatedMetricsAccess, err = parseutil.ParseBool(valRaw) |  | ||||||
| 					if err != nil { |  | ||||||
| 						c.UI.Error(fmt.Sprintf("Could not parse unauthenticated_metrics_access value %v", valRaw)) |  | ||||||
| 						return 1 |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		lns = append(lns, ServerListener{ |  | ||||||
| 			Listener: ln, | 			Listener: ln, | ||||||
| 			config:                       lnConfig.Config, | 			Config:   lnConfig, | ||||||
| 			maxRequestSize:               maxRequestSize, |  | ||||||
| 			maxRequestDuration:           maxRequestDuration, |  | ||||||
| 			unauthenticatedMetricsAccess: unauthenticatedMetricsAccess, |  | ||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
| 		// Store the listener props for output later | 		// Store the listener props for output later | ||||||
| @@ -1629,7 +1593,7 @@ CLUSTER_SYNTHESIS_COMPLETE: | |||||||
| 		c.UI.Warn("You may need to set the following environment variable:") | 		c.UI.Warn("You may need to set the following environment variable:") | ||||||
| 		c.UI.Warn("") | 		c.UI.Warn("") | ||||||
|  |  | ||||||
| 		endpointURL := "http://" + config.Listeners[0].Config["address"].(string) | 		endpointURL := "http://" + config.Listeners[0].Address | ||||||
| 		if runtime.GOOS == "windows" { | 		if runtime.GOOS == "windows" { | ||||||
| 			c.UI.Warn("PowerShell:") | 			c.UI.Warn("PowerShell:") | ||||||
| 			c.UI.Warn(fmt.Sprintf("    $env:VAULT_ADDR=\"%s\"", endpointURL)) | 			c.UI.Warn(fmt.Sprintf("    $env:VAULT_ADDR=\"%s\"", endpointURL)) | ||||||
| @@ -1686,24 +1650,19 @@ CLUSTER_SYNTHESIS_COMPLETE: | |||||||
|  |  | ||||||
| 	// Initialize the HTTP servers | 	// Initialize the HTTP servers | ||||||
| 	for _, ln := range lns { | 	for _, ln := range lns { | ||||||
|  | 		if ln.Config == nil { | ||||||
|  | 			c.UI.Error("Found nil listener config after parsing") | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
| 		handler := vaulthttp.Handler(&vault.HandlerProperties{ | 		handler := vaulthttp.Handler(&vault.HandlerProperties{ | ||||||
| 			Core:                  core, | 			Core:                  core, | ||||||
| 			MaxRequestSize:               ln.maxRequestSize, | 			ListenerConfig:        ln.Config, | ||||||
| 			MaxRequestDuration:           ln.maxRequestDuration, |  | ||||||
| 			DisablePrintableCheck: config.DisablePrintableCheck, | 			DisablePrintableCheck: config.DisablePrintableCheck, | ||||||
| 			UnauthenticatedMetricsAccess: ln.unauthenticatedMetricsAccess, |  | ||||||
| 			RecoveryMode:          c.flagRecovery, | 			RecoveryMode:          c.flagRecovery, | ||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
| 		// We perform validation on the config earlier, we can just cast here | 		if len(ln.Config.XForwardedForAuthorizedAddrs) > 0 { | ||||||
| 		if _, ok := ln.config["x_forwarded_for_authorized_addrs"]; ok { | 			handler = vaulthttp.WrapForwardedForHandler(handler, ln.Config) | ||||||
| 			hopSkips := ln.config["x_forwarded_for_hop_skips"].(int) |  | ||||||
| 			authzdAddrs := ln.config["x_forwarded_for_authorized_addrs"].([]*sockaddr.SockAddrMarshaler) |  | ||||||
| 			rejectNotPresent := ln.config["x_forwarded_for_reject_not_present"].(bool) |  | ||||||
| 			rejectNonAuthz := ln.config["x_forwarded_for_reject_not_authorized"].(bool) |  | ||||||
| 			if len(authzdAddrs) > 0 { |  | ||||||
| 				handler = vaulthttp.WrapForwardedForHandler(handler, authzdAddrs, rejectNotPresent, rejectNonAuthz, hopSkips) |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// server defaults | 		// server defaults | ||||||
| @@ -1716,40 +1675,17 @@ CLUSTER_SYNTHESIS_COMPLETE: | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// override server defaults with config values for read/write/idle timeouts if configured | 		// override server defaults with config values for read/write/idle timeouts if configured | ||||||
| 		if readHeaderTimeoutInterface, ok := ln.config["http_read_header_timeout"]; ok { | 		if ln.Config.HTTPReadHeaderTimeout > 0 { | ||||||
| 			readHeaderTimeout, err := parseutil.ParseDurationSecond(readHeaderTimeoutInterface) | 			server.ReadHeaderTimeout = ln.Config.HTTPReadHeaderTimeout | ||||||
| 			if err != nil { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse a time value for http_read_header_timeout %v", readHeaderTimeout)) |  | ||||||
| 				return 1 |  | ||||||
| 		} | 		} | ||||||
| 			server.ReadHeaderTimeout = readHeaderTimeout | 		if ln.Config.HTTPReadTimeout > 0 { | ||||||
|  | 			server.ReadTimeout = ln.Config.HTTPReadTimeout | ||||||
| 		} | 		} | ||||||
|  | 		if ln.Config.HTTPWriteTimeout > 0 { | ||||||
| 		if readTimeoutInterface, ok := ln.config["http_read_timeout"]; ok { | 			server.WriteTimeout = ln.Config.HTTPWriteTimeout | ||||||
| 			readTimeout, err := parseutil.ParseDurationSecond(readTimeoutInterface) |  | ||||||
| 			if err != nil { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse a time value for http_read_timeout %v", readTimeout)) |  | ||||||
| 				return 1 |  | ||||||
| 		} | 		} | ||||||
| 			server.ReadTimeout = readTimeout | 		if ln.Config.HTTPIdleTimeout > 0 { | ||||||
| 		} | 			server.IdleTimeout = ln.Config.HTTPIdleTimeout | ||||||
|  |  | ||||||
| 		if writeTimeoutInterface, ok := ln.config["http_write_timeout"]; ok { |  | ||||||
| 			writeTimeout, err := parseutil.ParseDurationSecond(writeTimeoutInterface) |  | ||||||
| 			if err != nil { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse a time value for http_write_timeout %v", writeTimeout)) |  | ||||||
| 				return 1 |  | ||||||
| 			} |  | ||||||
| 			server.WriteTimeout = writeTimeout |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if idleTimeoutInterface, ok := ln.config["http_idle_timeout"]; ok { |  | ||||||
| 			idleTimeout, err := parseutil.ParseDurationSecond(idleTimeoutInterface) |  | ||||||
| 			if err != nil { |  | ||||||
| 				c.UI.Error(fmt.Sprintf("Could not parse a time value for http_idle_timeout %v", idleTimeout)) |  | ||||||
| 				return 1 |  | ||||||
| 			} |  | ||||||
| 			server.IdleTimeout = idleTimeout |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// server config tests can exit now | 		// server config tests can exit now | ||||||
| @@ -2305,24 +2241,14 @@ func (c *ServerCommand) detectRedirect(detect physical.RedirectDetect, | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Check if TLS is disabled | 		// Check if TLS is disabled | ||||||
| 		if val, ok := list.Config["tls_disable"]; ok { | 		if list.TLSDisable { | ||||||
| 			disable, err := parseutil.ParseBool(val) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return "", errwrap.Wrapf("tls_disable: {{err}}", err) |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if disable { |  | ||||||
| 			scheme = "http" | 			scheme = "http" | ||||||
| 		} | 		} | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Check for address override | 		// Check for address override | ||||||
| 		var addr string | 		addr := list.Address | ||||||
| 		addrRaw, ok := list.Config["address"] | 		if addr == "" { | ||||||
| 		if !ok { |  | ||||||
| 			addr = "127.0.0.1:8200" | 			addr = "127.0.0.1:8200" | ||||||
| 		} else { |  | ||||||
| 			addr = addrRaw.(string) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Check for localhost | 		// Check for localhost | ||||||
| @@ -2352,165 +2278,6 @@ func (c *ServerCommand) detectRedirect(detect physical.RedirectDetect, | |||||||
| 	return url.String(), nil | 	return url.String(), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // setupTelemetry is used to setup the telemetry sub-systems and returns the in-memory sink to be used in http configuration |  | ||||||
| func (c *ServerCommand) setupTelemetry(config *server.Config) (*metricsutil.MetricsHelper, *metricsutil.ClusterMetricSink, error) { |  | ||||||
| 	/* Setup telemetry |  | ||||||
| 	Aggregate on 10 second intervals for 1 minute. Expose the |  | ||||||
| 	metrics over stderr when there is a SIGUSR1 received. |  | ||||||
| 	*/ |  | ||||||
| 	inm := metrics.NewInmemSink(10*time.Second, time.Minute) |  | ||||||
| 	metrics.DefaultInmemSignal(inm) |  | ||||||
|  |  | ||||||
| 	var telConfig *server.Telemetry |  | ||||||
| 	if config.Telemetry != nil { |  | ||||||
| 		telConfig = config.Telemetry |  | ||||||
| 	} else { |  | ||||||
| 		telConfig = &server.Telemetry{} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	serviceName := "vault" |  | ||||||
| 	if telConfig.MetricsPrefix != "" { |  | ||||||
| 		serviceName = telConfig.MetricsPrefix |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	metricsConf := metrics.DefaultConfig(serviceName) |  | ||||||
| 	metricsConf.EnableHostname = !telConfig.DisableHostname |  | ||||||
| 	metricsConf.EnableHostnameLabel = telConfig.EnableHostnameLabel |  | ||||||
|  |  | ||||||
| 	// Configure the statsite sink |  | ||||||
| 	var fanout metrics.FanoutSink |  | ||||||
| 	var prometheusEnabled bool |  | ||||||
|  |  | ||||||
| 	// Configure the Prometheus sink |  | ||||||
| 	if telConfig.PrometheusRetentionTime != 0 { |  | ||||||
| 		prometheusEnabled = true |  | ||||||
| 		prometheusOpts := prometheus.PrometheusOpts{ |  | ||||||
| 			Expiration: telConfig.PrometheusRetentionTime, |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		sink, err := prometheus.NewPrometheusSinkFrom(prometheusOpts) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
| 		fanout = append(fanout, sink) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	metricHelper := metricsutil.NewMetricsHelper(inm, prometheusEnabled) |  | ||||||
|  |  | ||||||
| 	if telConfig.StatsiteAddr != "" { |  | ||||||
| 		sink, err := metrics.NewStatsiteSink(telConfig.StatsiteAddr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
| 		fanout = append(fanout, sink) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Configure the statsd sink |  | ||||||
| 	if telConfig.StatsdAddr != "" { |  | ||||||
| 		sink, err := metrics.NewStatsdSink(telConfig.StatsdAddr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
| 		fanout = append(fanout, sink) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Configure the Circonus sink |  | ||||||
| 	if telConfig.CirconusAPIToken != "" || telConfig.CirconusCheckSubmissionURL != "" { |  | ||||||
| 		cfg := &circonus.Config{} |  | ||||||
| 		cfg.Interval = telConfig.CirconusSubmissionInterval |  | ||||||
| 		cfg.CheckManager.API.TokenKey = telConfig.CirconusAPIToken |  | ||||||
| 		cfg.CheckManager.API.TokenApp = telConfig.CirconusAPIApp |  | ||||||
| 		cfg.CheckManager.API.URL = telConfig.CirconusAPIURL |  | ||||||
| 		cfg.CheckManager.Check.SubmissionURL = telConfig.CirconusCheckSubmissionURL |  | ||||||
| 		cfg.CheckManager.Check.ID = telConfig.CirconusCheckID |  | ||||||
| 		cfg.CheckManager.Check.ForceMetricActivation = telConfig.CirconusCheckForceMetricActivation |  | ||||||
| 		cfg.CheckManager.Check.InstanceID = telConfig.CirconusCheckInstanceID |  | ||||||
| 		cfg.CheckManager.Check.SearchTag = telConfig.CirconusCheckSearchTag |  | ||||||
| 		cfg.CheckManager.Check.DisplayName = telConfig.CirconusCheckDisplayName |  | ||||||
| 		cfg.CheckManager.Check.Tags = telConfig.CirconusCheckTags |  | ||||||
| 		cfg.CheckManager.Broker.ID = telConfig.CirconusBrokerID |  | ||||||
| 		cfg.CheckManager.Broker.SelectTag = telConfig.CirconusBrokerSelectTag |  | ||||||
|  |  | ||||||
| 		if cfg.CheckManager.API.TokenApp == "" { |  | ||||||
| 			cfg.CheckManager.API.TokenApp = "vault" |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if cfg.CheckManager.Check.DisplayName == "" { |  | ||||||
| 			cfg.CheckManager.Check.DisplayName = "Vault" |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if cfg.CheckManager.Check.SearchTag == "" { |  | ||||||
| 			cfg.CheckManager.Check.SearchTag = "service:vault" |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		sink, err := circonus.NewCirconusSink(cfg) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
| 		sink.Start() |  | ||||||
| 		fanout = append(fanout, sink) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if telConfig.DogStatsDAddr != "" { |  | ||||||
| 		var tags []string |  | ||||||
|  |  | ||||||
| 		if telConfig.DogStatsDTags != nil { |  | ||||||
| 			tags = telConfig.DogStatsDTags |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		sink, err := datadog.NewDogStatsdSink(telConfig.DogStatsDAddr, metricsConf.HostName) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, errwrap.Wrapf("failed to start DogStatsD sink: {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		sink.SetTags(tags) |  | ||||||
| 		fanout = append(fanout, sink) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Configure the stackdriver sink |  | ||||||
| 	if telConfig.StackdriverProjectID != "" { |  | ||||||
| 		client, err := monitoring.NewMetricClient(context.Background(), option.WithUserAgent(useragent.String())) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, fmt.Errorf("Failed to create stackdriver client: %v", err) |  | ||||||
| 		} |  | ||||||
| 		sink := stackdriver.NewSink(client, &stackdriver.Config{ |  | ||||||
| 			LabelExtractor: stackdrivervault.Extractor, |  | ||||||
| 			Bucketer:       stackdrivervault.Bucketer, |  | ||||||
| 			ProjectID:      telConfig.StackdriverProjectID, |  | ||||||
| 			Location:       telConfig.StackdriverLocation, |  | ||||||
| 			Namespace:      telConfig.StackdriverNamespace, |  | ||||||
| 			DebugLogs:      telConfig.StackdriverDebugLogs, |  | ||||||
| 		}) |  | ||||||
| 		fanout = append(fanout, sink) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Initialize the global sink |  | ||||||
| 	if len(fanout) > 1 { |  | ||||||
| 		// Hostname enabled will create poor quality metrics name for prometheus |  | ||||||
| 		if !telConfig.DisableHostname { |  | ||||||
| 			c.UI.Warn("telemetry.disable_hostname has been set to false. Recommended setting is true for Prometheus to avoid poorly named metrics.") |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		metricsConf.EnableHostname = false |  | ||||||
| 	} |  | ||||||
| 	fanout = append(fanout, inm) |  | ||||||
| 	_, err := metrics.NewGlobal(metricsConf, fanout) |  | ||||||
|  |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Intialize a wrapper around the global sink; this will be passed to Core |  | ||||||
| 	// and to any backend. |  | ||||||
| 	wrapper := &metricsutil.ClusterMetricSink{ |  | ||||||
| 		ClusterName:         config.ClusterName, |  | ||||||
| 		MaxGaugeCardinality: 500, |  | ||||||
| 		GaugeInterval:       10 * time.Minute, |  | ||||||
| 		Sink:                fanout, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return metricHelper, wrapper, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *ServerCommand) Reload(lock *sync.RWMutex, reloadFuncs *map[string][]reloadutil.ReloadFunc, configPath []string) error { | func (c *ServerCommand) Reload(lock *sync.RWMutex, reloadFuncs *map[string][]reloadutil.ReloadFunc, configPath []string) error { | ||||||
| 	lock.RLock() | 	lock.RLock() | ||||||
| 	defer lock.RUnlock() | 	defer lock.RUnlock() | ||||||
| @@ -2522,7 +2289,7 @@ func (c *ServerCommand) Reload(lock *sync.RWMutex, reloadFuncs *map[string][]rel | |||||||
| 		case strings.HasPrefix(k, "listener|"): | 		case strings.HasPrefix(k, "listener|"): | ||||||
| 			for _, relFunc := range relFuncs { | 			for _, relFunc := range relFuncs { | ||||||
| 				if relFunc != nil { | 				if relFunc != nil { | ||||||
| 					if err := relFunc(nil); err != nil { | 					if err := relFunc(); err != nil { | ||||||
| 						reloadErrors = multierror.Append(reloadErrors, errwrap.Wrapf("error encountered reloading listener: {{err}}", err)) | 						reloadErrors = multierror.Append(reloadErrors, errwrap.Wrapf("error encountered reloading listener: {{err}}", err)) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| @@ -2531,7 +2298,7 @@ func (c *ServerCommand) Reload(lock *sync.RWMutex, reloadFuncs *map[string][]rel | |||||||
| 		case strings.HasPrefix(k, "audit_file|"): | 		case strings.HasPrefix(k, "audit_file|"): | ||||||
| 			for _, relFunc := range relFuncs { | 			for _, relFunc := range relFuncs { | ||||||
| 				if relFunc != nil { | 				if relFunc != nil { | ||||||
| 					if err := relFunc(nil); err != nil { | 					if err := relFunc(); err != nil { | ||||||
| 						reloadErrors = multierror.Append(reloadErrors, errwrap.Wrapf(fmt.Sprintf("error encountered reloading file audit device at path %q: {{err}}", strings.TrimPrefix(k, "audit_file|")), err)) | 						reloadErrors = multierror.Append(reloadErrors, errwrap.Wrapf(fmt.Sprintf("error encountered reloading file audit device at path %q: {{err}}", strings.TrimPrefix(k, "audit_file|")), err)) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -15,60 +15,40 @@ import ( | |||||||
| 	"github.com/hashicorp/go-multierror" | 	"github.com/hashicorp/go-multierror" | ||||||
| 	"github.com/hashicorp/hcl" | 	"github.com/hashicorp/hcl" | ||||||
| 	"github.com/hashicorp/hcl/hcl/ast" | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/parseutil" | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	prometheusDefaultRetentionTime = 24 * time.Hour |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Config is the configuration for the vault server. | // Config is the configuration for the vault server. | ||||||
| type Config struct { | type Config struct { | ||||||
| 	entConfig | 	entConfig | ||||||
|  |  | ||||||
| 	Listeners []*Listener `hcl:"-"` | 	*configutil.SharedConfig `hcl:"-"` | ||||||
|  |  | ||||||
| 	Storage   *Storage `hcl:"-"` | 	Storage   *Storage `hcl:"-"` | ||||||
| 	HAStorage *Storage `hcl:"-"` | 	HAStorage *Storage `hcl:"-"` | ||||||
|  |  | ||||||
| 	ServiceRegistration *ServiceRegistration `hcl:"-"` | 	ServiceRegistration *ServiceRegistration `hcl:"-"` | ||||||
|  |  | ||||||
| 	Seals   []*Seal  `hcl:"-"` |  | ||||||
| 	Entropy *Entropy `hcl:"-"` |  | ||||||
|  |  | ||||||
| 	CacheSize                int         `hcl:"cache_size"` | 	CacheSize                int         `hcl:"cache_size"` | ||||||
| 	DisableCache             bool        `hcl:"-"` | 	DisableCache             bool        `hcl:"-"` | ||||||
| 	DisableCacheRaw          interface{} `hcl:"disable_cache"` | 	DisableCacheRaw          interface{} `hcl:"disable_cache"` | ||||||
| 	DisableMlock             bool        `hcl:"-"` |  | ||||||
| 	DisableMlockRaw          interface{} `hcl:"disable_mlock"` |  | ||||||
| 	DisablePrintableCheck    bool        `hcl:"-"` | 	DisablePrintableCheck    bool        `hcl:"-"` | ||||||
| 	DisablePrintableCheckRaw interface{} `hcl:"disable_printable_check"` | 	DisablePrintableCheckRaw interface{} `hcl:"disable_printable_check"` | ||||||
|  |  | ||||||
| 	EnableUI    bool        `hcl:"-"` | 	EnableUI    bool        `hcl:"-"` | ||||||
| 	EnableUIRaw interface{} `hcl:"ui"` | 	EnableUIRaw interface{} `hcl:"ui"` | ||||||
|  |  | ||||||
| 	Telemetry *Telemetry `hcl:"telemetry"` |  | ||||||
|  |  | ||||||
| 	MaxLeaseTTL        time.Duration `hcl:"-"` | 	MaxLeaseTTL        time.Duration `hcl:"-"` | ||||||
| 	MaxLeaseTTLRaw     interface{}   `hcl:"max_lease_ttl"` | 	MaxLeaseTTLRaw     interface{}   `hcl:"max_lease_ttl"` | ||||||
| 	DefaultLeaseTTL    time.Duration `hcl:"-"` | 	DefaultLeaseTTL    time.Duration `hcl:"-"` | ||||||
| 	DefaultLeaseTTLRaw interface{}   `hcl:"default_lease_ttl"` | 	DefaultLeaseTTLRaw interface{}   `hcl:"default_lease_ttl"` | ||||||
|  |  | ||||||
| 	DefaultMaxRequestDuration    time.Duration `hcl:"-"` |  | ||||||
| 	DefaultMaxRequestDurationRaw interface{}   `hcl:"default_max_request_duration"` |  | ||||||
|  |  | ||||||
| 	ClusterName         string `hcl:"cluster_name"` |  | ||||||
| 	ClusterCipherSuites string `hcl:"cluster_cipher_suites"` | 	ClusterCipherSuites string `hcl:"cluster_cipher_suites"` | ||||||
|  |  | ||||||
| 	PluginDirectory string `hcl:"plugin_directory"` | 	PluginDirectory string `hcl:"plugin_directory"` | ||||||
|  |  | ||||||
| 	LogLevel string `hcl:"log_level"` |  | ||||||
|  |  | ||||||
| 	// LogFormat specifies the log format.  Valid values are "standard" and "json".  The values are case-insenstive. |  | ||||||
| 	// If no log format is specified, then standard format will be used. |  | ||||||
| 	LogFormat string `hcl:"log_format"` |  | ||||||
|  |  | ||||||
| 	PidFile              string      `hcl:"pid_file"` |  | ||||||
| 	EnableRawEndpoint    bool        `hcl:"-"` | 	EnableRawEndpoint    bool        `hcl:"-"` | ||||||
| 	EnableRawEndpointRaw interface{} `hcl:"raw_storage_endpoint"` | 	EnableRawEndpointRaw interface{} `hcl:"raw_storage_endpoint"` | ||||||
|  |  | ||||||
| @@ -88,58 +68,36 @@ type Config struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| // DevConfig is a Config that is used for dev mode of Vault. | // DevConfig is a Config that is used for dev mode of Vault. | ||||||
| func DevConfig(storageType string) *Config { | func DevConfig(storageType string) (*Config, error) { | ||||||
| 	ret := &Config{ | 	hclStr := ` | ||||||
| 		DisableMlock:      true, | disable_mlock = true | ||||||
| 		EnableRawEndpoint: true, |  | ||||||
|  |  | ||||||
| 		Storage: &Storage{ | listener "tcp" { | ||||||
| 			Type: storageType, | 	address = "127.0.0.1:8200" | ||||||
| 		}, | 	tls_disable = true | ||||||
|  | 	proxy_protocol_behavior = "allow_authorized" | ||||||
|  | 	proxy_protocol_authorized_addrs = "127.0.0.1:8200" | ||||||
|  | } | ||||||
|  |  | ||||||
| 		Listeners: []*Listener{ | telemetry { | ||||||
| 			&Listener{ | 	prometheus_retention_time = "24h" | ||||||
| 				Type: "tcp", | 	disable_hostname = true | ||||||
| 				Config: map[string]interface{}{ | } | ||||||
| 					"address":                         "127.0.0.1:8200", |  | ||||||
| 					"tls_disable":                     true, |  | ||||||
| 					"proxy_protocol_behavior":         "allow_authorized", |  | ||||||
| 					"proxy_protocol_authorized_addrs": "127.0.0.1:8200", |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		EnableUI: true, | enable_raw_endpoint = true | ||||||
|  |  | ||||||
| 		Telemetry: &Telemetry{ | storage "%s" { | ||||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, | } | ||||||
| 			DisableHostname:         true, |  | ||||||
| 		}, | enable_ui = true | ||||||
|  | ` | ||||||
|  |  | ||||||
|  | 	hclStr = fmt.Sprintf(hclStr, storageType) | ||||||
|  | 	parsed, err := ParseConfig(hclStr) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("error parsing dev config: %w", err) | ||||||
| 	} | 	} | ||||||
|  | 	return parsed, nil | ||||||
| 	return ret |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Listener is the listener configuration for the server. |  | ||||||
| type Listener struct { |  | ||||||
| 	Type   string |  | ||||||
| 	Config map[string]interface{} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (l *Listener) GoString() string { |  | ||||||
| 	return fmt.Sprintf("*%#v", *l) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Entropy contains Entropy configuration for the server |  | ||||||
| type EntropyMode int |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	Unknown EntropyMode = iota |  | ||||||
| 	Augmentation |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type Entropy struct { |  | ||||||
| 	Mode EntropyMode |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Storage is the underlying storage configuration for the server. | // Storage is the underlying storage configuration for the server. | ||||||
| @@ -165,125 +123,10 @@ func (b *ServiceRegistration) GoString() string { | |||||||
| 	return fmt.Sprintf("*%#v", *b) | 	return fmt.Sprintf("*%#v", *b) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Seal contains Seal configuration for the server | func NewConfig() *Config { | ||||||
| type Seal struct { | 	return &Config{ | ||||||
| 	Type     string | 		SharedConfig: new(configutil.SharedConfig), | ||||||
| 	Disabled bool | 	} | ||||||
| 	Config   map[string]string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *Seal) GoString() string { |  | ||||||
| 	return fmt.Sprintf("*%#v", *h) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Telemetry is the telemetry configuration for the server |  | ||||||
| type Telemetry struct { |  | ||||||
| 	StatsiteAddr string `hcl:"statsite_address"` |  | ||||||
| 	StatsdAddr   string `hcl:"statsd_address"` |  | ||||||
|  |  | ||||||
| 	DisableHostname     bool   `hcl:"disable_hostname"` |  | ||||||
| 	EnableHostnameLabel bool   `hcl:"enable_hostname_label"` |  | ||||||
| 	MetricsPrefix       string `hcl:"metrics_prefix"` |  | ||||||
|  |  | ||||||
| 	// Circonus: see https://github.com/circonus-labs/circonus-gometrics |  | ||||||
| 	// for more details on the various configuration options. |  | ||||||
| 	// Valid configuration combinations: |  | ||||||
| 	//    - CirconusAPIToken |  | ||||||
| 	//      metric management enabled (search for existing check or create a new one) |  | ||||||
| 	//    - CirconusSubmissionUrl |  | ||||||
| 	//      metric management disabled (use check with specified submission_url, |  | ||||||
| 	//      broker must be using a public SSL certificate) |  | ||||||
| 	//    - CirconusAPIToken + CirconusCheckSubmissionURL |  | ||||||
| 	//      metric management enabled (use check with specified submission_url) |  | ||||||
| 	//    - CirconusAPIToken + CirconusCheckID |  | ||||||
| 	//      metric management enabled (use check with specified id) |  | ||||||
|  |  | ||||||
| 	// CirconusAPIToken is a valid API Token used to create/manage check. If provided, |  | ||||||
| 	// metric management is enabled. |  | ||||||
| 	// Default: none |  | ||||||
| 	CirconusAPIToken string `hcl:"circonus_api_token"` |  | ||||||
| 	// CirconusAPIApp is an app name associated with API token. |  | ||||||
| 	// Default: "consul" |  | ||||||
| 	CirconusAPIApp string `hcl:"circonus_api_app"` |  | ||||||
| 	// CirconusAPIURL is the base URL to use for contacting the Circonus API. |  | ||||||
| 	// Default: "https://api.circonus.com/v2" |  | ||||||
| 	CirconusAPIURL string `hcl:"circonus_api_url"` |  | ||||||
| 	// CirconusSubmissionInterval is the interval at which metrics are submitted to Circonus. |  | ||||||
| 	// Default: 10s |  | ||||||
| 	CirconusSubmissionInterval string `hcl:"circonus_submission_interval"` |  | ||||||
| 	// CirconusCheckSubmissionURL is the check.config.submission_url field from a |  | ||||||
| 	// previously created HTTPTRAP check. |  | ||||||
| 	// Default: none |  | ||||||
| 	CirconusCheckSubmissionURL string `hcl:"circonus_submission_url"` |  | ||||||
| 	// CirconusCheckID is the check id (not check bundle id) from a previously created |  | ||||||
| 	// HTTPTRAP check. The numeric portion of the check._cid field. |  | ||||||
| 	// Default: none |  | ||||||
| 	CirconusCheckID string `hcl:"circonus_check_id"` |  | ||||||
| 	// CirconusCheckForceMetricActivation will force enabling metrics, as they are encountered, |  | ||||||
| 	// if the metric already exists and is NOT active. If check management is enabled, the default |  | ||||||
| 	// behavior is to add new metrics as they are encountered. If the metric already exists in the |  | ||||||
| 	// check, it will *NOT* be activated. This setting overrides that behavior. |  | ||||||
| 	// Default: "false" |  | ||||||
| 	CirconusCheckForceMetricActivation string `hcl:"circonus_check_force_metric_activation"` |  | ||||||
| 	// CirconusCheckInstanceID serves to uniquely identify the metrics coming from this "instance". |  | ||||||
| 	// It can be used to maintain metric continuity with transient or ephemeral instances as |  | ||||||
| 	// they move around within an infrastructure. |  | ||||||
| 	// Default: hostname:app |  | ||||||
| 	CirconusCheckInstanceID string `hcl:"circonus_check_instance_id"` |  | ||||||
| 	// CirconusCheckSearchTag is a special tag which, when coupled with the instance id, helps to |  | ||||||
| 	// narrow down the search results when neither a Submission URL or Check ID is provided. |  | ||||||
| 	// Default: service:app (e.g. service:consul) |  | ||||||
| 	CirconusCheckSearchTag string `hcl:"circonus_check_search_tag"` |  | ||||||
| 	// CirconusCheckTags is a comma separated list of tags to apply to the check. Note that |  | ||||||
| 	// the value of CirconusCheckSearchTag will always be added to the check. |  | ||||||
| 	// Default: none |  | ||||||
| 	CirconusCheckTags string `hcl:"circonus_check_tags"` |  | ||||||
| 	// CirconusCheckDisplayName is the name for the check which will be displayed in the Circonus UI. |  | ||||||
| 	// Default: value of CirconusCheckInstanceID |  | ||||||
| 	CirconusCheckDisplayName string `hcl:"circonus_check_display_name"` |  | ||||||
| 	// CirconusBrokerID is an explicit broker to use when creating a new check. The numeric portion |  | ||||||
| 	// of broker._cid. If metric management is enabled and neither a Submission URL nor Check ID |  | ||||||
| 	// is provided, an attempt will be made to search for an existing check using Instance ID and |  | ||||||
| 	// Search Tag. If one is not found, a new HTTPTRAP check will be created. |  | ||||||
| 	// Default: use Select Tag if provided, otherwise, a random Enterprise Broker associated |  | ||||||
| 	// with the specified API token or the default Circonus Broker. |  | ||||||
| 	// Default: none |  | ||||||
| 	CirconusBrokerID string `hcl:"circonus_broker_id"` |  | ||||||
| 	// CirconusBrokerSelectTag is a special tag which will be used to select a broker when |  | ||||||
| 	// a Broker ID is not provided. The best use of this is to as a hint for which broker |  | ||||||
| 	// should be used based on *where* this particular instance is running. |  | ||||||
| 	// (e.g. a specific geo location or datacenter, dc:sfo) |  | ||||||
| 	// Default: none |  | ||||||
| 	CirconusBrokerSelectTag string `hcl:"circonus_broker_select_tag"` |  | ||||||
|  |  | ||||||
| 	// Dogstats: |  | ||||||
| 	// DogStatsdAddr is the address of a dogstatsd instance. If provided, |  | ||||||
| 	// metrics will be sent to that instance |  | ||||||
| 	DogStatsDAddr string `hcl:"dogstatsd_addr"` |  | ||||||
|  |  | ||||||
| 	// DogStatsdTags are the global tags that should be sent with each packet to dogstatsd |  | ||||||
| 	// It is a list of strings, where each string looks like "my_tag_name:my_tag_value" |  | ||||||
| 	DogStatsDTags []string `hcl:"dogstatsd_tags"` |  | ||||||
|  |  | ||||||
| 	// Prometheus: |  | ||||||
| 	// PrometheusRetentionTime is the retention time for prometheus metrics if greater than 0. |  | ||||||
| 	// Default: 24h |  | ||||||
| 	PrometheusRetentionTime    time.Duration `hcl:"-"` |  | ||||||
| 	PrometheusRetentionTimeRaw interface{}   `hcl:"prometheus_retention_time"` |  | ||||||
|  |  | ||||||
| 	// Stackdriver: |  | ||||||
| 	// StackdriverProjectID is the project to publish stackdriver metrics to. |  | ||||||
| 	StackdriverProjectID string `hcl:"stackdriver_project_id"` |  | ||||||
| 	// StackdriverLocation is the GCP or AWS region of the monitored resource. |  | ||||||
| 	StackdriverLocation string `hcl:"stackdriver_location"` |  | ||||||
| 	// StackdriverNamespace is the namespace identifier, such as a cluster name. |  | ||||||
| 	StackdriverNamespace string `hcl:"stackdriver_namespace"` |  | ||||||
| 	// StackdriverDebugLogs will write additional stackdriver related debug logs to stderr. |  | ||||||
| 	StackdriverDebugLogs bool `hcl:"stackdriver_debug_logs"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *Telemetry) GoString() string { |  | ||||||
| 	return fmt.Sprintf("*%#v", *s) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Merge merges two configurations. | // Merge merges two configurations. | ||||||
| @@ -292,12 +135,11 @@ func (c *Config) Merge(c2 *Config) *Config { | |||||||
| 		return c | 		return c | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result := new(Config) | 	result := NewConfig() | ||||||
| 	for _, l := range c.Listeners { |  | ||||||
| 		result.Listeners = append(result.Listeners, l) | 	result.SharedConfig = c.SharedConfig | ||||||
| 	} | 	if c2.SharedConfig != nil { | ||||||
| 	for _, l := range c2.Listeners { | 		result.SharedConfig = c.SharedConfig.Merge(c2.SharedConfig) | ||||||
| 		result.Listeners = append(result.Listeners, l) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result.Storage = c.Storage | 	result.Storage = c.Storage | ||||||
| @@ -315,23 +157,6 @@ func (c *Config) Merge(c2 *Config) *Config { | |||||||
| 		result.ServiceRegistration = c2.ServiceRegistration | 		result.ServiceRegistration = c2.ServiceRegistration | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result.Entropy = c.Entropy |  | ||||||
| 	if c2.Entropy != nil { |  | ||||||
| 		result.Entropy = c2.Entropy |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, s := range c.Seals { |  | ||||||
| 		result.Seals = append(result.Seals, s) |  | ||||||
| 	} |  | ||||||
| 	for _, s := range c2.Seals { |  | ||||||
| 		result.Seals = append(result.Seals, s) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.Telemetry = c.Telemetry |  | ||||||
| 	if c2.Telemetry != nil { |  | ||||||
| 		result.Telemetry = c2.Telemetry |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.CacheSize = c.CacheSize | 	result.CacheSize = c.CacheSize | ||||||
| 	if c2.CacheSize != 0 { | 	if c2.CacheSize != 0 { | ||||||
| 		result.CacheSize = c2.CacheSize | 		result.CacheSize = c2.CacheSize | ||||||
| @@ -343,11 +168,6 @@ func (c *Config) Merge(c2 *Config) *Config { | |||||||
| 		result.DisableCache = c2.DisableCache | 		result.DisableCache = c2.DisableCache | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result.DisableMlock = c.DisableMlock |  | ||||||
| 	if c2.DisableMlock { |  | ||||||
| 		result.DisableMlock = c2.DisableMlock |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.DisablePrintableCheck = c.DisablePrintableCheck | 	result.DisablePrintableCheck = c.DisablePrintableCheck | ||||||
| 	if c2.DisablePrintableCheckRaw != nil { | 	if c2.DisablePrintableCheckRaw != nil { | ||||||
| 		result.DisablePrintableCheck = c2.DisablePrintableCheck | 		result.DisablePrintableCheck = c2.DisablePrintableCheck | ||||||
| @@ -364,26 +184,6 @@ func (c *Config) Merge(c2 *Config) *Config { | |||||||
| 		result.DefaultLeaseTTL = c2.DefaultLeaseTTL | 		result.DefaultLeaseTTL = c2.DefaultLeaseTTL | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result.DefaultMaxRequestDuration = c.DefaultMaxRequestDuration |  | ||||||
| 	if c2.DefaultMaxRequestDuration > result.DefaultMaxRequestDuration { |  | ||||||
| 		result.DefaultMaxRequestDuration = c2.DefaultMaxRequestDuration |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.LogLevel = c.LogLevel |  | ||||||
| 	if c2.LogLevel != "" { |  | ||||||
| 		result.LogLevel = c2.LogLevel |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.LogFormat = c.LogFormat |  | ||||||
| 	if c2.LogFormat != "" { |  | ||||||
| 		result.LogFormat = c2.LogFormat |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.ClusterName = c.ClusterName |  | ||||||
| 	if c2.ClusterName != "" { |  | ||||||
| 		result.ClusterName = c2.ClusterName |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.ClusterCipherSuites = c.ClusterCipherSuites | 	result.ClusterCipherSuites = c.ClusterCipherSuites | ||||||
| 	if c2.ClusterCipherSuites != "" { | 	if c2.ClusterCipherSuites != "" { | ||||||
| 		result.ClusterCipherSuites = c2.ClusterCipherSuites | 		result.ClusterCipherSuites = c2.ClusterCipherSuites | ||||||
| @@ -422,11 +222,6 @@ func (c *Config) Merge(c2 *Config) *Config { | |||||||
| 		result.PluginDirectory = c2.PluginDirectory | 		result.PluginDirectory = c2.PluginDirectory | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result.PidFile = c.PidFile |  | ||||||
| 	if c2.PidFile != "" { |  | ||||||
| 		result.PidFile = c2.PidFile |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.DisablePerformanceStandby = c.DisablePerformanceStandby | 	result.DisablePerformanceStandby = c.DisablePerformanceStandby | ||||||
| 	if c2.DisablePerformanceStandby { | 	if c2.DisablePerformanceStandby { | ||||||
| 		result.DisablePerformanceStandby = c2.DisablePerformanceStandby | 		result.DisablePerformanceStandby = c2.DisablePerformanceStandby | ||||||
| @@ -479,9 +274,26 @@ func LoadConfig(path string) (*Config, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if fi.IsDir() { | 	if fi.IsDir() { | ||||||
| 		return LoadConfigDir(path) | 		return CheckConfig(LoadConfigDir(path)) | ||||||
| 	} | 	} | ||||||
| 	return LoadConfigFile(path) | 	return CheckConfig(LoadConfigFile(path)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func CheckConfig(c *Config, e error) (*Config, error) { | ||||||
|  | 	if e != nil { | ||||||
|  | 		return c, e | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(c.Seals) == 2 { | ||||||
|  | 		switch { | ||||||
|  | 		case c.Seals[0].Disabled && c.Seals[1].Disabled: | ||||||
|  | 			return nil, errors.New("seals: two seals provided but both are disabled") | ||||||
|  | 		case !c.Seals[0].Disabled && !c.Seals[1].Disabled: | ||||||
|  | 			return nil, errors.New("seals: two seals provided but neither is disabled") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return c, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // LoadConfigFile loads the configuration from the given file. | // LoadConfigFile loads the configuration from the given file. | ||||||
| @@ -491,7 +303,13 @@ func LoadConfigFile(path string) (*Config, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return ParseConfig(string(d)) |  | ||||||
|  | 	conf, err := ParseConfig(string(d)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return conf, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func ParseConfig(d string) (*Config, error) { | func ParseConfig(d string) (*Config, error) { | ||||||
| @@ -502,11 +320,17 @@ func ParseConfig(d string) (*Config, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Start building the result | 	// Start building the result | ||||||
| 	var result Config | 	result := NewConfig() | ||||||
| 	if err := hcl.DecodeObject(&result, obj); err != nil { | 	if err := hcl.DecodeObject(result, obj); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	sharedConfig, err := configutil.ParseConfig(d) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	result.SharedConfig = sharedConfig | ||||||
|  |  | ||||||
| 	if result.MaxLeaseTTLRaw != nil { | 	if result.MaxLeaseTTLRaw != nil { | ||||||
| 		if result.MaxLeaseTTL, err = parseutil.ParseDurationSecond(result.MaxLeaseTTLRaw); err != nil { | 		if result.MaxLeaseTTL, err = parseutil.ParseDurationSecond(result.MaxLeaseTTLRaw); err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| @@ -518,12 +342,6 @@ func ParseConfig(d string) (*Config, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if result.DefaultMaxRequestDurationRaw != nil { |  | ||||||
| 		if result.DefaultMaxRequestDuration, err = parseutil.ParseDurationSecond(result.DefaultMaxRequestDurationRaw); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if result.EnableUIRaw != nil { | 	if result.EnableUIRaw != nil { | ||||||
| 		if result.EnableUI, err = parseutil.ParseBool(result.EnableUIRaw); err != nil { | 		if result.EnableUI, err = parseutil.ParseBool(result.EnableUIRaw); err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| @@ -536,12 +354,6 @@ func ParseConfig(d string) (*Config, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if result.DisableMlockRaw != nil { |  | ||||||
| 		if result.DisableMlock, err = parseutil.ParseBool(result.DisableMlockRaw); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if result.DisablePrintableCheckRaw != nil { | 	if result.DisablePrintableCheckRaw != nil { | ||||||
| 		if result.DisablePrintableCheck, err = parseutil.ParseBool(result.DisablePrintableCheckRaw); err != nil { | 		if result.DisablePrintableCheck, err = parseutil.ParseBool(result.DisablePrintableCheckRaw); err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| @@ -585,24 +397,24 @@ func ParseConfig(d string) (*Config, error) { | |||||||
|  |  | ||||||
| 	// Look for storage but still support old backend | 	// Look for storage but still support old backend | ||||||
| 	if o := list.Filter("storage"); len(o.Items) > 0 { | 	if o := list.Filter("storage"); len(o.Items) > 0 { | ||||||
| 		if err := ParseStorage(&result, o, "storage"); err != nil { | 		if err := ParseStorage(result, o, "storage"); err != nil { | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'storage': {{err}}", err) | 			return nil, errwrap.Wrapf("error parsing 'storage': {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if o := list.Filter("backend"); len(o.Items) > 0 { | 		if o := list.Filter("backend"); len(o.Items) > 0 { | ||||||
| 			if err := ParseStorage(&result, o, "backend"); err != nil { | 			if err := ParseStorage(result, o, "backend"); err != nil { | ||||||
| 				return nil, errwrap.Wrapf("error parsing 'backend': {{err}}", err) | 				return nil, errwrap.Wrapf("error parsing 'backend': {{err}}", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o := list.Filter("ha_storage"); len(o.Items) > 0 { | 	if o := list.Filter("ha_storage"); len(o.Items) > 0 { | ||||||
| 		if err := parseHAStorage(&result, o, "ha_storage"); err != nil { | 		if err := parseHAStorage(result, o, "ha_storage"); err != nil { | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'ha_storage': {{err}}", err) | 			return nil, errwrap.Wrapf("error parsing 'ha_storage': {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if o := list.Filter("ha_backend"); len(o.Items) > 0 { | 		if o := list.Filter("ha_backend"); len(o.Items) > 0 { | ||||||
| 			if err := parseHAStorage(&result, o, "ha_backend"); err != nil { | 			if err := parseHAStorage(result, o, "ha_backend"); err != nil { | ||||||
| 				return nil, errwrap.Wrapf("error parsing 'ha_backend': {{err}}", err) | 				return nil, errwrap.Wrapf("error parsing 'ha_backend': {{err}}", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -610,47 +422,17 @@ func ParseConfig(d string) (*Config, error) { | |||||||
|  |  | ||||||
| 	// Parse service discovery | 	// Parse service discovery | ||||||
| 	if o := list.Filter("service_registration"); len(o.Items) > 0 { | 	if o := list.Filter("service_registration"); len(o.Items) > 0 { | ||||||
| 		if err := parseServiceRegistration(&result, o, "service_registration"); err != nil { | 		if err := parseServiceRegistration(result, o, "service_registration"); err != nil { | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'service_registration': {{err}}", err) | 			return nil, errwrap.Wrapf("error parsing 'service_registration': {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o := list.Filter("hsm"); len(o.Items) > 0 { |  | ||||||
| 		if err := parseSeals(&result, o, "hsm"); err != nil { |  | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'hsm': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o := list.Filter("seal"); len(o.Items) > 0 { |  | ||||||
| 		if err := parseSeals(&result, o, "seal"); err != nil { |  | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'seal': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o := list.Filter("entropy"); len(o.Items) > 0 { |  | ||||||
| 		if err := parseEntropy(&result, o, "entropy"); err != nil { |  | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'entropy': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o := list.Filter("listener"); len(o.Items) > 0 { |  | ||||||
| 		if err := parseListeners(&result, o); err != nil { |  | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'listener': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o := list.Filter("telemetry"); len(o.Items) > 0 { |  | ||||||
| 		if err := parseTelemetry(&result, o); err != nil { |  | ||||||
| 			return nil, errwrap.Wrapf("error parsing 'telemetry': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	entConfig := &(result.entConfig) | 	entConfig := &(result.entConfig) | ||||||
| 	if err := entConfig.parseConfig(list); err != nil { | 	if err := entConfig.parseConfig(list); err != nil { | ||||||
| 		return nil, errwrap.Wrapf("error parsing enterprise config: {{err}}", err) | 		return nil, errwrap.Wrapf("error parsing enterprise config: {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return &result, nil | 	return result, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // LoadConfigDir loads all the configurations in the given directory | // LoadConfigDir loads all the configurations in the given directory | ||||||
| @@ -702,7 +484,7 @@ func LoadConfigDir(dir string) (*Config, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var result *Config | 	result := NewConfig() | ||||||
| 	for _, f := range files { | 	for _, f := range files { | ||||||
| 		config, err := LoadConfigFile(f) | 		config, err := LoadConfigFile(f) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -902,106 +684,6 @@ func parseServiceRegistration(result *Config, list *ast.ObjectList, name string) | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func parseSeals(result *Config, list *ast.ObjectList, blockName string) error { |  | ||||||
| 	if len(list.Items) > 2 { |  | ||||||
| 		return fmt.Errorf("only two or less %q blocks are permitted", blockName) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	seals := make([]*Seal, 0, len(list.Items)) |  | ||||||
| 	for _, item := range list.Items { |  | ||||||
| 		key := "seal" |  | ||||||
| 		if len(item.Keys) > 0 { |  | ||||||
| 			key = item.Keys[0].Token.Value().(string) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var m map[string]string |  | ||||||
| 		if err := hcl.DecodeObject(&m, item.Val); err != nil { |  | ||||||
| 			return multierror.Prefix(err, fmt.Sprintf("seal.%s:", key)) |  | ||||||
| 		} |  | ||||||
| 		var disabled bool |  | ||||||
| 		var err error |  | ||||||
| 		if v, ok := m["disabled"]; ok { |  | ||||||
| 			disabled, err = strconv.ParseBool(v) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) |  | ||||||
| 			} |  | ||||||
| 			delete(m, "disabled") |  | ||||||
| 		} |  | ||||||
| 		seals = append(seals, &Seal{ |  | ||||||
| 			Type:     strings.ToLower(key), |  | ||||||
| 			Disabled: disabled, |  | ||||||
| 			Config:   m, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(seals) == 2 && |  | ||||||
| 		(seals[0].Disabled && seals[1].Disabled || !seals[0].Disabled && !seals[1].Disabled) { |  | ||||||
| 		return errors.New("seals: two seals provided but both are disabled or neither are disabled") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.Seals = seals |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func parseListeners(result *Config, list *ast.ObjectList) error { |  | ||||||
| 	listeners := make([]*Listener, 0, len(list.Items)) |  | ||||||
| 	for _, item := range list.Items { |  | ||||||
| 		key := "listener" |  | ||||||
| 		if len(item.Keys) > 0 { |  | ||||||
| 			key = item.Keys[0].Token.Value().(string) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var m map[string]interface{} |  | ||||||
| 		if err := hcl.DecodeObject(&m, item.Val); err != nil { |  | ||||||
| 			return multierror.Prefix(err, fmt.Sprintf("listeners.%s:", key)) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		lnType := strings.ToLower(key) |  | ||||||
|  |  | ||||||
| 		listeners = append(listeners, &Listener{ |  | ||||||
| 			Type:   lnType, |  | ||||||
| 			Config: m, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	result.Listeners = listeners |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func parseTelemetry(result *Config, list *ast.ObjectList) error { |  | ||||||
| 	if len(list.Items) > 1 { |  | ||||||
| 		return fmt.Errorf("only one 'telemetry' block is permitted") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Get our one item |  | ||||||
| 	item := list.Items[0] |  | ||||||
|  |  | ||||||
| 	var t Telemetry |  | ||||||
| 	if err := hcl.DecodeObject(&t, item.Val); err != nil { |  | ||||||
| 		return multierror.Prefix(err, "telemetry:") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if result.Telemetry == nil { |  | ||||||
| 		result.Telemetry = &Telemetry{} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := hcl.DecodeObject(&result.Telemetry, item.Val); err != nil { |  | ||||||
| 		return multierror.Prefix(err, "telemetry:") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if result.Telemetry.PrometheusRetentionTimeRaw != nil { |  | ||||||
| 		var err error |  | ||||||
| 		if result.Telemetry.PrometheusRetentionTime, err = parseutil.ParseDurationSecond(result.Telemetry.PrometheusRetentionTimeRaw); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		result.Telemetry.PrometheusRetentionTime = prometheusDefaultRetentionTime |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sanitized returns a copy of the config with all values that are considered | // Sanitized returns a copy of the config with all values that are considered | ||||||
| // sensitive stripped. It also strips all `*Raw` values that are mainly | // sensitive stripped. It also strips all `*Raw` values that are mainly | ||||||
| // used for parsing. | // used for parsing. | ||||||
| @@ -1012,10 +694,15 @@ func parseTelemetry(result *Config, list *ast.ObjectList) error { | |||||||
| // - Seals.Config | // - Seals.Config | ||||||
| // - Telemetry.CirconusAPIToken | // - Telemetry.CirconusAPIToken | ||||||
| func (c *Config) Sanitized() map[string]interface{} { | func (c *Config) Sanitized() map[string]interface{} { | ||||||
|  | 	// Create shared config if it doesn't exist (e.g. in tests) so that map | ||||||
|  | 	// keys are actually populated | ||||||
|  | 	if c.SharedConfig == nil { | ||||||
|  | 		c.SharedConfig = new(configutil.SharedConfig) | ||||||
|  | 	} | ||||||
|  | 	sharedResult := c.SharedConfig.Sanitized() | ||||||
| 	result := map[string]interface{}{ | 	result := map[string]interface{}{ | ||||||
| 		"cache_size":              c.CacheSize, | 		"cache_size":              c.CacheSize, | ||||||
| 		"disable_cache":           c.DisableCache, | 		"disable_cache":           c.DisableCache, | ||||||
| 		"disable_mlock":           c.DisableMlock, |  | ||||||
| 		"disable_printable_check": c.DisablePrintableCheck, | 		"disable_printable_check": c.DisablePrintableCheck, | ||||||
|  |  | ||||||
| 		"enable_ui": c.EnableUI, | 		"enable_ui": c.EnableUI, | ||||||
| @@ -1023,17 +710,10 @@ func (c *Config) Sanitized() map[string]interface{} { | |||||||
| 		"max_lease_ttl":     c.MaxLeaseTTL, | 		"max_lease_ttl":     c.MaxLeaseTTL, | ||||||
| 		"default_lease_ttl": c.DefaultLeaseTTL, | 		"default_lease_ttl": c.DefaultLeaseTTL, | ||||||
|  |  | ||||||
| 		"default_max_request_duration": c.DefaultMaxRequestDuration, |  | ||||||
|  |  | ||||||
| 		"cluster_name":          c.ClusterName, |  | ||||||
| 		"cluster_cipher_suites": c.ClusterCipherSuites, | 		"cluster_cipher_suites": c.ClusterCipherSuites, | ||||||
|  |  | ||||||
| 		"plugin_directory": c.PluginDirectory, | 		"plugin_directory": c.PluginDirectory, | ||||||
|  |  | ||||||
| 		"log_level":  c.LogLevel, |  | ||||||
| 		"log_format": c.LogFormat, |  | ||||||
|  |  | ||||||
| 		"pid_file":             c.PidFile, |  | ||||||
| 		"raw_storage_endpoint": c.EnableRawEndpoint, | 		"raw_storage_endpoint": c.EnableRawEndpoint, | ||||||
|  |  | ||||||
| 		"api_addr":           c.APIAddr, | 		"api_addr":           c.APIAddr, | ||||||
| @@ -1046,18 +726,8 @@ func (c *Config) Sanitized() map[string]interface{} { | |||||||
|  |  | ||||||
| 		"disable_indexing": c.DisableIndexing, | 		"disable_indexing": c.DisableIndexing, | ||||||
| 	} | 	} | ||||||
|  | 	for k, v := range sharedResult { | ||||||
| 	// Sanitize listeners | 		result[k] = v | ||||||
| 	if len(c.Listeners) != 0 { |  | ||||||
| 		var sanitizedListeners []interface{} |  | ||||||
| 		for _, ln := range c.Listeners { |  | ||||||
| 			cleanLn := map[string]interface{}{ |  | ||||||
| 				"type":   ln.Type, |  | ||||||
| 				"config": ln.Config, |  | ||||||
| 			} |  | ||||||
| 			sanitizedListeners = append(sanitizedListeners, cleanLn) |  | ||||||
| 		} |  | ||||||
| 		result["listeners"] = sanitizedListeners |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Sanitize storage stanza | 	// Sanitize storage stanza | ||||||
| @@ -1090,49 +760,5 @@ func (c *Config) Sanitized() map[string]interface{} { | |||||||
| 		result["service_registration"] = sanitizedServiceRegistration | 		result["service_registration"] = sanitizedServiceRegistration | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Sanitize seals stanza |  | ||||||
| 	if len(c.Seals) != 0 { |  | ||||||
| 		var sanitizedSeals []interface{} |  | ||||||
| 		for _, s := range c.Seals { |  | ||||||
| 			cleanSeal := map[string]interface{}{ |  | ||||||
| 				"type":     s.Type, |  | ||||||
| 				"disabled": s.Disabled, |  | ||||||
| 			} |  | ||||||
| 			sanitizedSeals = append(sanitizedSeals, cleanSeal) |  | ||||||
| 		} |  | ||||||
| 		result["seals"] = sanitizedSeals |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Sanitize telemetry stanza |  | ||||||
| 	if c.Telemetry != nil { |  | ||||||
| 		sanitizedTelemetry := map[string]interface{}{ |  | ||||||
| 			"statsite_address":                       c.Telemetry.StatsiteAddr, |  | ||||||
| 			"statsd_address":                         c.Telemetry.StatsdAddr, |  | ||||||
| 			"disable_hostname":                       c.Telemetry.DisableHostname, |  | ||||||
| 			"metrics_prefix":                         c.Telemetry.MetricsPrefix, |  | ||||||
| 			"circonus_api_token":                     "", |  | ||||||
| 			"circonus_api_app":                       c.Telemetry.CirconusAPIApp, |  | ||||||
| 			"circonus_api_url":                       c.Telemetry.CirconusAPIURL, |  | ||||||
| 			"circonus_submission_interval":           c.Telemetry.CirconusSubmissionInterval, |  | ||||||
| 			"circonus_submission_url":                c.Telemetry.CirconusCheckSubmissionURL, |  | ||||||
| 			"circonus_check_id":                      c.Telemetry.CirconusCheckID, |  | ||||||
| 			"circonus_check_force_metric_activation": c.Telemetry.CirconusCheckForceMetricActivation, |  | ||||||
| 			"circonus_check_instance_id":             c.Telemetry.CirconusCheckInstanceID, |  | ||||||
| 			"circonus_check_search_tag":              c.Telemetry.CirconusCheckSearchTag, |  | ||||||
| 			"circonus_check_tags":                    c.Telemetry.CirconusCheckTags, |  | ||||||
| 			"circonus_check_display_name":            c.Telemetry.CirconusCheckDisplayName, |  | ||||||
| 			"circonus_broker_id":                     c.Telemetry.CirconusBrokerID, |  | ||||||
| 			"circonus_broker_select_tag":             c.Telemetry.CirconusBrokerSelectTag, |  | ||||||
| 			"dogstatsd_addr":                         c.Telemetry.DogStatsDAddr, |  | ||||||
| 			"dogstatsd_tags":                         c.Telemetry.DogStatsDTags, |  | ||||||
| 			"prometheus_retention_time":              c.Telemetry.PrometheusRetentionTime, |  | ||||||
| 			"stackdriver_project_id":                 c.Telemetry.StackdriverProjectID, |  | ||||||
| 			"stackdriver_location":                   c.Telemetry.StackdriverLocation, |  | ||||||
| 			"stackdriver_namespace":                  c.Telemetry.StackdriverNamespace, |  | ||||||
| 			"stackdriver_debug_logs":                 c.Telemetry.StackdriverDebugLogs, |  | ||||||
| 		} |  | ||||||
| 		result["telemetry"] = sanitizedTelemetry |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ package server | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -10,6 +9,7 @@ import ( | |||||||
| 	"github.com/go-test/deep" | 	"github.com/go-test/deep" | ||||||
| 	"github.com/hashicorp/hcl" | 	"github.com/hashicorp/hcl" | ||||||
| 	"github.com/hashicorp/hcl/hcl/ast" | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func testConfigRaftRetryJoin(t *testing.T) { | func testConfigRaftRetryJoin(t *testing.T) { | ||||||
| @@ -19,13 +19,14 @@ func testConfigRaftRetryJoin(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	retryJoinConfig := `[{"leader_api_addr":"http://127.0.0.1:8200"},{"leader_api_addr":"http://127.0.0.2:8200"},{"leader_api_addr":"http://127.0.0.3:8200"}]` + "\n" | 	retryJoinConfig := `[{"leader_api_addr":"http://127.0.0.1:8200"},{"leader_api_addr":"http://127.0.0.2:8200"},{"leader_api_addr":"http://127.0.0.3:8200"}]` + "\n" | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
| 				{ | 				{ | ||||||
| 					Type:    "tcp", | 					Type:    "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address: "127.0.0.1:8200", | ||||||
| 					"address": "127.0.0.1:8200", |  | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  | 			DisableMlock: true, | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		Storage: &Storage{ | 		Storage: &Storage{ | ||||||
| @@ -36,26 +37,58 @@ func testConfigRaftRetryJoin(t *testing.T) { | |||||||
| 				"retry_join": retryJoinConfig, | 				"retry_join": retryJoinConfig, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		DisableMlock:    true, |  | ||||||
| 		DisableMlockRaw: true, |  | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(config, expected) { | 	config.Listeners[0].RawConfig = nil | ||||||
| 		t.Fatalf("\nexpected: %#v\n actual:%#v\n", config, expected) | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
|  | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func testLoadConfigFile_topLevel(t *testing.T, entropy *Entropy) { | func testLoadConfigFile_topLevel(t *testing.T, entropy *configutil.Entropy) { | ||||||
| 	config, err := LoadConfigFile("./test-fixtures/config2.hcl") | 	config, err := LoadConfigFile("./test-fixtures/config2.hcl") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			&Listener{ | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
| 					Type:    "tcp", | 					Type:    "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address: "127.0.0.1:443", | ||||||
| 					"address": "127.0.0.1:443", | 				}, | ||||||
|  | 			}, | ||||||
|  |  | ||||||
|  | 			Telemetry: &configutil.Telemetry{ | ||||||
|  | 				StatsdAddr:              "bar", | ||||||
|  | 				StatsiteAddr:            "foo", | ||||||
|  | 				DisableHostname:         false, | ||||||
|  | 				DogStatsDAddr:           "127.0.0.1:7254", | ||||||
|  | 				DogStatsDTags:           []string{"tag_1:val_1", "tag_2:val_2"}, | ||||||
|  | 				PrometheusRetentionTime: 30 * time.Second, | ||||||
|  | 			}, | ||||||
|  |  | ||||||
|  | 			DisableMlock: true, | ||||||
|  |  | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  |  | ||||||
|  | 			ClusterName: "testcluster", | ||||||
|  |  | ||||||
|  | 			Seals: []*configutil.KMS{ | ||||||
|  | 				{ | ||||||
|  | 					Type: "nopurpose", | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					Type:    "stringpurpose", | ||||||
|  | 					Purpose: []string{"foo"}, | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					Type:    "commastringpurpose", | ||||||
|  | 					Purpose: []string{"foo", "bar"}, | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					Type:    "slicepurpose", | ||||||
|  | 					Purpose: []string{"zip", "zap"}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| @@ -86,20 +119,8 @@ func testLoadConfigFile_topLevel(t *testing.T, entropy *Entropy) { | |||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		Telemetry: &Telemetry{ |  | ||||||
| 			StatsdAddr:                 "bar", |  | ||||||
| 			StatsiteAddr:               "foo", |  | ||||||
| 			DisableHostname:            false, |  | ||||||
| 			DogStatsDAddr:              "127.0.0.1:7254", |  | ||||||
| 			DogStatsDTags:              []string{"tag_1:val_1", "tag_2:val_2"}, |  | ||||||
| 			PrometheusRetentionTime:    30 * time.Second, |  | ||||||
| 			PrometheusRetentionTimeRaw: "30s", |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		DisableCache:    true, | 		DisableCache:    true, | ||||||
| 		DisableCacheRaw: true, | 		DisableCacheRaw: true, | ||||||
| 		DisableMlock:    true, |  | ||||||
| 		DisableMlockRaw: true, |  | ||||||
| 		EnableUI:        true, | 		EnableUI:        true, | ||||||
| 		EnableUIRaw:     true, | 		EnableUIRaw:     true, | ||||||
|  |  | ||||||
| @@ -113,9 +134,6 @@ func testLoadConfigFile_topLevel(t *testing.T, entropy *Entropy) { | |||||||
| 		MaxLeaseTTLRaw:     "10h", | 		MaxLeaseTTLRaw:     "10h", | ||||||
| 		DefaultLeaseTTL:    10 * time.Hour, | 		DefaultLeaseTTL:    10 * time.Hour, | ||||||
| 		DefaultLeaseTTLRaw: "10h", | 		DefaultLeaseTTLRaw: "10h", | ||||||
| 		ClusterName:        "testcluster", |  | ||||||
|  |  | ||||||
| 		PidFile: "./pidfile", |  | ||||||
|  |  | ||||||
| 		APIAddr:     "top_level_api_addr", | 		APIAddr:     "top_level_api_addr", | ||||||
| 		ClusterAddr: "top_level_cluster_addr", | 		ClusterAddr: "top_level_cluster_addr", | ||||||
| @@ -123,31 +141,50 @@ func testLoadConfigFile_topLevel(t *testing.T, entropy *Entropy) { | |||||||
| 	if entropy != nil { | 	if entropy != nil { | ||||||
| 		expected.Entropy = entropy | 		expected.Entropy = entropy | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(config, expected) { | 	config.Listeners[0].RawConfig = nil | ||||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
|  | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func testLoadConfigFile_json2(t *testing.T, entropy *Entropy) { | func testLoadConfigFile_json2(t *testing.T, entropy *configutil.Entropy) { | ||||||
| 	config, err := LoadConfigFile("./test-fixtures/config2.hcl.json") | 	config, err := LoadConfigFile("./test-fixtures/config2.hcl.json") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			&Listener{ | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
| 					Type:    "tcp", | 					Type:    "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address: "127.0.0.1:443", | ||||||
| 					"address": "127.0.0.1:443", |  | ||||||
| 				}, | 				}, | ||||||
| 			}, | 				{ | ||||||
| 			&Listener{ |  | ||||||
| 					Type:    "tcp", | 					Type:    "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address: "127.0.0.1:444", | ||||||
| 					"address": "127.0.0.1:444", |  | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|  | 			Telemetry: &configutil.Telemetry{ | ||||||
|  | 				StatsiteAddr:                       "foo", | ||||||
|  | 				StatsdAddr:                         "bar", | ||||||
|  | 				DisableHostname:                    true, | ||||||
|  | 				CirconusAPIToken:                   "0", | ||||||
|  | 				CirconusAPIApp:                     "vault", | ||||||
|  | 				CirconusAPIURL:                     "http://api.circonus.com/v2", | ||||||
|  | 				CirconusSubmissionInterval:         "10s", | ||||||
|  | 				CirconusCheckSubmissionURL:         "https://someplace.com/metrics", | ||||||
|  | 				CirconusCheckID:                    "0", | ||||||
|  | 				CirconusCheckForceMetricActivation: "true", | ||||||
|  | 				CirconusCheckInstanceID:            "node1:vault", | ||||||
|  | 				CirconusCheckSearchTag:             "service:vault", | ||||||
|  | 				CirconusCheckDisplayName:           "node1:vault", | ||||||
|  | 				CirconusCheckTags:                  "cat1:tag1,cat2:tag2", | ||||||
|  | 				CirconusBrokerID:                   "0", | ||||||
|  | 				CirconusBrokerSelectTag:            "dc:sfo", | ||||||
|  | 				PrometheusRetentionTime:            30 * time.Second, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		Storage: &Storage{ | 		Storage: &Storage{ | ||||||
| @@ -182,33 +219,14 @@ func testLoadConfigFile_json2(t *testing.T, entropy *Entropy) { | |||||||
|  |  | ||||||
| 		DisableSealWrap:    true, | 		DisableSealWrap:    true, | ||||||
| 		DisableSealWrapRaw: true, | 		DisableSealWrapRaw: true, | ||||||
|  |  | ||||||
| 		Telemetry: &Telemetry{ |  | ||||||
| 			StatsiteAddr:                       "foo", |  | ||||||
| 			StatsdAddr:                         "bar", |  | ||||||
| 			DisableHostname:                    true, |  | ||||||
| 			CirconusAPIToken:                   "0", |  | ||||||
| 			CirconusAPIApp:                     "vault", |  | ||||||
| 			CirconusAPIURL:                     "http://api.circonus.com/v2", |  | ||||||
| 			CirconusSubmissionInterval:         "10s", |  | ||||||
| 			CirconusCheckSubmissionURL:         "https://someplace.com/metrics", |  | ||||||
| 			CirconusCheckID:                    "0", |  | ||||||
| 			CirconusCheckForceMetricActivation: "true", |  | ||||||
| 			CirconusCheckInstanceID:            "node1:vault", |  | ||||||
| 			CirconusCheckSearchTag:             "service:vault", |  | ||||||
| 			CirconusCheckDisplayName:           "node1:vault", |  | ||||||
| 			CirconusCheckTags:                  "cat1:tag1,cat2:tag2", |  | ||||||
| 			CirconusBrokerID:                   "0", |  | ||||||
| 			CirconusBrokerSelectTag:            "dc:sfo", |  | ||||||
| 			PrometheusRetentionTime:            30 * time.Second, |  | ||||||
| 			PrometheusRetentionTimeRaw:         "30s", |  | ||||||
| 		}, |  | ||||||
| 	} | 	} | ||||||
| 	if entropy != nil { | 	if entropy != nil { | ||||||
| 		expected.Entropy = entropy | 		expected.Entropy = entropy | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(config, expected) { | 	config.Listeners[0].RawConfig = nil | ||||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | 	config.Listeners[1].RawConfig = nil | ||||||
|  | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
|  | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -216,14 +234,14 @@ func testParseEntropy(t *testing.T, oss bool) { | |||||||
| 	var tests = []struct { | 	var tests = []struct { | ||||||
| 		inConfig   string | 		inConfig   string | ||||||
| 		outErr     error | 		outErr     error | ||||||
| 		outEntropy Entropy | 		outEntropy configutil.Entropy | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			inConfig: `entropy "seal" { | 			inConfig: `entropy "seal" { | ||||||
| 				mode = "augmentation" | 				mode = "augmentation" | ||||||
| 				}`, | 				}`, | ||||||
| 			outErr:     nil, | 			outErr:     nil, | ||||||
| 			outEntropy: Entropy{Augmentation}, | 			outEntropy: configutil.Entropy{configutil.EntropyAugmentation}, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			inConfig: `entropy "seal" { | 			inConfig: `entropy "seal" { | ||||||
| @@ -248,13 +266,15 @@ func testParseEntropy(t *testing.T, oss bool) { | |||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var config Config | 	config := Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	for _, test := range tests { | 	for _, test := range tests { | ||||||
| 		obj, _ := hcl.Parse(strings.TrimSpace(test.inConfig)) | 		obj, _ := hcl.Parse(strings.TrimSpace(test.inConfig)) | ||||||
| 		list, _ := obj.Node.(*ast.ObjectList) | 		list, _ := obj.Node.(*ast.ObjectList) | ||||||
| 		objList := list.Filter("entropy") | 		objList := list.Filter("entropy") | ||||||
| 		err := parseEntropy(&config, objList, "entropy") | 		err := configutil.ParseEntropy(config.SharedConfig, objList, "entropy") | ||||||
| 		// validate the error, both should be nil or have the same Error() | 		// validate the error, both should be nil or have the same Error() | ||||||
| 		switch { | 		switch { | ||||||
| 		case oss: | 		case oss: | ||||||
| @@ -281,13 +301,31 @@ func testLoadConfigFile(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			&Listener{ | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
| 					Type:    "tcp", | 					Type:    "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address: "127.0.0.1:443", | ||||||
| 					"address": "127.0.0.1:443", |  | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|  | 			Telemetry: &configutil.Telemetry{ | ||||||
|  | 				StatsdAddr:              "bar", | ||||||
|  | 				StatsiteAddr:            "foo", | ||||||
|  | 				DisableHostname:         false, | ||||||
|  | 				DogStatsDAddr:           "127.0.0.1:7254", | ||||||
|  | 				DogStatsDTags:           []string{"tag_1:val_1", "tag_2:val_2"}, | ||||||
|  | 				PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime, | ||||||
|  | 				MetricsPrefix:           "myprefix", | ||||||
|  | 			}, | ||||||
|  |  | ||||||
|  | 			DisableMlock: true, | ||||||
|  |  | ||||||
|  | 			Entropy: nil, | ||||||
|  |  | ||||||
|  | 			PidFile: "./pidfile", | ||||||
|  |  | ||||||
|  | 			ClusterName: "testcluster", | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		Storage: &Storage{ | 		Storage: &Storage{ | ||||||
| @@ -314,20 +352,8 @@ func testLoadConfigFile(t *testing.T) { | |||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		Telemetry: &Telemetry{ |  | ||||||
| 			StatsdAddr:              "bar", |  | ||||||
| 			StatsiteAddr:            "foo", |  | ||||||
| 			DisableHostname:         false, |  | ||||||
| 			DogStatsDAddr:           "127.0.0.1:7254", |  | ||||||
| 			DogStatsDTags:           []string{"tag_1:val_1", "tag_2:val_2"}, |  | ||||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, |  | ||||||
| 			MetricsPrefix:           "myprefix", |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		DisableCache:             true, | 		DisableCache:             true, | ||||||
| 		DisableCacheRaw:          true, | 		DisableCacheRaw:          true, | ||||||
| 		DisableMlock:             true, |  | ||||||
| 		DisableMlockRaw:          true, |  | ||||||
| 		DisablePrintableCheckRaw: true, | 		DisablePrintableCheckRaw: true, | ||||||
| 		DisablePrintableCheck:    true, | 		DisablePrintableCheck:    true, | ||||||
| 		EnableUI:                 true, | 		EnableUI:                 true, | ||||||
| @@ -339,18 +365,14 @@ func testLoadConfigFile(t *testing.T) { | |||||||
| 		DisableSealWrap:    true, | 		DisableSealWrap:    true, | ||||||
| 		DisableSealWrapRaw: true, | 		DisableSealWrapRaw: true, | ||||||
|  |  | ||||||
| 		Entropy: nil, |  | ||||||
|  |  | ||||||
| 		MaxLeaseTTL:        10 * time.Hour, | 		MaxLeaseTTL:        10 * time.Hour, | ||||||
| 		MaxLeaseTTLRaw:     "10h", | 		MaxLeaseTTLRaw:     "10h", | ||||||
| 		DefaultLeaseTTL:    10 * time.Hour, | 		DefaultLeaseTTL:    10 * time.Hour, | ||||||
| 		DefaultLeaseTTLRaw: "10h", | 		DefaultLeaseTTLRaw: "10h", | ||||||
| 		ClusterName:        "testcluster", |  | ||||||
|  |  | ||||||
| 		PidFile: "./pidfile", |  | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(config, expected) { | 	config.Listeners[0].RawConfig = nil | ||||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
|  | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -361,13 +383,37 @@ func testLoadConfigFile_json(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			&Listener{ | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
| 					Type:    "tcp", | 					Type:    "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address: "127.0.0.1:443", | ||||||
| 					"address": "127.0.0.1:443", |  | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|  | 			Telemetry: &configutil.Telemetry{ | ||||||
|  | 				StatsiteAddr:                       "baz", | ||||||
|  | 				StatsdAddr:                         "", | ||||||
|  | 				DisableHostname:                    false, | ||||||
|  | 				CirconusAPIToken:                   "", | ||||||
|  | 				CirconusAPIApp:                     "", | ||||||
|  | 				CirconusAPIURL:                     "", | ||||||
|  | 				CirconusSubmissionInterval:         "", | ||||||
|  | 				CirconusCheckSubmissionURL:         "", | ||||||
|  | 				CirconusCheckID:                    "", | ||||||
|  | 				CirconusCheckForceMetricActivation: "", | ||||||
|  | 				CirconusCheckInstanceID:            "", | ||||||
|  | 				CirconusCheckSearchTag:             "", | ||||||
|  | 				CirconusCheckDisplayName:           "", | ||||||
|  | 				CirconusCheckTags:                  "", | ||||||
|  | 				CirconusBrokerID:                   "", | ||||||
|  | 				CirconusBrokerSelectTag:            "", | ||||||
|  | 				PrometheusRetentionTime:            configutil.PrometheusDefaultRetentionTime, | ||||||
|  | 			}, | ||||||
|  |  | ||||||
|  | 			PidFile:     "./pidfile", | ||||||
|  | 			Entropy:     nil, | ||||||
|  | 			ClusterName: "testcluster", | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		Storage: &Storage{ | 		Storage: &Storage{ | ||||||
| @@ -387,44 +433,21 @@ func testLoadConfigFile_json(t *testing.T) { | |||||||
|  |  | ||||||
| 		ClusterCipherSuites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", | 		ClusterCipherSuites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", | ||||||
|  |  | ||||||
| 		Telemetry: &Telemetry{ |  | ||||||
| 			StatsiteAddr:                       "baz", |  | ||||||
| 			StatsdAddr:                         "", |  | ||||||
| 			DisableHostname:                    false, |  | ||||||
| 			CirconusAPIToken:                   "", |  | ||||||
| 			CirconusAPIApp:                     "", |  | ||||||
| 			CirconusAPIURL:                     "", |  | ||||||
| 			CirconusSubmissionInterval:         "", |  | ||||||
| 			CirconusCheckSubmissionURL:         "", |  | ||||||
| 			CirconusCheckID:                    "", |  | ||||||
| 			CirconusCheckForceMetricActivation: "", |  | ||||||
| 			CirconusCheckInstanceID:            "", |  | ||||||
| 			CirconusCheckSearchTag:             "", |  | ||||||
| 			CirconusCheckDisplayName:           "", |  | ||||||
| 			CirconusCheckTags:                  "", |  | ||||||
| 			CirconusBrokerID:                   "", |  | ||||||
| 			CirconusBrokerSelectTag:            "", |  | ||||||
| 			PrometheusRetentionTime:            prometheusDefaultRetentionTime, |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		MaxLeaseTTL:          10 * time.Hour, | 		MaxLeaseTTL:          10 * time.Hour, | ||||||
| 		MaxLeaseTTLRaw:       "10h", | 		MaxLeaseTTLRaw:       "10h", | ||||||
| 		DefaultLeaseTTL:      10 * time.Hour, | 		DefaultLeaseTTL:      10 * time.Hour, | ||||||
| 		DefaultLeaseTTLRaw:   "10h", | 		DefaultLeaseTTLRaw:   "10h", | ||||||
| 		ClusterName:          "testcluster", |  | ||||||
| 		DisableCacheRaw:      interface{}(nil), | 		DisableCacheRaw:      interface{}(nil), | ||||||
| 		DisableMlockRaw:      interface{}(nil), |  | ||||||
| 		EnableUI:             true, | 		EnableUI:             true, | ||||||
| 		EnableUIRaw:          true, | 		EnableUIRaw:          true, | ||||||
| 		PidFile:              "./pidfile", |  | ||||||
| 		EnableRawEndpoint:    true, | 		EnableRawEndpoint:    true, | ||||||
| 		EnableRawEndpointRaw: true, | 		EnableRawEndpointRaw: true, | ||||||
| 		DisableSealWrap:      true, | 		DisableSealWrap:      true, | ||||||
| 		DisableSealWrapRaw:   true, | 		DisableSealWrapRaw:   true, | ||||||
| 		Entropy:              nil, |  | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(config, expected) { | 	config.Listeners[0].RawConfig = nil | ||||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
|  | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -435,24 +458,32 @@ func testLoadConfigDir(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		DisableCache: true, | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			DisableMlock: true, | 			DisableMlock: true, | ||||||
|  |  | ||||||
|  | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
|  | 					Type:    "tcp", | ||||||
|  | 					Address: "127.0.0.1:443", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  |  | ||||||
|  | 			Telemetry: &configutil.Telemetry{ | ||||||
|  | 				StatsiteAddr:            "qux", | ||||||
|  | 				StatsdAddr:              "baz", | ||||||
|  | 				DisableHostname:         true, | ||||||
|  | 				PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime, | ||||||
|  | 			}, | ||||||
|  | 			ClusterName: "testcluster", | ||||||
|  | 		}, | ||||||
|  |  | ||||||
|  | 		DisableCache:         true, | ||||||
| 		DisableClustering:    false, | 		DisableClustering:    false, | ||||||
| 		DisableClusteringRaw: false, | 		DisableClusteringRaw: false, | ||||||
|  |  | ||||||
| 		APIAddr:     "https://vault.local", | 		APIAddr:     "https://vault.local", | ||||||
| 		ClusterAddr: "https://127.0.0.1:444", | 		ClusterAddr: "https://127.0.0.1:444", | ||||||
|  |  | ||||||
| 		Listeners: []*Listener{ |  | ||||||
| 			&Listener{ |  | ||||||
| 				Type: "tcp", |  | ||||||
| 				Config: map[string]interface{}{ |  | ||||||
| 					"address": "127.0.0.1:443", |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		Storage: &Storage{ | 		Storage: &Storage{ | ||||||
| 			Type: "consul", | 			Type: "consul", | ||||||
| 			Config: map[string]string{ | 			Config: map[string]string{ | ||||||
| @@ -467,19 +498,12 @@ func testLoadConfigDir(t *testing.T) { | |||||||
|  |  | ||||||
| 		EnableRawEndpoint: true, | 		EnableRawEndpoint: true, | ||||||
|  |  | ||||||
| 		Telemetry: &Telemetry{ |  | ||||||
| 			StatsiteAddr:            "qux", |  | ||||||
| 			StatsdAddr:              "baz", |  | ||||||
| 			DisableHostname:         true, |  | ||||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		MaxLeaseTTL:     10 * time.Hour, | 		MaxLeaseTTL:     10 * time.Hour, | ||||||
| 		DefaultLeaseTTL: 10 * time.Hour, | 		DefaultLeaseTTL: 10 * time.Hour, | ||||||
| 		ClusterName:     "testcluster", |  | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(config, expected) { | 	config.Listeners[0].RawConfig = nil | ||||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | 	if diff := deep.Equal(config, expected); diff != nil { | ||||||
|  | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -567,6 +591,7 @@ func testConfig_Sanitized(t *testing.T) { | |||||||
| 			"statsite_address":                       ""}, | 			"statsite_address":                       ""}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if diff := deep.Equal(sanitizedConfig, expected); len(diff) > 0 { | 	if diff := deep.Equal(sanitizedConfig, expected); len(diff) > 0 { | ||||||
| 		t.Fatalf("bad, diff: %#v", diff) | 		t.Fatalf("bad, diff: %#v", diff) | ||||||
| 	} | 	} | ||||||
| @@ -586,10 +611,12 @@ listener "tcp" { | |||||||
| 	tls_disable_client_certs = true | 	tls_disable_client_certs = true | ||||||
| }`)) | }`)) | ||||||
|  |  | ||||||
| 	var config Config | 	config := Config{ | ||||||
|  | 		SharedConfig: &configutil.SharedConfig{}, | ||||||
|  | 	} | ||||||
| 	list, _ := obj.Node.(*ast.ObjectList) | 	list, _ := obj.Node.(*ast.ObjectList) | ||||||
| 	objList := list.Filter("listener") | 	objList := list.Filter("listener") | ||||||
| 	parseListeners(&config, objList) | 	configutil.ParseListeners(config.SharedConfig, objList) | ||||||
| 	listeners := config.Listeners | 	listeners := config.Listeners | ||||||
| 	if len(listeners) == 0 { | 	if len(listeners) == 0 { | ||||||
| 		t.Fatalf("expected at least one listener in the config") | 		t.Fatalf("expected at least one listener in the config") | ||||||
| @@ -600,26 +627,24 @@ listener "tcp" { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expected := &Config{ | 	expected := &Config{ | ||||||
| 		Listeners: []*Listener{ | 		SharedConfig: &configutil.SharedConfig{ | ||||||
| 			&Listener{ | 			Listeners: []*configutil.Listener{ | ||||||
|  | 				{ | ||||||
| 					Type:                          "tcp", | 					Type:                          "tcp", | ||||||
| 				Config: map[string]interface{}{ | 					Address:                       "127.0.0.1:443", | ||||||
| 					"address":                            "127.0.0.1:443", | 					ClusterAddress:                "127.0.0.1:8201", | ||||||
| 					"cluster_address":                    "127.0.0.1:8201", | 					TLSCertFile:                   "./certs/server.crt", | ||||||
| 					"tls_disable":                        false, | 					TLSKeyFile:                    "./certs/server.key", | ||||||
| 					"tls_cert_file":                      "./certs/server.crt", | 					TLSClientCAFile:               "./certs/rootca.crt", | ||||||
| 					"tls_key_file":                       "./certs/server.key", | 					TLSMinVersion:                 "tls12", | ||||||
| 					"tls_client_ca_file":                 "./certs/rootca.crt", | 					TLSRequireAndVerifyClientCert: true, | ||||||
| 					"tls_min_version":                    "tls12", | 					TLSDisableClientCerts:         true, | ||||||
| 					"tls_require_and_verify_client_cert": true, |  | ||||||
| 					"tls_disable_client_certs":           true, |  | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  | 	config.Listeners[0].RawConfig = nil | ||||||
| 	if !reflect.DeepEqual(config, *expected) { | 	if diff := deep.Equal(config, *expected); diff != nil { | ||||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, *expected) | 		t.Fatal(diff) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,7 +12,3 @@ type entConfig struct { | |||||||
| func (ec *entConfig) parseConfig(list *ast.ObjectList) error { | func (ec *entConfig) parseConfig(list *ast.ObjectList) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func parseEntropy(result *Config, list *ast.ObjectList, blockName string) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -10,12 +10,13 @@ import ( | |||||||
| 	"net" | 	"net" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/helper/proxyutil" | 	"github.com/hashicorp/vault/helper/proxyutil" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/reloadutil" | 	"github.com/hashicorp/vault/internalshared/reloadutil" | ||||||
| 	"github.com/mitchellh/cli" | 	"github.com/mitchellh/cli" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ListenerFactory is the factory function to create a listener. | // ListenerFactory is the factory function to create a listener. | ||||||
| type ListenerFactory func(map[string]interface{}, io.Writer, cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, error) | type ListenerFactory func(*configutil.Listener, io.Writer, cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, error) | ||||||
|  |  | ||||||
| // BuiltinListeners is the list of built-in listener types. | // BuiltinListeners is the list of built-in listener types. | ||||||
| var BuiltinListeners = map[string]ListenerFactory{ | var BuiltinListeners = map[string]ListenerFactory{ | ||||||
| @@ -24,39 +25,24 @@ var BuiltinListeners = map[string]ListenerFactory{ | |||||||
|  |  | ||||||
| // NewListener creates a new listener of the given type with the given | // NewListener creates a new listener of the given type with the given | ||||||
| // configuration. The type is looked up in the BuiltinListeners map. | // configuration. The type is looked up in the BuiltinListeners map. | ||||||
| func NewListener(t string, config map[string]interface{}, logger io.Writer, ui cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, error) { | func NewListener(l *configutil.Listener, logger io.Writer, ui cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, error) { | ||||||
| 	f, ok := BuiltinListeners[t] | 	f, ok := BuiltinListeners[l.Type] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, nil, nil, fmt.Errorf("unknown listener type: %q", t) | 		return nil, nil, nil, fmt.Errorf("unknown listener type: %q", l.Type) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return f(config, logger, ui) | 	return f(l, logger, ui) | ||||||
| } | } | ||||||
|  |  | ||||||
| func listenerWrapProxy(ln net.Listener, config map[string]interface{}) (net.Listener, error) { | func listenerWrapProxy(ln net.Listener, l *configutil.Listener) (net.Listener, error) { | ||||||
| 	behaviorRaw, ok := config["proxy_protocol_behavior"] | 	behavior := l.ProxyProtocolBehavior | ||||||
| 	if !ok { | 	if behavior == "" { | ||||||
| 		return ln, nil | 		return ln, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	behavior, ok := behaviorRaw.(string) |  | ||||||
| 	if !ok { |  | ||||||
| 		return nil, fmt.Errorf("failed parsing proxy_protocol_behavior value: not a string") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	proxyProtoConfig := &proxyutil.ProxyProtoConfig{ | 	proxyProtoConfig := &proxyutil.ProxyProtoConfig{ | ||||||
| 		Behavior:        behavior, | 		Behavior:        behavior, | ||||||
| 	} | 		AuthorizedAddrs: l.ProxyProtocolAuthorizedAddrs, | ||||||
|  |  | ||||||
| 	if proxyProtoConfig.Behavior == "allow_authorized" || proxyProtoConfig.Behavior == "deny_unauthorized" { |  | ||||||
| 		authorizedAddrsRaw, ok := config["proxy_protocol_authorized_addrs"] |  | ||||||
| 		if !ok { |  | ||||||
| 			return nil, fmt.Errorf("proxy_protocol_behavior set but no proxy_protocol_authorized_addrs value") |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if err := proxyProtoConfig.SetAuthorizedAddrs(authorizedAddrsRaw); err != nil { |  | ||||||
| 			return nil, errwrap.Wrapf("failed parsing proxy_protocol_authorized_addrs: {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newLn, err := proxyutil.WrapInProxyProto(ln, proxyProtoConfig) | 	newLn, err := proxyutil.WrapInProxyProto(ln, proxyProtoConfig) | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"crypto/tls" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net" | 	"net" | ||||||
| @@ -8,23 +9,19 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/listenerutil" | 	"github.com/hashicorp/vault/internalshared/listenerutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/reloadutil" | 	"github.com/hashicorp/vault/internalshared/reloadutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/parseutil" |  | ||||||
| 	"github.com/mitchellh/cli" | 	"github.com/mitchellh/cli" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func tcpListenerFactory(config map[string]interface{}, _ io.Writer, ui cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, error) { | func tcpListenerFactory(l *configutil.Listener, _ io.Writer, ui cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, error) { | ||||||
| 	bindProto := "tcp" | 	addr := l.Address | ||||||
| 	var addr string | 	if addr == "" { | ||||||
| 	addrRaw, ok := config["address"] |  | ||||||
| 	if !ok { |  | ||||||
| 		addr = "127.0.0.1:8200" | 		addr = "127.0.0.1:8200" | ||||||
| 	} else { |  | ||||||
| 		addr = addrRaw.(string) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	bindProto := "tcp" | ||||||
| 	// If they've passed 0.0.0.0, we only want to bind on IPv4 | 	// If they've passed 0.0.0.0, we only want to bind on IPv4 | ||||||
| 	// rather than golang's dual stack default | 	// rather than golang's dual stack default | ||||||
| 	if strings.HasPrefix(addr, "0.0.0.0:") { | 	if strings.HasPrefix(addr, "0.0.0.0:") { | ||||||
| @@ -38,67 +35,41 @@ func tcpListenerFactory(config map[string]interface{}, _ io.Writer, ui cli.Ui) ( | |||||||
|  |  | ||||||
| 	ln = TCPKeepAliveListener{ln.(*net.TCPListener)} | 	ln = TCPKeepAliveListener{ln.(*net.TCPListener)} | ||||||
|  |  | ||||||
| 	ln, err = listenerWrapProxy(ln, config) | 	ln, err = listenerWrapProxy(ln, l) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, nil, nil, err | 		return nil, nil, nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	props := map[string]string{"addr": addr} | 	props := map[string]string{"addr": addr} | ||||||
|  |  | ||||||
| 	ffAllowedRaw, ffAllowedOK := config["x_forwarded_for_authorized_addrs"] | 	// X-Forwarded-For props | ||||||
| 	if ffAllowedOK { | 	{ | ||||||
| 		ffAllowed, err := parseutil.ParseAddrs(ffAllowedRaw) | 		if len(l.XForwardedForAuthorizedAddrs) > 0 { | ||||||
| 		if err != nil { | 			props["x_forwarded_for_authorized_addrs"] = fmt.Sprintf("%v", l.XForwardedForAuthorizedAddrs) | ||||||
| 			return nil, nil, nil, errwrap.Wrapf("error parsing \"x_forwarded_for_authorized_addrs\": {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		props["x_forwarded_for_authorized_addrs"] = fmt.Sprintf("%v", ffAllowed) |  | ||||||
| 		config["x_forwarded_for_authorized_addrs"] = ffAllowed |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	if ffHopsRaw, ok := config["x_forwarded_for_hop_skips"]; ok { | 		if l.XForwardedForHopSkips > 0 { | ||||||
| 		ffHops64, err := parseutil.ParseInt(ffHopsRaw) | 			props["x_forwarded_for_hop_skips"] = fmt.Sprintf("%d", l.XForwardedForHopSkips) | ||||||
| 		if err != nil { | 		} else if len(l.XForwardedForAuthorizedAddrs) > 0 { | ||||||
| 			return nil, nil, nil, errwrap.Wrapf("error parsing \"x_forwarded_for_hop_skips\": {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		if ffHops64 < 0 { |  | ||||||
| 			return nil, nil, nil, fmt.Errorf("\"x_forwarded_for_hop_skips\" cannot be negative") |  | ||||||
| 		} |  | ||||||
| 		ffHops := int(ffHops64) |  | ||||||
| 		props["x_forwarded_for_hop_skips"] = strconv.Itoa(ffHops) |  | ||||||
| 		config["x_forwarded_for_hop_skips"] = ffHops |  | ||||||
| 	} else if ffAllowedOK { |  | ||||||
| 			props["x_forwarded_for_hop_skips"] = "0" | 			props["x_forwarded_for_hop_skips"] = "0" | ||||||
| 		config["x_forwarded_for_hop_skips"] = int(0) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	if ffRejectNotPresentRaw, ok := config["x_forwarded_for_reject_not_present"]; ok { | 		if len(l.XForwardedForAuthorizedAddrs) > 0 { | ||||||
| 		ffRejectNotPresent, err := parseutil.ParseBool(ffRejectNotPresentRaw) | 			props["x_forwarded_for_reject_not_present"] = strconv.FormatBool(l.XForwardedForRejectNotPresent) | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, nil, errwrap.Wrapf("error parsing \"x_forwarded_for_reject_not_present\": {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		props["x_forwarded_for_reject_not_present"] = strconv.FormatBool(ffRejectNotPresent) |  | ||||||
| 		config["x_forwarded_for_reject_not_present"] = ffRejectNotPresent |  | ||||||
| 	} else if ffAllowedOK { |  | ||||||
| 		props["x_forwarded_for_reject_not_present"] = "true" |  | ||||||
| 		config["x_forwarded_for_reject_not_present"] = true |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	if ffRejectNonAuthorizedRaw, ok := config["x_forwarded_for_reject_not_authorized"]; ok { | 		if len(l.XForwardedForAuthorizedAddrs) > 0 { | ||||||
| 		ffRejectNonAuthorized, err := parseutil.ParseBool(ffRejectNonAuthorizedRaw) | 			props["x_forwarded_for_reject_not_authorized"] = strconv.FormatBool(l.XForwardedForRejectNotAuthorized) | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, nil, errwrap.Wrapf("error parsing \"x_forwarded_for_reject_not_authorized\": {{err}}", err) |  | ||||||
| 		} | 		} | ||||||
| 		props["x_forwarded_for_reject_not_authorized"] = strconv.FormatBool(ffRejectNonAuthorized) |  | ||||||
| 		config["x_forwarded_for_reject_not_authorized"] = ffRejectNonAuthorized |  | ||||||
| 	} else if ffAllowedOK { |  | ||||||
| 		props["x_forwarded_for_reject_not_authorized"] = "true" |  | ||||||
| 		config["x_forwarded_for_reject_not_authorized"] = true |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ln, props, reloadFunc, _, err := listenerutil.WrapTLS(ln, props, config, ui) | 	tlsConfig, reloadFunc, err := listenerutil.TLSConfig(l, props, ui) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, nil, nil, err | 		return nil, nil, nil, err | ||||||
| 	} | 	} | ||||||
|  | 	if tlsConfig != nil { | ||||||
|  | 		ln = tls.NewListener(ln, tlsConfig) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return ln, props, reloadFunc, nil | 	return ln, props, reloadFunc, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,13 +11,14 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/mitchellh/cli" | 	"github.com/mitchellh/cli" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestTCPListener(t *testing.T) { | func TestTCPListener(t *testing.T) { | ||||||
| 	ln, _, _, err := tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err := tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":     "127.0.0.1:0", | 		Address:    "127.0.0.1:0", | ||||||
| 		"tls_disable": "1", | 		TLSDisable: true, | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| @@ -49,12 +50,12 @@ func TestTCPListener_tls(t *testing.T) { | |||||||
| 		t.Fatal("not ok when appending CA cert") | 		t.Fatal("not ok when appending CA cert") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ln, _, _, err := tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err := tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":                            "127.0.0.1:0", | 		Address:                       "127.0.0.1:0", | ||||||
| 		"tls_cert_file":                      wd + "reload_foo.pem", | 		TLSCertFile:                   wd + "reload_foo.pem", | ||||||
| 		"tls_key_file":                       wd + "reload_foo.key", | 		TLSKeyFile:                    wd + "reload_foo.key", | ||||||
| 		"tls_require_and_verify_client_cert": "true", | 		TLSRequireAndVerifyClientCert: true, | ||||||
| 		"tls_client_ca_file":                 wd + "reload_ca.pem", | 		TLSClientCAFile:               wd + "reload_ca.pem", | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| @@ -87,24 +88,24 @@ func TestTCPListener_tls(t *testing.T) { | |||||||
|  |  | ||||||
| 	testListenerImpl(t, ln, connFn(true), "foo.example.com") | 	testListenerImpl(t, ln, connFn(true), "foo.example.com") | ||||||
|  |  | ||||||
| 	ln, _, _, err = tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err = tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":                            "127.0.0.1:0", | 		Address:                       "127.0.0.1:0", | ||||||
| 		"tls_cert_file":                      wd + "reload_foo.pem", | 		TLSCertFile:                   wd + "reload_foo.pem", | ||||||
| 		"tls_key_file":                       wd + "reload_foo.key", | 		TLSKeyFile:                    wd + "reload_foo.key", | ||||||
| 		"tls_require_and_verify_client_cert": "true", | 		TLSRequireAndVerifyClientCert: true, | ||||||
| 		"tls_disable_client_certs":           "true", | 		TLSDisableClientCerts:         true, | ||||||
| 		"tls_client_ca_file":                 wd + "reload_ca.pem", | 		TLSClientCAFile:               wd + "reload_ca.pem", | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatal("expected error due to mutually exclusive client cert options") | 		t.Fatal("expected error due to mutually exclusive client cert options") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ln, _, _, err = tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err = tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":                  "127.0.0.1:0", | 		Address:               "127.0.0.1:0", | ||||||
| 		"tls_cert_file":            wd + "reload_foo.pem", | 		TLSCertFile:           wd + "reload_foo.pem", | ||||||
| 		"tls_key_file":             wd + "reload_foo.key", | 		TLSKeyFile:            wd + "reload_foo.key", | ||||||
| 		"tls_disable_client_certs": "true", | 		TLSDisableClientCerts: true, | ||||||
| 		"tls_client_ca_file":       wd + "reload_ca.pem", | 		TLSClientCAFile:       wd + "reload_ca.pem", | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| @@ -131,13 +132,13 @@ func TestTCPListener_tls13(t *testing.T) { | |||||||
| 		t.Fatal("not ok when appending CA cert") | 		t.Fatal("not ok when appending CA cert") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ln, _, _, err := tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err := tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":                            "127.0.0.1:0", | 		Address:                       "127.0.0.1:0", | ||||||
| 		"tls_cert_file":                      wd + "reload_foo.pem", | 		TLSCertFile:                   wd + "reload_foo.pem", | ||||||
| 		"tls_key_file":                       wd + "reload_foo.key", | 		TLSKeyFile:                    wd + "reload_foo.key", | ||||||
| 		"tls_require_and_verify_client_cert": "true", | 		TLSRequireAndVerifyClientCert: true, | ||||||
| 		"tls_client_ca_file":                 wd + "reload_ca.pem", | 		TLSClientCAFile:               wd + "reload_ca.pem", | ||||||
| 		"tls_min_version":                    "tls13", | 		TLSMinVersion:                 "tls13", | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| @@ -170,26 +171,26 @@ func TestTCPListener_tls13(t *testing.T) { | |||||||
|  |  | ||||||
| 	testListenerImpl(t, ln, connFn(true), "foo.example.com") | 	testListenerImpl(t, ln, connFn(true), "foo.example.com") | ||||||
|  |  | ||||||
| 	ln, _, _, err = tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err = tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":                            "127.0.0.1:0", | 		Address:                       "127.0.0.1:0", | ||||||
| 		"tls_cert_file":                      wd + "reload_foo.pem", | 		TLSCertFile:                   wd + "reload_foo.pem", | ||||||
| 		"tls_key_file":                       wd + "reload_foo.key", | 		TLSKeyFile:                    wd + "reload_foo.key", | ||||||
| 		"tls_require_and_verify_client_cert": "true", | 		TLSRequireAndVerifyClientCert: true, | ||||||
| 		"tls_disable_client_certs":           "true", | 		TLSDisableClientCerts:         true, | ||||||
| 		"tls_client_ca_file":                 wd + "reload_ca.pem", | 		TLSClientCAFile:               wd + "reload_ca.pem", | ||||||
| 		"tls_min_version":                    "tls13", | 		TLSMinVersion:                 "tls13", | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatal("expected error due to mutually exclusive client cert options") | 		t.Fatal("expected error due to mutually exclusive client cert options") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ln, _, _, err = tcpListenerFactory(map[string]interface{}{ | 	ln, _, _, err = tcpListenerFactory(&configutil.Listener{ | ||||||
| 		"address":                  "127.0.0.1:0", | 		Address:               "127.0.0.1:0", | ||||||
| 		"tls_cert_file":            wd + "reload_foo.pem", | 		TLSCertFile:           wd + "reload_foo.pem", | ||||||
| 		"tls_key_file":             wd + "reload_foo.key", | 		TLSKeyFile:            wd + "reload_foo.key", | ||||||
| 		"tls_disable_client_certs": "true", | 		TLSDisableClientCerts: true, | ||||||
| 		"tls_client_ca_file":       wd + "reload_ca.pem", | 		TLSClientCAFile:       wd + "reload_ca.pem", | ||||||
| 		"tls_min_version":          "tls13", | 		TLSMinVersion:         "tls13", | ||||||
| 	}, nil, cli.NewMockUi()) | 	}, nil, cli.NewMockUi()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
|   | |||||||
| @@ -1,45 +0,0 @@ | |||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/go-hclog" |  | ||||||
| 	wrapping "github.com/hashicorp/go-kms-wrapping" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	ConfigureSeal = configureSeal |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func configureSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger hclog.Logger, inseal vault.Seal) (outseal vault.Seal, err error) { |  | ||||||
| 	switch configSeal.Type { |  | ||||||
| 	case wrapping.AliCloudKMS: |  | ||||||
| 		return configureAliCloudKMSSeal(configSeal, infoKeys, info, logger, inseal) |  | ||||||
|  |  | ||||||
| 	case wrapping.AWSKMS: |  | ||||||
| 		return configureAWSKMSSeal(configSeal, infoKeys, info, logger, inseal) |  | ||||||
|  |  | ||||||
| 	case wrapping.AzureKeyVault: |  | ||||||
| 		return configureAzureKeyVaultSeal(configSeal, infoKeys, info, logger, inseal) |  | ||||||
|  |  | ||||||
| 	case wrapping.GCPCKMS: |  | ||||||
| 		return configureGCPCKMSSeal(configSeal, infoKeys, info, logger, inseal) |  | ||||||
|  |  | ||||||
| 	case wrapping.OCIKMS: |  | ||||||
| 		return configureOCIKMSSeal(configSeal, infoKeys, info, logger, inseal) |  | ||||||
|  |  | ||||||
| 	case wrapping.Transit: |  | ||||||
| 		return configureTransitSeal(configSeal, infoKeys, info, logger, inseal) |  | ||||||
|  |  | ||||||
| 	case wrapping.PKCS11: |  | ||||||
| 		return nil, fmt.Errorf("Seal type 'pkcs11' requires the Vault Enterprise HSM binary") |  | ||||||
|  |  | ||||||
| 	case wrapping.Shamir: |  | ||||||
| 		return inseal, nil |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 		return nil, fmt.Errorf("Unknown seal type %q", configSeal.Type) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -1,36 +0,0 @@ | |||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/hashicorp/errwrap" |  | ||||||
| 	log "github.com/hashicorp/go-hclog" |  | ||||||
| 	"github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| 	"github.com/hashicorp/vault/vault/seal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func configureAliCloudKMSSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger log.Logger, inseal vault.Seal) (vault.Seal, error) { |  | ||||||
| 	kms := alicloudkms.NewWrapper(nil) |  | ||||||
| 	kmsInfo, err := kms.SetConfig(configSeal.Config) |  | ||||||
| 	if err != nil { |  | ||||||
| 		// If the error is any other than logical.KeyNotFoundError, return the error |  | ||||||
| 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	autoseal := vault.NewAutoSeal(&seal.Access{ |  | ||||||
| 		Wrapper: kms, |  | ||||||
| 	}) |  | ||||||
| 	if kmsInfo != nil { |  | ||||||
| 		*infoKeys = append(*infoKeys, "Seal Type", "AliCloud KMS Region", "AliCloud KMS KeyID") |  | ||||||
| 		(*info)["Seal Type"] = configSeal.Type |  | ||||||
| 		(*info)["AliCloud KMS Region"] = kmsInfo["region"] |  | ||||||
| 		(*info)["AliCloud KMS KeyID"] = kmsInfo["kms_key_id"] |  | ||||||
| 		if domain, ok := kmsInfo["domain"]; ok { |  | ||||||
| 			*infoKeys = append(*infoKeys, "AliCloud KMS Domain") |  | ||||||
| 			(*info)["AliCloud KMS Domain"] = domain |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return autoseal, nil |  | ||||||
| } |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/hashicorp/errwrap" |  | ||||||
| 	"github.com/hashicorp/go-hclog" |  | ||||||
| 	wrapping "github.com/hashicorp/go-kms-wrapping" |  | ||||||
| 	"github.com/hashicorp/go-kms-wrapping/wrappers/awskms" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| 	"github.com/hashicorp/vault/vault/seal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var getAWSKMSFunc = func(opts *wrapping.WrapperOptions, config map[string]string) (wrapping.Wrapper, map[string]string, error) { |  | ||||||
| 	kms := awskms.NewWrapper(nil) |  | ||||||
| 	kmsInfo, err := kms.SetConfig(config) |  | ||||||
| 	return kms, kmsInfo, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func configureAWSKMSSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger hclog.Logger, inseal vault.Seal) (vault.Seal, error) { |  | ||||||
| 	kms, kmsInfo, err := getAWSKMSFunc(nil, configSeal.Config) |  | ||||||
| 	if err != nil { |  | ||||||
| 		// If the error is any other than logical.KeyNotFoundError, return the error |  | ||||||
| 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	autoseal := vault.NewAutoSeal(&seal.Access{ |  | ||||||
| 		Wrapper: kms, |  | ||||||
| 	}) |  | ||||||
| 	if kmsInfo != nil { |  | ||||||
| 		*infoKeys = append(*infoKeys, "Seal Type", "AWS KMS Region", "AWS KMS KeyID") |  | ||||||
| 		(*info)["Seal Type"] = configSeal.Type |  | ||||||
| 		(*info)["AWS KMS Region"] = kmsInfo["region"] |  | ||||||
| 		(*info)["AWS KMS KeyID"] = kmsInfo["kms_key_id"] |  | ||||||
| 		if endpoint, ok := kmsInfo["endpoint"]; ok { |  | ||||||
| 			*infoKeys = append(*infoKeys, "AWS KMS Endpoint") |  | ||||||
| 			(*info)["AWS KMS Endpoint"] = endpoint |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return autoseal, nil |  | ||||||
| } |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/hashicorp/errwrap" |  | ||||||
| 	log "github.com/hashicorp/go-hclog" |  | ||||||
| 	"github.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| 	"github.com/hashicorp/vault/vault/seal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func configureAzureKeyVaultSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger log.Logger, inseal vault.Seal) (vault.Seal, error) { |  | ||||||
| 	kv := azurekeyvault.NewWrapper(nil) |  | ||||||
| 	kvInfo, err := kv.SetConfig(configSeal.Config) |  | ||||||
| 	if err != nil { |  | ||||||
| 		// If the error is any other than logical.KeyNotFoundError, return the error |  | ||||||
| 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	autoseal := vault.NewAutoSeal(&seal.Access{ |  | ||||||
| 		Wrapper: kv, |  | ||||||
| 	}) |  | ||||||
| 	if kvInfo != nil { |  | ||||||
| 		*infoKeys = append(*infoKeys, "Seal Type", "Azure Environment", "Azure Vault Name", "Azure Key Name") |  | ||||||
| 		(*info)["Seal Type"] = configSeal.Type |  | ||||||
| 		(*info)["Azure Environment"] = kvInfo["environment"] |  | ||||||
| 		(*info)["Azure Vault Name"] = kvInfo["vault_name"] |  | ||||||
| 		(*info)["Azure Key Name"] = kvInfo["key_name"] |  | ||||||
| 	} |  | ||||||
| 	return autoseal, nil |  | ||||||
| } |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/hashicorp/errwrap" |  | ||||||
| 	log "github.com/hashicorp/go-hclog" |  | ||||||
| 	"github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/useragent" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| 	"github.com/hashicorp/vault/vault/seal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func configureGCPCKMSSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger log.Logger, inseal vault.Seal) (vault.Seal, error) { |  | ||||||
| 	// The config map can be nil if all other seal params were provided via env |  | ||||||
| 	// vars so we nil check here before setting user_agent down below. |  | ||||||
| 	if configSeal.Config == nil { |  | ||||||
| 		configSeal.Config = map[string]string{} |  | ||||||
| 	} |  | ||||||
| 	// This is not exposed at the moment so we always override user_agent |  | ||||||
| 	// with Vault's internal value. |  | ||||||
| 	configSeal.Config["user_agent"] = useragent.String() |  | ||||||
|  |  | ||||||
| 	kms := gcpckms.NewWrapper(nil) |  | ||||||
| 	kmsInfo, err := kms.SetConfig(configSeal.Config) |  | ||||||
| 	if err != nil { |  | ||||||
| 		// If the error is any other than logical.KeyNotFoundError, return the error |  | ||||||
| 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	autoseal := vault.NewAutoSeal(&seal.Access{ |  | ||||||
| 		Wrapper: kms, |  | ||||||
| 	}) |  | ||||||
| 	if kmsInfo != nil { |  | ||||||
| 		*infoKeys = append(*infoKeys, "Seal Type", "GCP KMS Project", "GCP KMS Region", "GCP KMS Key Ring", "GCP KMS Crypto Key") |  | ||||||
| 		(*info)["Seal Type"] = configSeal.Type |  | ||||||
| 		(*info)["GCP KMS Project"] = kmsInfo["project"] |  | ||||||
| 		(*info)["GCP KMS Region"] = kmsInfo["region"] |  | ||||||
| 		(*info)["GCP KMS Key Ring"] = kmsInfo["key_ring"] |  | ||||||
| 		(*info)["GCP KMS Crypto Key"] = kmsInfo["crypto_key"] |  | ||||||
| 	} |  | ||||||
| 	return autoseal, nil |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| // Copyright © 2019, Oracle and/or its affiliates. |  | ||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	log "github.com/hashicorp/go-hclog" |  | ||||||
| 	"github.com/hashicorp/go-kms-wrapping/wrappers/ocikms" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| 	"github.com/hashicorp/vault/vault/seal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func configureOCIKMSSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger log.Logger, inseal vault.Seal) (vault.Seal, error) { |  | ||||||
| 	kms := ocikms.NewWrapper(nil) |  | ||||||
| 	kmsInfo, err := kms.SetConfig(configSeal.Config) |  | ||||||
| 	if err != nil { |  | ||||||
| 		logger.Error("error on setting up config for OCI KMS", "error", err) |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	autoseal := vault.NewAutoSeal(&seal.Access{ |  | ||||||
| 		Wrapper: kms, |  | ||||||
| 	}) |  | ||||||
| 	if kmsInfo != nil { |  | ||||||
| 		*infoKeys = append(*infoKeys, "Seal Type", "OCI KMS KeyID") |  | ||||||
| 		(*info)["Seal Type"] = configSeal.Type |  | ||||||
| 		(*info)["OCI KMS KeyID"] = kmsInfo[ocikms.KMSConfigKeyID] |  | ||||||
| 		(*info)["OCI KMS Crypto Endpoint"] = kmsInfo[ocikms.KMSConfigCryptoEndpoint] |  | ||||||
| 		(*info)["OCI KMS Management Endpoint"] = kmsInfo[ocikms.KMSConfigManagementEndpoint] |  | ||||||
| 		(*info)["OCI KMS Principal Type"] = kmsInfo["principal_type"] |  | ||||||
| 	} |  | ||||||
| 	return autoseal, nil |  | ||||||
| } |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| package seal |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/hashicorp/errwrap" |  | ||||||
| 	log "github.com/hashicorp/go-hclog" |  | ||||||
| 	wrapping "github.com/hashicorp/go-kms-wrapping" |  | ||||||
| 	"github.com/hashicorp/go-kms-wrapping/wrappers/transit" |  | ||||||
| 	"github.com/hashicorp/vault/command/server" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" |  | ||||||
| 	"github.com/hashicorp/vault/vault" |  | ||||||
| 	"github.com/hashicorp/vault/vault/seal" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var GetTransitKMSFunc = func(opts *wrapping.WrapperOptions, config map[string]string) (wrapping.Wrapper, map[string]string, error) { |  | ||||||
| 	transitSeal := transit.NewWrapper(opts) |  | ||||||
| 	sealInfo, err := transitSeal.SetConfig(config) |  | ||||||
| 	return transitSeal, sealInfo, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func configureTransitSeal(configSeal *server.Seal, infoKeys *[]string, info *map[string]string, logger log.Logger, inseal vault.Seal) (vault.Seal, error) { |  | ||||||
| 	transitSeal, sealInfo, err := GetTransitKMSFunc( |  | ||||||
| 		&wrapping.WrapperOptions{ |  | ||||||
| 			Logger: logger.ResetNamed("seal-transit"), |  | ||||||
| 		}, configSeal.Config) |  | ||||||
| 	if err != nil { |  | ||||||
| 		// If the error is any other than logical.KeyNotFoundError, return the error |  | ||||||
| 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	autoseal := vault.NewAutoSeal(&seal.Access{ |  | ||||||
| 		Wrapper: transitSeal, |  | ||||||
| 	}) |  | ||||||
| 	if sealInfo != nil { |  | ||||||
| 		*infoKeys = append(*infoKeys, "Seal Type", "Transit Address", "Transit Mount Path", "Transit Key Name") |  | ||||||
| 		(*info)["Seal Type"] = configSeal.Type |  | ||||||
| 		(*info)["Transit Address"] = sealInfo["address"] |  | ||||||
| 		(*info)["Transit Mount Path"] = sealInfo["mount_path"] |  | ||||||
| 		(*info)["Transit Key Name"] = sealInfo["key_name"] |  | ||||||
| 		if namespace, ok := sealInfo["namespace"]; ok { |  | ||||||
| 			*infoKeys = append(*infoKeys, "Transit Namespace") |  | ||||||
| 			(*info)["Transit Namespace"] = namespace |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return autoseal, nil |  | ||||||
| } |  | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package seal_test | package server | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -11,7 +11,7 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/hashicorp/go-uuid" | 	"github.com/hashicorp/go-uuid" | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
| 	"github.com/hashicorp/vault/command/server/seal" | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/ory/dockertest" | 	"github.com/ory/dockertest" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @@ -26,19 +26,19 @@ func TestTransitWrapper_Lifecycle(t *testing.T) { | |||||||
| 		"key_name":   keyName, | 		"key_name":   keyName, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	s, _, err := seal.GetTransitKMSFunc(nil, wrapperConfig) | 	kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("error setting wrapper config: %v", err) | 		t.Fatalf("error setting wrapper config: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Test Encrypt and Decrypt calls | 	// Test Encrypt and Decrypt calls | ||||||
| 	input := []byte("foo") | 	input := []byte("foo") | ||||||
| 	swi, err := s.Encrypt(context.Background(), input, nil) | 	swi, err := kms.Encrypt(context.Background(), input, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err.Error()) | 		t.Fatalf("err: %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	pt, err := s.Decrypt(context.Background(), swi, nil) | 	pt, err := kms.Decrypt(context.Background(), swi, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err.Error()) | 		t.Fatalf("err: %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| @@ -79,7 +79,7 @@ func TestTransitSeal_TokenRenewal(t *testing.T) { | |||||||
| 		"mount_path": mountPath, | 		"mount_path": mountPath, | ||||||
| 		"key_name":   keyName, | 		"key_name":   keyName, | ||||||
| 	} | 	} | ||||||
| 	s, _, err := seal.GetTransitKMSFunc(nil, wrapperConfig) | 	kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("error setting wrapper config: %v", err) | 		t.Fatalf("error setting wrapper config: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -88,12 +88,12 @@ func TestTransitSeal_TokenRenewal(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	// Test Encrypt and Decrypt calls | 	// Test Encrypt and Decrypt calls | ||||||
| 	input := []byte("foo") | 	input := []byte("foo") | ||||||
| 	swi, err := s.Encrypt(context.Background(), input, nil) | 	swi, err := kms.Encrypt(context.Background(), input, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err.Error()) | 		t.Fatalf("err: %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	pt, err := s.Decrypt(context.Background(), swi, nil) | 	pt, err := kms.Decrypt(context.Background(), swi, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("err: %s", err.Error()) | 		t.Fatalf("err: %s", err.Error()) | ||||||
| 	} | 	} | ||||||
| @@ -5,6 +5,7 @@ ui = true | |||||||
|  |  | ||||||
| listener "tcp" { | listener "tcp" { | ||||||
|     address = "127.0.0.1:443" |     address = "127.0.0.1:443" | ||||||
|  | 	allow_stuff = true | ||||||
| } | } | ||||||
|  |  | ||||||
| backend "consul" { | backend "consul" { | ||||||
|   | |||||||
| @@ -37,6 +37,18 @@ entropy "seal" { | |||||||
|     mode = "augmentation" |     mode = "augmentation" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | kms "commastringpurpose" { | ||||||
|  |     purpose = "foo,bar" | ||||||
|  | } | ||||||
|  | kms "slicepurpose" { | ||||||
|  |     purpose = ["zip", "zap"] | ||||||
|  | } | ||||||
|  | seal "nopurpose" { | ||||||
|  | } | ||||||
|  | seal "stringpurpose" { | ||||||
|  |     purpose = "foo" | ||||||
|  | } | ||||||
|  |  | ||||||
| max_lease_ttl = "10h" | max_lease_ttl = "10h" | ||||||
| default_lease_ttl = "10h" | default_lease_ttl = "10h" | ||||||
| cluster_name = "testcluster" | cluster_name = "testcluster" | ||||||
|   | |||||||
| @@ -230,28 +230,28 @@ func TestServer(t *testing.T) { | |||||||
| 		{ | 		{ | ||||||
| 			"bad_listener_read_header_timeout_config", | 			"bad_listener_read_header_timeout_config", | ||||||
| 			testBaseHCL(t, badListenerReadHeaderTimeout) + inmemHCL, | 			testBaseHCL(t, badListenerReadHeaderTimeout) + inmemHCL, | ||||||
| 			"Could not parse a time value for http_read_header_timeout", | 			"unknown unit km in duration 12km", | ||||||
| 			1, | 			1, | ||||||
| 			"-test-server-config", | 			"-test-server-config", | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"bad_listener_read_timeout_config", | 			"bad_listener_read_timeout_config", | ||||||
| 			testBaseHCL(t, badListenerReadTimeout) + inmemHCL, | 			testBaseHCL(t, badListenerReadTimeout) + inmemHCL, | ||||||
| 			"Could not parse a time value for http_read_timeout", | 			"parsing \"34日\": invalid syntax", | ||||||
| 			1, | 			1, | ||||||
| 			"-test-server-config", | 			"-test-server-config", | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"bad_listener_write_timeout_config", | 			"bad_listener_write_timeout_config", | ||||||
| 			testBaseHCL(t, badListenerWriteTimeout) + inmemHCL, | 			testBaseHCL(t, badListenerWriteTimeout) + inmemHCL, | ||||||
| 			"Could not parse a time value for http_write_timeout", | 			"unknown unit lbs in duration 56lbs", | ||||||
| 			1, | 			1, | ||||||
| 			"-test-server-config", | 			"-test-server-config", | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"bad_listener_idle_timeout_config", | 			"bad_listener_idle_timeout_config", | ||||||
| 			testBaseHCL(t, badListenerIdleTimeout) + inmemHCL, | 			testBaseHCL(t, badListenerIdleTimeout) + inmemHCL, | ||||||
| 			"Could not parse a time value for http_idle_timeout", | 			"unknown unit gophers in duration 78gophers", | ||||||
| 			1, | 			1, | ||||||
| 			"-test-server-config", | 			"-test-server-config", | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -2,9 +2,7 @@ package command | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"crypto/rand" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" |  | ||||||
|  |  | ||||||
| 	log "github.com/hashicorp/go-hclog" | 	log "github.com/hashicorp/go-hclog" | ||||||
| 	wrapping "github.com/hashicorp/go-kms-wrapping" | 	wrapping "github.com/hashicorp/go-kms-wrapping" | ||||||
| @@ -16,17 +14,12 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	createSecureRandomReaderFunc = createSecureRandomReader |  | ||||||
| 	adjustCoreConfigForEnt = adjustCoreConfigForEntNoop | 	adjustCoreConfigForEnt = adjustCoreConfigForEntNoop | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func adjustCoreConfigForEntNoop(config *server.Config, coreConfig *vault.CoreConfig) { | func adjustCoreConfigForEntNoop(config *server.Config, coreConfig *vault.CoreConfig) { | ||||||
| } | } | ||||||
|  |  | ||||||
| func createSecureRandomReader(config *server.Config, seal *vault.Seal) (io.Reader, error) { |  | ||||||
| 	return rand.Reader, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal, unwrapSeal vault.Seal) error { | func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal, unwrapSeal vault.Seal) error { | ||||||
| 	existBarrierSealConfig, existRecoverySealConfig, err := core.PhysicalSealConfigs(context.Background()) | 	existBarrierSealConfig, existRecoverySealConfig, err := core.PhysicalSealConfigs(context.Background()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -70,7 +63,7 @@ func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal | |||||||
| 	case wrapping.Shamir: | 	case wrapping.Shamir: | ||||||
| 		// The value reflected in config is what we're going to | 		// The value reflected in config is what we're going to | ||||||
| 		migrationSeal = vault.NewDefaultSeal(&vaultseal.Access{ | 		migrationSeal = vault.NewDefaultSeal(&vaultseal.Access{ | ||||||
| 			Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 			Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 				Logger: logger.Named("shamir"), | 				Logger: logger.Named("shamir"), | ||||||
| 			}), | 			}), | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								go.mod
									
									
									
									
									
								
							| @@ -9,7 +9,7 @@ replace github.com/hashicorp/vault/sdk => ./sdk | |||||||
| require ( | require ( | ||||||
| 	cloud.google.com/go v0.39.0 | 	cloud.google.com/go v0.39.0 | ||||||
| 	github.com/Azure/azure-sdk-for-go v36.2.0+incompatible | 	github.com/Azure/azure-sdk-for-go v36.2.0+incompatible | ||||||
| 	github.com/Azure/go-autorest/autorest v0.9.2 | 	github.com/Azure/go-autorest/autorest v0.9.6 | ||||||
| 	github.com/DataDog/zstd v1.4.4 // indirect | 	github.com/DataDog/zstd v1.4.4 // indirect | ||||||
| 	github.com/NYTimes/gziphandler v1.1.1 | 	github.com/NYTimes/gziphandler v1.1.1 | ||||||
| 	github.com/SAP/go-hdb v0.14.1 | 	github.com/SAP/go-hdb v0.14.1 | ||||||
| @@ -43,7 +43,7 @@ require ( | |||||||
| 	github.com/go-test/deep v1.0.2 | 	github.com/go-test/deep v1.0.2 | ||||||
| 	github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df | 	github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df | ||||||
| 	github.com/gogo/protobuf v1.2.1 | 	github.com/gogo/protobuf v1.2.1 | ||||||
| 	github.com/golang/protobuf v1.3.2 | 	github.com/golang/protobuf v1.3.4 | ||||||
| 	github.com/google/go-github v17.0.0+incompatible | 	github.com/google/go-github v17.0.0+incompatible | ||||||
| 	github.com/google/go-metrics-stackdriver v0.2.0 | 	github.com/google/go-metrics-stackdriver v0.2.0 | ||||||
| 	github.com/hashicorp/consul-template v0.22.0 | 	github.com/hashicorp/consul-template v0.22.0 | ||||||
| @@ -51,8 +51,8 @@ require ( | |||||||
| 	github.com/hashicorp/errwrap v1.0.0 | 	github.com/hashicorp/errwrap v1.0.0 | ||||||
| 	github.com/hashicorp/go-cleanhttp v0.5.1 | 	github.com/hashicorp/go-cleanhttp v0.5.1 | ||||||
| 	github.com/hashicorp/go-gcp-common v0.6.0 | 	github.com/hashicorp/go-gcp-common v0.6.0 | ||||||
| 	github.com/hashicorp/go-hclog v0.12.0 | 	github.com/hashicorp/go-hclog v0.12.1 | ||||||
| 	github.com/hashicorp/go-kms-wrapping v0.5.1 | 	github.com/hashicorp/go-kms-wrapping v0.5.5 | ||||||
| 	github.com/hashicorp/go-memdb v1.0.2 | 	github.com/hashicorp/go-memdb v1.0.2 | ||||||
| 	github.com/hashicorp/go-msgpack v0.5.5 | 	github.com/hashicorp/go-msgpack v0.5.5 | ||||||
| 	github.com/hashicorp/go-multierror v1.0.0 | 	github.com/hashicorp/go-multierror v1.0.0 | ||||||
| @@ -86,8 +86,8 @@ require ( | |||||||
| 	github.com/hashicorp/vault-plugin-secrets-kv v0.5.5 | 	github.com/hashicorp/vault-plugin-secrets-kv v0.5.5 | ||||||
| 	github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.1.2 | 	github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.1.2 | ||||||
| 	github.com/hashicorp/vault-plugin-secrets-openldap v0.1.2 | 	github.com/hashicorp/vault-plugin-secrets-openldap v0.1.2 | ||||||
| 	github.com/hashicorp/vault/api v1.0.5-0.20200317185738-82f498082f02 | 	github.com/hashicorp/vault/api v1.0.5-0.20200425175256-972b211f3e96 | ||||||
| 	github.com/hashicorp/vault/sdk v0.1.14-0.20200317185738-82f498082f02 | 	github.com/hashicorp/vault/sdk v0.1.14-0.20200425175256-972b211f3e96 | ||||||
| 	github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 | 	github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 | ||||||
| 	github.com/jcmturner/gokrb5/v8 v8.0.0 | 	github.com/jcmturner/gokrb5/v8 v8.0.0 | ||||||
| 	github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f | 	github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f | ||||||
|   | |||||||
							
								
								
									
										70
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								go.sum
									
									
									
									
									
								
							| @@ -12,16 +12,23 @@ github.com/Azure/azure-sdk-for-go v36.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo | |||||||
| github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= | github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= | ||||||
| github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= | github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= | ||||||
| github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= | github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= | ||||||
| github.com/Azure/go-autorest/autorest v0.9.2 h1:6AWuh3uWrsZJcNoCHrCF/+g4aKPCU39kaMO6/qrnK/4= |  | ||||||
| github.com/Azure/go-autorest/autorest v0.9.2/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= | github.com/Azure/go-autorest/autorest v0.9.2/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= | ||||||
|  | github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= | ||||||
|  | github.com/Azure/go-autorest/autorest v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0= | ||||||
|  | github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= | github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= | github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.7.0 h1:PUMxSVw3tEImG0JTRqbxjXLKCSoPk7DartDELqlOuiI= |  | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.7.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= | github.com/Azure/go-autorest/autorest/adal v0.7.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= | ||||||
| github.com/Azure/go-autorest/autorest/azure/auth v0.4.0 h1:18ld/uw9Rr7VkNie7a7RMAcFIWrJdlUL59TWGfcu530= | github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= | ||||||
|  | github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= | ||||||
|  | github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0= | ||||||
|  | github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= | ||||||
| github.com/Azure/go-autorest/autorest/azure/auth v0.4.0/go.mod h1:Oo5cRhLvZteXzI2itUm5ziqsoIxRkzrt3t61FeZaS18= | github.com/Azure/go-autorest/autorest/azure/auth v0.4.0/go.mod h1:Oo5cRhLvZteXzI2itUm5ziqsoIxRkzrt3t61FeZaS18= | ||||||
| github.com/Azure/go-autorest/autorest/azure/cli v0.3.0 h1:5PAqnv+CSTwW9mlZWZAizmzrazFWEgZykEZXpr2hDtY= | github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk= | ||||||
|  | github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= | ||||||
| github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE= | github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE= | ||||||
|  | github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U= | ||||||
|  | github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= | ||||||
| github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= | github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= | ||||||
| github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= | github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= | ||||||
| github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= | github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= | ||||||
| @@ -81,7 +88,6 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC | |||||||
| github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | ||||||
| github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= | ||||||
| github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= | github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= | ||||||
| github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU= |  | ||||||
| github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= | github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= | ||||||
| github.com/armon/go-metrics v0.3.3 h1:a9F4rlj7EWWrbj7BYw8J8+x+ZZkJeqzNyRk8hdPF+ro= | github.com/armon/go-metrics v0.3.3 h1:a9F4rlj7EWWrbj7BYw8J8+x+ZZkJeqzNyRk8hdPF+ro= | ||||||
| github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= | github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= | ||||||
| @@ -97,9 +103,7 @@ github.com/aws/aws-sdk-go v1.25.41 h1:/hj7nZ0586wFqpwjNpzWiUTwtaMgxAZNZKHay80MdX | |||||||
| github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= | github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= | ||||||
| github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= | github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= | ||||||
| github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= | github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= | ||||||
| github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= |  | ||||||
| github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | ||||||
| github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= |  | ||||||
| github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||||
| github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | ||||||
| github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||||||
| @@ -144,17 +148,14 @@ github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL | |||||||
| github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= | ||||||
| github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= | ||||||
| github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= | github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= | ||||||
| github.com/coreos/go-oidc v2.0.0+incompatible h1:+RStIopZ8wooMx+Vs5Bt8zMXxV1ABl5LbakNExNmZIg= |  | ||||||
| github.com/coreos/go-oidc v2.0.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= | github.com/coreos/go-oidc v2.0.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= | ||||||
| github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= | github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= | ||||||
| github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= | github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= | ||||||
| github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= | github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= | ||||||
| github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||||
| github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM= |  | ||||||
| github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||||||
| github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= | ||||||
| github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||||||
| github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI= |  | ||||||
| github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | ||||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= | ||||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | ||||||
| @@ -183,7 +184,6 @@ github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5Jflh | |||||||
| github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= | github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= | ||||||
| github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M= | github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M= | ||||||
| github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= | github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= | ||||||
| github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs= |  | ||||||
| github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | ||||||
| github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= | github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= | ||||||
| github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | ||||||
| @@ -247,16 +247,17 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV | |||||||
| github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= | github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= | ||||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | ||||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||||
| github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= |  | ||||||
| github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||||
|  | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= | ||||||
| github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||||
| github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= | github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= | ||||||
| github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||||
| github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
| github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= |  | ||||||
| github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
|  | github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= | ||||||
|  | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||||||
| github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | ||||||
| github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | ||||||
| github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= | ||||||
| @@ -266,7 +267,6 @@ github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= | |||||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||||
| github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= |  | ||||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||||
| github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= | github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= | ||||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| @@ -276,7 +276,6 @@ github.com/google/go-metrics-stackdriver v0.2.0 h1:rbs2sxHAPn2OtUj9JdR/Gij1YKGl0 | |||||||
| github.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJSZktIsTjb50eB72U2YZ9K0= | github.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJSZktIsTjb50eB72U2YZ9K0= | ||||||
| github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | ||||||
| github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | ||||||
| github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= |  | ||||||
| github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= | github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= | ||||||
| github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= | github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= | ||||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||||
| @@ -300,7 +299,6 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC | |||||||
| github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= | github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= | ||||||
| github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= | github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= | ||||||
| github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= | github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= | ||||||
| github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c h1:Lh2aW+HnU2Nbe1gqD9SOJLJxW1jBMmQOktN2acDyJk8= |  | ||||||
| github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||||
| github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||||
| github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= | github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= | ||||||
| @@ -320,11 +318,9 @@ 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/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= | ||||||
| github.com/hashicorp/consul-template v0.22.0 h1:ti5cqAekOeMfFYLJCjlPtKGwBcqwVxoZO/Y2vctwuUE= | github.com/hashicorp/consul-template v0.22.0 h1:ti5cqAekOeMfFYLJCjlPtKGwBcqwVxoZO/Y2vctwuUE= | ||||||
| github.com/hashicorp/consul-template v0.22.0/go.mod h1:lHrykBIcPobCuEcIMLJryKxDyk2lUMnQWmffOEONH0k= | github.com/hashicorp/consul-template v0.22.0/go.mod h1:lHrykBIcPobCuEcIMLJryKxDyk2lUMnQWmffOEONH0k= | ||||||
| github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= |  | ||||||
| github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= | ||||||
| github.com/hashicorp/consul/api v1.2.1-0.20200128105449-6681be918a6e h1:vOqdnsq53winzJDN6RTQe9n9g87S595PNsdwKyBWXRM= | github.com/hashicorp/consul/api v1.2.1-0.20200128105449-6681be918a6e h1:vOqdnsq53winzJDN6RTQe9n9g87S595PNsdwKyBWXRM= | ||||||
| github.com/hashicorp/consul/api v1.2.1-0.20200128105449-6681be918a6e/go.mod h1:ztzLK20HA5O27oTf2j/wbNgq8qj/crN8xsSx7pzX0sc= | github.com/hashicorp/consul/api v1.2.1-0.20200128105449-6681be918a6e/go.mod h1:ztzLK20HA5O27oTf2j/wbNgq8qj/crN8xsSx7pzX0sc= | ||||||
| github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= |  | ||||||
| github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= | ||||||
| github.com/hashicorp/consul/sdk v0.2.0 h1:GWFYFmry/k4b1hEoy7kSkmU8e30GAyI4VZHk0fRxeL4= | github.com/hashicorp/consul/sdk v0.2.0 h1:GWFYFmry/k4b1hEoy7kSkmU8e30GAyI4VZHk0fRxeL4= | ||||||
| github.com/hashicorp/consul/sdk v0.2.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= | github.com/hashicorp/consul/sdk v0.2.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= | ||||||
| @@ -335,7 +331,6 @@ github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVo | |||||||
| github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | ||||||
| github.com/hashicorp/go-gatedio v0.5.0 h1:Jm1X5yP4yCqqWj5L1TgW7iZwCVPGtVc+mro5r/XX7Tg= | github.com/hashicorp/go-gatedio v0.5.0 h1:Jm1X5yP4yCqqWj5L1TgW7iZwCVPGtVc+mro5r/XX7Tg= | ||||||
| github.com/hashicorp/go-gatedio v0.5.0/go.mod h1:Lr3t8L6IyxD3DAeaUxGcgl2JnRUpWMCsmBl4Omu/2t4= | github.com/hashicorp/go-gatedio v0.5.0/go.mod h1:Lr3t8L6IyxD3DAeaUxGcgl2JnRUpWMCsmBl4Omu/2t4= | ||||||
| github.com/hashicorp/go-gcp-common v0.5.0 h1:kkIQTjNTopn4eXQ1+lCiHYZXUtgIZvbc6YtAQkMnTos= |  | ||||||
| github.com/hashicorp/go-gcp-common v0.5.0/go.mod h1:IDGUI2N/OS3PiU4qZcXJeWKPI6O/9Y8hOrbSiMcqyYw= | github.com/hashicorp/go-gcp-common v0.5.0/go.mod h1:IDGUI2N/OS3PiU4qZcXJeWKPI6O/9Y8hOrbSiMcqyYw= | ||||||
| github.com/hashicorp/go-gcp-common v0.6.0 h1:m1X+DK003bj4WEjqOnv+Csepb3zpfN/bidboUeUSj68= | github.com/hashicorp/go-gcp-common v0.6.0 h1:m1X+DK003bj4WEjqOnv+Csepb3zpfN/bidboUeUSj68= | ||||||
| github.com/hashicorp/go-gcp-common v0.6.0/go.mod h1:RuZi18562/z30wxOzpjeRrGcmk9Ro/rBzixaSZDhIhY= | github.com/hashicorp/go-gcp-common v0.6.0/go.mod h1:RuZi18562/z30wxOzpjeRrGcmk9Ro/rBzixaSZDhIhY= | ||||||
| @@ -343,15 +338,14 @@ github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9 | |||||||
| github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | ||||||
| github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | ||||||
| github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= | ||||||
| github.com/hashicorp/go-hclog v0.10.1 h1:uyt/l0dWjJ879yiAu+T7FG3/6QX+zwm4bQ8P7XsYt3o= |  | ||||||
| github.com/hashicorp/go-hclog v0.10.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= |  | ||||||
| github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= |  | ||||||
| github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= | github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= | ||||||
|  | github.com/hashicorp/go-hclog v0.12.1 h1:99niEVkDqsEv3/jINwoOUgGE9L41LHXM4k3jTkV+DdA= | ||||||
|  | github.com/hashicorp/go-hclog v0.12.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= | ||||||
| github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= | ||||||
| github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= | github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= | ||||||
| github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= | github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= | ||||||
| github.com/hashicorp/go-kms-wrapping v0.5.1 h1:Ed6Z5gV3LY3J9Ora4cwxVmV8Hyt6CPOTrQoGIPry2Ew= | github.com/hashicorp/go-kms-wrapping v0.5.5 h1:ld350yu4UPAFCyt5NifPU3WpFts71z69n3NfMeTv2z8= | ||||||
| github.com/hashicorp/go-kms-wrapping v0.5.1/go.mod h1:cGIibZmMx9qlxS1pZTUrEgGqA+7u3zJyvVYMhjU2bDs= | github.com/hashicorp/go-kms-wrapping v0.5.5/go.mod h1:FeTpMJSbqrCtAeEK30hlNS8jm6W7cjzmLWurZ4Tk/J4= | ||||||
| github.com/hashicorp/go-kms-wrapping/entropy v0.1.0 h1:xuTi5ZwjimfpvpL09jDE71smCBRpnF5xfo871BSX4gs= | github.com/hashicorp/go-kms-wrapping/entropy v0.1.0 h1:xuTi5ZwjimfpvpL09jDE71smCBRpnF5xfo871BSX4gs= | ||||||
| github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= | github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= | ||||||
| github.com/hashicorp/go-memdb v1.0.2 h1:AIjzJlwIxz2inhZqRJZfe6D15lPeF0/cZyS1BVlnlHg= | github.com/hashicorp/go-memdb v1.0.2 h1:AIjzJlwIxz2inhZqRJZfe6D15lPeF0/cZyS1BVlnlHg= | ||||||
| @@ -369,7 +363,6 @@ github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es | |||||||
| github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw= | github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw= | ||||||
| github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= | github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= | ||||||
| github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= | ||||||
| github.com/hashicorp/go-rootcerts v1.0.1 h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8= |  | ||||||
| github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= | github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= | ||||||
| github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= | github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= | ||||||
| github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= | github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= | ||||||
| @@ -380,8 +373,6 @@ github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwM | |||||||
| github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= | ||||||
| github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||||
| github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8 h1:PKbxRbsOP7R3f/TpdqcgXrO69T3yd9nLoR+RMRUxSxA= |  | ||||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= |  | ||||||
| github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= | github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= | ||||||
| github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||||
| github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||||
| @@ -450,14 +441,12 @@ github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.1.2 h1:X9eK6NSb1qafvoE | |||||||
| github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.1.2/go.mod h1:YRW9zn9NZNitRlPYNAWRp/YEdKCF/X8aOg8IYSxFT5Y= | github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.1.2/go.mod h1:YRW9zn9NZNitRlPYNAWRp/YEdKCF/X8aOg8IYSxFT5Y= | ||||||
| github.com/hashicorp/vault-plugin-secrets-openldap v0.1.2 h1:618nyNUHX2Oc7pcQh6r0Zm0kaMrhkfAyUyFmDFwyYnQ= | github.com/hashicorp/vault-plugin-secrets-openldap v0.1.2 h1:618nyNUHX2Oc7pcQh6r0Zm0kaMrhkfAyUyFmDFwyYnQ= | ||||||
| github.com/hashicorp/vault-plugin-secrets-openldap v0.1.2/go.mod h1:9Cy4Jp779BjuIOhYLjEfH3M3QCUxZgPnvJ3tAOOmof4= | github.com/hashicorp/vault-plugin-secrets-openldap v0.1.2/go.mod h1:9Cy4Jp779BjuIOhYLjEfH3M3QCUxZgPnvJ3tAOOmof4= | ||||||
| github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= |  | ||||||
| github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | ||||||
| github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= | github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= | ||||||
| github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | ||||||
| github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= | github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= | ||||||
| github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||||
| github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= | github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= | ||||||
| github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= |  | ||||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||||
| github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 h1:3K3KcD4S6/Y2hevi70EzUTNKOS3cryQyhUnkjE6Tz0w= | github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 h1:3K3KcD4S6/Y2hevi70EzUTNKOS3cryQyhUnkjE6Tz0w= | ||||||
| github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= | github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= | ||||||
| @@ -491,9 +480,7 @@ github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8fa | |||||||
| github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= | github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= | ||||||
| github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | ||||||
| github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | ||||||
| github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= |  | ||||||
| github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | ||||||
| github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= |  | ||||||
| github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||||
| github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= | ||||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||||
| @@ -644,35 +631,27 @@ github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d h1:PinQItctnaL2LtkaS | |||||||
| github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= | github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= | ||||||
| github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | ||||||
| github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= | github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= | ||||||
| github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA= |  | ||||||
| github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= | ||||||
| github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= | ||||||
| github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= |  | ||||||
| github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= | ||||||
| github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI= | github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI= | ||||||
| github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= | github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= | ||||||
| github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||||||
| github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU= |  | ||||||
| github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||||||
| github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= |  | ||||||
| github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||||
| github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= | github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= | ||||||
| github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||||
| github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | ||||||
| github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | ||||||
| github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= |  | ||||||
| github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | ||||||
| github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | ||||||
| github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= |  | ||||||
| github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | ||||||
| github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= | github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= | ||||||
| github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= | github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= | ||||||
| github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | ||||||
| github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | ||||||
| github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg= |  | ||||||
| github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | ||||||
| github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | ||||||
| github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= |  | ||||||
| github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | ||||||
| github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= | github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= | ||||||
| github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= | github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= | ||||||
| @@ -718,12 +697,11 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO | |||||||
| github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | ||||||
| github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= | github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= | ||||||
| github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||||
| github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= |  | ||||||
| github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | ||||||
| github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= | ||||||
| github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | ||||||
| github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= |  | ||||||
| github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||||
|  | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | ||||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||||
| github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | ||||||
| github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= | github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= | ||||||
| @@ -739,8 +717,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy | |||||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||||
| github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= | github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= | ||||||
| github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= | github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= | ||||||
| github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE= |  | ||||||
| github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | ||||||
|  | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= | ||||||
| github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | 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 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= | ||||||
| github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= | github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= | ||||||
| @@ -786,6 +764,7 @@ golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaE | |||||||
| golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
| golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
| golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
|  | golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= | golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= | ||||||
| golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||||
| @@ -816,7 +795,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL | |||||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= |  | ||||||
| golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= | ||||||
| golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| @@ -832,7 +810,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ | |||||||
| golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= |  | ||||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= | ||||||
| golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| @@ -859,7 +836,6 @@ golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7w | |||||||
| golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU= |  | ||||||
| golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= | ||||||
| @@ -918,7 +894,6 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3 | |||||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||||
| google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||||
| google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= |  | ||||||
| google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | ||||||
| google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= | google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= | ||||||
| google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | ||||||
| @@ -926,7 +901,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks | |||||||
| gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= | gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= | ||||||
| gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= | gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= | ||||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= |  | ||||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= | ||||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| @@ -948,7 +922,6 @@ gopkg.in/ory-am/dockertest.v3 v3.3.4 h1:oen8RiwxVNxtQ1pRoV4e4jqh6UjNsOuIZ1NXns6j | |||||||
| gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= | gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= | ||||||
| gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | ||||||
| gopkg.in/square/go-jose.v2 v2.3.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | gopkg.in/square/go-jose.v2 v2.3.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | ||||||
| gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= |  | ||||||
| gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | ||||||
| gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= | gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= | ||||||
| gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | ||||||
| @@ -956,7 +929,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep | |||||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||||
| gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= | ||||||
| gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= |  | ||||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= | gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ import ( | |||||||
| 	logicalGcpKms "github.com/hashicorp/vault-plugin-secrets-gcpkms" | 	logicalGcpKms "github.com/hashicorp/vault-plugin-secrets-gcpkms" | ||||||
| 	logicalKv "github.com/hashicorp/vault-plugin-secrets-kv" | 	logicalKv "github.com/hashicorp/vault-plugin-secrets-kv" | ||||||
| 	logicalMongoAtlas "github.com/hashicorp/vault-plugin-secrets-mongodbatlas" | 	logicalMongoAtlas "github.com/hashicorp/vault-plugin-secrets-mongodbatlas" | ||||||
|  | 	logicalOpenLDAP "github.com/hashicorp/vault-plugin-secrets-openldap" | ||||||
| 	logicalAws "github.com/hashicorp/vault/builtin/logical/aws" | 	logicalAws "github.com/hashicorp/vault/builtin/logical/aws" | ||||||
| 	logicalCass "github.com/hashicorp/vault/builtin/logical/cassandra" | 	logicalCass "github.com/hashicorp/vault/builtin/logical/cassandra" | ||||||
| 	logicalConsul "github.com/hashicorp/vault/builtin/logical/consul" | 	logicalConsul "github.com/hashicorp/vault/builtin/logical/consul" | ||||||
| @@ -47,7 +48,6 @@ import ( | |||||||
| 	logicalMssql "github.com/hashicorp/vault/builtin/logical/mssql" | 	logicalMssql "github.com/hashicorp/vault/builtin/logical/mssql" | ||||||
| 	logicalMysql "github.com/hashicorp/vault/builtin/logical/mysql" | 	logicalMysql "github.com/hashicorp/vault/builtin/logical/mysql" | ||||||
| 	logicalNomad "github.com/hashicorp/vault/builtin/logical/nomad" | 	logicalNomad "github.com/hashicorp/vault/builtin/logical/nomad" | ||||||
| 	logicalOpenLDAP "github.com/hashicorp/vault-plugin-secrets-openldap" |  | ||||||
| 	logicalPki "github.com/hashicorp/vault/builtin/logical/pki" | 	logicalPki "github.com/hashicorp/vault/builtin/logical/pki" | ||||||
| 	logicalPostgres "github.com/hashicorp/vault/builtin/logical/postgresql" | 	logicalPostgres "github.com/hashicorp/vault/builtin/logical/postgresql" | ||||||
| 	logicalRabbit "github.com/hashicorp/vault/builtin/logical/rabbitmq" | 	logicalRabbit "github.com/hashicorp/vault/builtin/logical/rabbitmq" | ||||||
|   | |||||||
| @@ -6,13 +6,13 @@ import ( | |||||||
| 	"github.com/hashicorp/go-hclog" | 	"github.com/hashicorp/go-hclog" | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
| 	"github.com/hashicorp/vault/builtin/logical/transit" | 	"github.com/hashicorp/vault/builtin/logical/transit" | ||||||
| 	"github.com/hashicorp/vault/command/server/seal" |  | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/teststorage" | 	"github.com/hashicorp/vault/helper/testhelpers/teststorage" | ||||||
| 	"github.com/hashicorp/vault/http" | 	"github.com/hashicorp/vault/http" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/logging" | 	"github.com/hashicorp/vault/sdk/helper/logging" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| 	"github.com/hashicorp/vault/vault" | 	"github.com/hashicorp/vault/vault" | ||||||
| 	vaultseal "github.com/hashicorp/vault/vault/seal" | 	"github.com/hashicorp/vault/vault/seal" | ||||||
| 	"github.com/mitchellh/go-testing-interface" | 	"github.com/mitchellh/go-testing-interface" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -65,12 +65,12 @@ func (tss *TransitSealServer) MakeSeal(t testing.T, key string) vault.Seal { | |||||||
| 		"key_name":    key, | 		"key_name":    key, | ||||||
| 		"tls_ca_cert": tss.CACertPEMFile, | 		"tls_ca_cert": tss.CACertPEMFile, | ||||||
| 	} | 	} | ||||||
| 	transitSeal, _, err := seal.GetTransitKMSFunc(nil, wrapperConfig) | 	transitSeal, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("error setting wrapper config: %v", err) | 		t.Fatalf("error setting wrapper config: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return vault.NewAutoSeal(&vaultseal.Access{ | 	return vault.NewAutoSeal(&seal.Access{ | ||||||
| 		Wrapper: transitSeal, | 		Wrapper: transitSeal, | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,9 +7,20 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	sockaddr "github.com/hashicorp/go-sockaddr" | 	sockaddr "github.com/hashicorp/go-sockaddr" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/vault" | 	"github.com/hashicorp/vault/vault" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | func getListenerConfigForMarshalerTest(addr sockaddr.IPAddr) *configutil.Listener { | ||||||
|  | 	return &configutil.Listener{ | ||||||
|  | 		XForwardedForAuthorizedAddrs: []*sockaddr.SockAddrMarshaler{ | ||||||
|  | 			{ | ||||||
|  | 				SockAddr: addr, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func TestHandler_XForwardedFor(t *testing.T) { | func TestHandler_XForwardedFor(t *testing.T) { | ||||||
| 	goodAddr, err := sockaddr.NewIPAddr("127.0.0.1") | 	goodAddr, err := sockaddr.NewIPAddr("127.0.0.1") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -29,11 +40,9 @@ func TestHandler_XForwardedFor(t *testing.T) { | |||||||
| 				w.WriteHeader(http.StatusOK) | 				w.WriteHeader(http.StatusOK) | ||||||
| 				w.Write([]byte(r.RemoteAddr)) | 				w.Write([]byte(r.RemoteAddr)) | ||||||
| 			}) | 			}) | ||||||
| 			return WrapForwardedForHandler(origHandler, []*sockaddr.SockAddrMarshaler{ | 			listenerConfig := getListenerConfigForMarshalerTest(goodAddr) | ||||||
| 				&sockaddr.SockAddrMarshaler{ | 			listenerConfig.XForwardedForRejectNotPresent = true | ||||||
| 					SockAddr: goodAddr, | 			return WrapForwardedForHandler(origHandler, listenerConfig) | ||||||
| 				}, |  | ||||||
| 			}, true, false, 0) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | ||||||
| @@ -74,11 +83,9 @@ func TestHandler_XForwardedFor(t *testing.T) { | |||||||
| 				w.WriteHeader(http.StatusOK) | 				w.WriteHeader(http.StatusOK) | ||||||
| 				w.Write([]byte(r.RemoteAddr)) | 				w.Write([]byte(r.RemoteAddr)) | ||||||
| 			}) | 			}) | ||||||
| 			return WrapForwardedForHandler(origHandler, []*sockaddr.SockAddrMarshaler{ | 			listenerConfig := getListenerConfigForMarshalerTest(badAddr) | ||||||
| 				&sockaddr.SockAddrMarshaler{ | 			listenerConfig.XForwardedForRejectNotPresent = true | ||||||
| 					SockAddr: badAddr, | 			return WrapForwardedForHandler(origHandler, listenerConfig) | ||||||
| 				}, |  | ||||||
| 			}, true, false, 0) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | ||||||
| @@ -111,11 +118,10 @@ func TestHandler_XForwardedFor(t *testing.T) { | |||||||
| 				w.WriteHeader(http.StatusOK) | 				w.WriteHeader(http.StatusOK) | ||||||
| 				w.Write([]byte(r.RemoteAddr)) | 				w.Write([]byte(r.RemoteAddr)) | ||||||
| 			}) | 			}) | ||||||
| 			return WrapForwardedForHandler(origHandler, []*sockaddr.SockAddrMarshaler{ | 			listenerConfig := getListenerConfigForMarshalerTest(badAddr) | ||||||
| 				&sockaddr.SockAddrMarshaler{ | 			listenerConfig.XForwardedForRejectNotPresent = true | ||||||
| 					SockAddr: badAddr, | 			listenerConfig.XForwardedForRejectNotAuthorized = true | ||||||
| 				}, | 			return WrapForwardedForHandler(origHandler, listenerConfig) | ||||||
| 			}, true, true, 0) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | ||||||
| @@ -145,11 +151,11 @@ func TestHandler_XForwardedFor(t *testing.T) { | |||||||
| 				w.WriteHeader(http.StatusOK) | 				w.WriteHeader(http.StatusOK) | ||||||
| 				w.Write([]byte(r.RemoteAddr)) | 				w.Write([]byte(r.RemoteAddr)) | ||||||
| 			}) | 			}) | ||||||
| 			return WrapForwardedForHandler(origHandler, []*sockaddr.SockAddrMarshaler{ | 			listenerConfig := getListenerConfigForMarshalerTest(goodAddr) | ||||||
| 				&sockaddr.SockAddrMarshaler{ | 			listenerConfig.XForwardedForRejectNotPresent = true | ||||||
| 					SockAddr: goodAddr, | 			listenerConfig.XForwardedForRejectNotAuthorized = true | ||||||
| 				}, | 			listenerConfig.XForwardedForHopSkips = 4 | ||||||
| 			}, true, true, 4) | 			return WrapForwardedForHandler(origHandler, listenerConfig) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | ||||||
| @@ -179,11 +185,11 @@ func TestHandler_XForwardedFor(t *testing.T) { | |||||||
| 				w.WriteHeader(http.StatusOK) | 				w.WriteHeader(http.StatusOK) | ||||||
| 				w.Write([]byte(r.RemoteAddr)) | 				w.Write([]byte(r.RemoteAddr)) | ||||||
| 			}) | 			}) | ||||||
| 			return WrapForwardedForHandler(origHandler, []*sockaddr.SockAddrMarshaler{ | 			listenerConfig := getListenerConfigForMarshalerTest(goodAddr) | ||||||
| 				&sockaddr.SockAddrMarshaler{ | 			listenerConfig.XForwardedForRejectNotPresent = true | ||||||
| 					SockAddr: goodAddr, | 			listenerConfig.XForwardedForRejectNotAuthorized = true | ||||||
| 				}, | 			listenerConfig.XForwardedForHopSkips = 1 | ||||||
| 			}, true, true, 1) | 			return WrapForwardedForHandler(origHandler, listenerConfig) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | ||||||
| @@ -216,11 +222,11 @@ func TestHandler_XForwardedFor(t *testing.T) { | |||||||
| 				w.WriteHeader(http.StatusOK) | 				w.WriteHeader(http.StatusOK) | ||||||
| 				w.Write([]byte(r.RemoteAddr)) | 				w.Write([]byte(r.RemoteAddr)) | ||||||
| 			}) | 			}) | ||||||
| 			return WrapForwardedForHandler(origHandler, []*sockaddr.SockAddrMarshaler{ | 			listenerConfig := getListenerConfigForMarshalerTest(goodAddr) | ||||||
| 				&sockaddr.SockAddrMarshaler{ | 			listenerConfig.XForwardedForRejectNotPresent = true | ||||||
| 					SockAddr: goodAddr, | 			listenerConfig.XForwardedForRejectNotAuthorized = true | ||||||
| 				}, | 			listenerConfig.XForwardedForHopSkips = 1 | ||||||
| 			}, true, true, 1) | 			return WrapForwardedForHandler(origHandler, listenerConfig) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | 		cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{ | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import ( | |||||||
| 	cleanhttp "github.com/hashicorp/go-cleanhttp" | 	cleanhttp "github.com/hashicorp/go-cleanhttp" | ||||||
| 	sockaddr "github.com/hashicorp/go-sockaddr" | 	sockaddr "github.com/hashicorp/go-sockaddr" | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/consts" | 	"github.com/hashicorp/vault/sdk/helper/consts" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/parseutil" | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
| @@ -161,7 +162,7 @@ func Handler(props *vault.HandlerProperties) http.Handler { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Register metrics path without authentication if enabled | 		// Register metrics path without authentication if enabled | ||||||
| 		if props.UnauthenticatedMetricsAccess { | 		if props.ListenerConfig != nil && props.ListenerConfig.Telemetry.UnauthenticatedMetricsAccess { | ||||||
| 			mux.Handle("/v1/sys/metrics", handleMetricsUnauthenticated(core)) | 			mux.Handle("/v1/sys/metrics", handleMetricsUnauthenticated(core)) | ||||||
| 		} else { | 		} else { | ||||||
| 			mux.Handle("/v1/sys/metrics", handleLogicalNoForward(core)) | 			mux.Handle("/v1/sys/metrics", handleLogicalNoForward(core)) | ||||||
| @@ -252,10 +253,19 @@ func handleAuditNonLogical(core *vault.Core, h http.Handler) http.Handler { | |||||||
| // wrapGenericHandler wraps the handler with an extra layer of handler where | // wrapGenericHandler wraps the handler with an extra layer of handler where | ||||||
| // tasks that should be commonly handled for all the requests and/or responses | // tasks that should be commonly handled for all the requests and/or responses | ||||||
| // are performed. | // are performed. | ||||||
| func wrapGenericHandler(core *vault.Core, h http.Handler, maxRequestSize int64, maxRequestDuration time.Duration) http.Handler { | func wrapGenericHandler(core *vault.Core, h http.Handler, props *vault.HandlerProperties) http.Handler { | ||||||
|  | 	var maxRequestDuration time.Duration | ||||||
|  | 	var maxRequestSize int64 | ||||||
|  | 	if props.ListenerConfig != nil { | ||||||
|  | 		maxRequestDuration = props.ListenerConfig.MaxRequestDuration | ||||||
|  | 		maxRequestSize = props.ListenerConfig.MaxRequestSize | ||||||
|  | 	} | ||||||
| 	if maxRequestDuration == 0 { | 	if maxRequestDuration == 0 { | ||||||
| 		maxRequestDuration = vault.DefaultMaxRequestDuration | 		maxRequestDuration = vault.DefaultMaxRequestDuration | ||||||
| 	} | 	} | ||||||
|  | 	if maxRequestSize == 0 { | ||||||
|  | 		maxRequestSize = DefaultMaxRequestSize | ||||||
|  | 	} | ||||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		// Set the Cache-Control header for all the responses returned | 		// Set the Cache-Control header for all the responses returned | ||||||
| 		// by Vault | 		// by Vault | ||||||
| @@ -296,7 +306,11 @@ func wrapGenericHandler(core *vault.Core, h http.Handler, maxRequestSize int64, | |||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func WrapForwardedForHandler(h http.Handler, authorizedAddrs []*sockaddr.SockAddrMarshaler, rejectNotPresent, rejectNonAuthz bool, hopSkips int) http.Handler { | func WrapForwardedForHandler(h http.Handler, l *configutil.Listener) http.Handler { | ||||||
|  | 	rejectNotPresent := l.XForwardedForRejectNotPresent | ||||||
|  | 	hopSkips := l.XForwardedForHopSkips | ||||||
|  | 	authorizedAddrs := l.XForwardedForAuthorizedAddrs | ||||||
|  | 	rejectNotAuthz := l.XForwardedForRejectNotAuthorized | ||||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		headers, headersOK := r.Header[textproto.CanonicalMIMEHeaderKey("X-Forwarded-For")] | 		headers, headersOK := r.Header[textproto.CanonicalMIMEHeaderKey("X-Forwarded-For")] | ||||||
| 		if !headersOK || len(headers) == 0 { | 		if !headersOK || len(headers) == 0 { | ||||||
| @@ -342,7 +356,7 @@ func WrapForwardedForHandler(h http.Handler, authorizedAddrs []*sockaddr.SockAdd | |||||||
| 		if !found { | 		if !found { | ||||||
| 			// If we didn't find it and aren't configured to reject, simply | 			// If we didn't find it and aren't configured to reject, simply | ||||||
| 			// don't trust it | 			// don't trust it | ||||||
| 			if !rejectNonAuthz { | 			if !rejectNotAuthz { | ||||||
| 				h.ServeHTTP(w, r) | 				h.ServeHTTP(w, r) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| @@ -362,7 +376,7 @@ func WrapForwardedForHandler(h http.Handler, authorizedAddrs []*sockaddr.SockAdd | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		indexToUse := len(acc) - 1 - hopSkips | 		indexToUse := int64(len(acc)) - 1 - hopSkips | ||||||
| 		if indexToUse < 0 { | 		if indexToUse < 0 { | ||||||
| 			// This is likely an error in either configuration or other | 			// This is likely an error in either configuration or other | ||||||
| 			// infrastructure. We could either deny the request, or we | 			// infrastructure. We could either deny the request, or we | ||||||
|   | |||||||
| @@ -655,7 +655,6 @@ func testNonPrintable(t *testing.T, disable bool) { | |||||||
| 	ln, addr := TestListener(t) | 	ln, addr := TestListener(t) | ||||||
| 	props := &vault.HandlerProperties{ | 	props := &vault.HandlerProperties{ | ||||||
| 		Core:                  core, | 		Core:                  core, | ||||||
| 		MaxRequestSize:        DefaultMaxRequestSize, |  | ||||||
| 		DisablePrintableCheck: disable, | 		DisablePrintableCheck: disable, | ||||||
| 	} | 	} | ||||||
| 	TestServerWithListenerAndProperties(t, ln, addr, core, props) | 	TestServerWithListenerAndProperties(t, ln, addr, core, props) | ||||||
|   | |||||||
| @@ -267,7 +267,9 @@ func TestLogical_RequestSizeLimit(t *testing.T) { | |||||||
| 	defer ln.Close() | 	defer ln.Close() | ||||||
| 	TestServerAuth(t, addr, token) | 	TestServerAuth(t, addr, token) | ||||||
|  |  | ||||||
| 	// Write a very large object, should fail | 	// Write a very large object, should fail. This test works because Go will | ||||||
|  | 	// convert the byte slice to base64, which makes it significantly larger | ||||||
|  | 	// than the default max request size. | ||||||
| 	resp := testHttpPut(t, token, addr+"/v1/secret/foo", map[string]interface{}{ | 	resp := testHttpPut(t, token, addr+"/v1/secret/foo", map[string]interface{}{ | ||||||
| 		"data": make([]byte, DefaultMaxRequestSize), | 		"data": make([]byte, DefaultMaxRequestSize), | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/armon/go-metrics" | 	"github.com/armon/go-metrics" | ||||||
| 	"github.com/hashicorp/vault/helper/metricsutil" | 	"github.com/hashicorp/vault/helper/metricsutil" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/vault" | 	"github.com/hashicorp/vault/vault" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -33,8 +34,11 @@ func TestSysMetricsUnauthenticated(t *testing.T) { | |||||||
| 	ln, addr = TestListener(t) | 	ln, addr = TestListener(t) | ||||||
| 	props := &vault.HandlerProperties{ | 	props := &vault.HandlerProperties{ | ||||||
| 		Core: core, | 		Core: core, | ||||||
| 		MaxRequestSize:               DefaultMaxRequestSize, | 		ListenerConfig: &configutil.Listener{ | ||||||
|  | 			Telemetry: configutil.ListenerTelemetry{ | ||||||
| 				UnauthenticatedMetricsAccess: true, | 				UnauthenticatedMetricsAccess: true, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 	TestServerWithListenerAndProperties(t, ln, addr, core, props) | 	TestServerWithListenerAndProperties(t, ln, addr, core, props) | ||||||
| 	defer ln.Close() | 	defer ln.Close() | ||||||
|   | |||||||
| @@ -45,7 +45,6 @@ func TestServerWithListener(tb testing.TB, ln net.Listener, addr string, core *v | |||||||
| 	// for tests. | 	// for tests. | ||||||
| 	props := &vault.HandlerProperties{ | 	props := &vault.HandlerProperties{ | ||||||
| 		Core: core, | 		Core: core, | ||||||
| 		MaxRequestSize: DefaultMaxRequestSize, |  | ||||||
| 	} | 	} | ||||||
| 	TestServerWithListenerAndProperties(tb, ln, addr, core, props) | 	TestServerWithListenerAndProperties(tb, ln, addr, core, props) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ var ( | |||||||
| 	genericWrapping = func(core *vault.Core, in http.Handler, props *vault.HandlerProperties) http.Handler { | 	genericWrapping = func(core *vault.Core, in http.Handler, props *vault.HandlerProperties) http.Handler { | ||||||
| 		// Wrap the help wrapped handler with another layer with a generic | 		// Wrap the help wrapped handler with another layer with a generic | ||||||
| 		// handler | 		// handler | ||||||
| 		return wrapGenericHandler(core, in, props.MaxRequestSize, props.MaxRequestDuration) | 		return wrapGenericHandler(core, in, props) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	additionalRoutes = func(mux *http.ServeMux, core *vault.Core) {} | 	additionalRoutes = func(mux *http.ServeMux, core *vault.Core) {} | ||||||
|   | |||||||
							
								
								
									
										211
									
								
								internalshared/configutil/config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								internalshared/configutil/config.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | |||||||
|  | package configutil | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	"github.com/hashicorp/hcl" | ||||||
|  | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // SharedConfig contains some shared values | ||||||
|  | type SharedConfig struct { | ||||||
|  | 	EntSharedConfig | ||||||
|  |  | ||||||
|  | 	Listeners []*Listener `hcl:"-"` | ||||||
|  |  | ||||||
|  | 	Seals   []*KMS   `hcl:"-"` | ||||||
|  | 	Entropy *Entropy `hcl:"-"` | ||||||
|  |  | ||||||
|  | 	DisableMlock    bool        `hcl:"-"` | ||||||
|  | 	DisableMlockRaw interface{} `hcl:"disable_mlock"` | ||||||
|  |  | ||||||
|  | 	Telemetry *Telemetry `hcl:"telemetry"` | ||||||
|  |  | ||||||
|  | 	DefaultMaxRequestDuration    time.Duration `hcl:"-"` | ||||||
|  | 	DefaultMaxRequestDurationRaw interface{}   `hcl:"default_max_request_duration"` | ||||||
|  |  | ||||||
|  | 	// LogFormat specifies the log format. Valid values are "standard" and | ||||||
|  | 	// "json". The values are case-insenstive. If no log format is specified, | ||||||
|  | 	// then standard format will be used. | ||||||
|  | 	LogFormat string `hcl:"log_format"` | ||||||
|  | 	LogLevel  string `hcl:"log_level"` | ||||||
|  |  | ||||||
|  | 	PidFile string `hcl:"pid_file"` | ||||||
|  |  | ||||||
|  | 	ClusterName string `hcl:"cluster_name"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // LoadConfigFile loads the configuration from the given file. | ||||||
|  | func LoadConfigFile(path string) (*SharedConfig, error) { | ||||||
|  | 	// Read the file | ||||||
|  | 	d, err := ioutil.ReadFile(path) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return ParseConfig(string(d)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ParseConfig(d string) (*SharedConfig, error) { | ||||||
|  | 	// Parse! | ||||||
|  | 	obj, err := hcl.Parse(d) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Start building the result | ||||||
|  | 	var result SharedConfig | ||||||
|  | 	if err := hcl.DecodeObject(&result, obj); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if result.DefaultMaxRequestDurationRaw != nil { | ||||||
|  | 		if result.DefaultMaxRequestDuration, err = parseutil.ParseDurationSecond(result.DefaultMaxRequestDurationRaw); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		result.DefaultMaxRequestDurationRaw = nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if result.DisableMlockRaw != nil { | ||||||
|  | 		if result.DisableMlock, err = parseutil.ParseBool(result.DisableMlockRaw); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		result.DisableMlockRaw = nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	list, ok := obj.Node.(*ast.ObjectList) | ||||||
|  | 	if !ok { | ||||||
|  | 		return nil, fmt.Errorf("error parsing: file doesn't contain a root object") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o := list.Filter("hsm"); len(o.Items) > 0 { | ||||||
|  | 		if err := parseKMS(&result, o, "hsm", 1); err != nil { | ||||||
|  | 			return nil, errwrap.Wrapf("error parsing 'hsm': {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o := list.Filter("seal"); len(o.Items) > 0 { | ||||||
|  | 		if err := parseKMS(&result, o, "seal", 2); err != nil { | ||||||
|  | 			return nil, errwrap.Wrapf("error parsing 'seal': {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o := list.Filter("kms"); len(o.Items) > 0 { | ||||||
|  | 		if err := parseKMS(&result, o, "kms", 2); err != nil { | ||||||
|  | 			return nil, errwrap.Wrapf("error parsing 'kms': {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o := list.Filter("entropy"); len(o.Items) > 0 { | ||||||
|  | 		if err := ParseEntropy(&result, o, "entropy"); err != nil { | ||||||
|  | 			return nil, errwrap.Wrapf("error parsing 'entropy': {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o := list.Filter("listener"); len(o.Items) > 0 { | ||||||
|  | 		if err := ParseListeners(&result, o); err != nil { | ||||||
|  | 			return nil, errwrap.Wrapf("error parsing 'listener': {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o := list.Filter("telemetry"); len(o.Items) > 0 { | ||||||
|  | 		if err := parseTelemetry(&result, o); err != nil { | ||||||
|  | 			return nil, errwrap.Wrapf("error parsing 'telemetry': {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	entConfig := &(result.EntSharedConfig) | ||||||
|  | 	if err := entConfig.ParseConfig(list); err != nil { | ||||||
|  | 		return nil, errwrap.Wrapf("error parsing enterprise config: {{err}}", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &result, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Sanitized returns a copy of the config with all values that are considered | ||||||
|  | // sensitive stripped. It also strips all `*Raw` values that are mainly | ||||||
|  | // used for parsing. | ||||||
|  | // | ||||||
|  | // Specifically, the fields that this method strips are: | ||||||
|  | // - KMS.Config | ||||||
|  | // - Telemetry.CirconusAPIToken | ||||||
|  | func (c *SharedConfig) Sanitized() map[string]interface{} { | ||||||
|  | 	if c == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result := map[string]interface{}{ | ||||||
|  | 		"disable_mlock": c.DisableMlock, | ||||||
|  |  | ||||||
|  | 		"default_max_request_duration": c.DefaultMaxRequestDuration, | ||||||
|  |  | ||||||
|  | 		"log_level":  c.LogLevel, | ||||||
|  | 		"log_format": c.LogFormat, | ||||||
|  |  | ||||||
|  | 		"pid_file": c.PidFile, | ||||||
|  |  | ||||||
|  | 		"cluster_name": c.ClusterName, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Sanitize listeners | ||||||
|  | 	if len(c.Listeners) != 0 { | ||||||
|  | 		var sanitizedListeners []interface{} | ||||||
|  | 		for _, ln := range c.Listeners { | ||||||
|  | 			cleanLn := map[string]interface{}{ | ||||||
|  | 				"type":   ln.Type, | ||||||
|  | 				"config": ln.RawConfig, | ||||||
|  | 			} | ||||||
|  | 			sanitizedListeners = append(sanitizedListeners, cleanLn) | ||||||
|  | 		} | ||||||
|  | 		result["listeners"] = sanitizedListeners | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Sanitize seals stanza | ||||||
|  | 	if len(c.Seals) != 0 { | ||||||
|  | 		var sanitizedSeals []interface{} | ||||||
|  | 		for _, s := range c.Seals { | ||||||
|  | 			cleanSeal := map[string]interface{}{ | ||||||
|  | 				"type":     s.Type, | ||||||
|  | 				"disabled": s.Disabled, | ||||||
|  | 			} | ||||||
|  | 			sanitizedSeals = append(sanitizedSeals, cleanSeal) | ||||||
|  | 		} | ||||||
|  | 		result["seals"] = sanitizedSeals | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Sanitize telemetry stanza | ||||||
|  | 	if c.Telemetry != nil { | ||||||
|  | 		sanitizedTelemetry := map[string]interface{}{ | ||||||
|  | 			"statsite_address":                       c.Telemetry.StatsiteAddr, | ||||||
|  | 			"statsd_address":                         c.Telemetry.StatsdAddr, | ||||||
|  | 			"disable_hostname":                       c.Telemetry.DisableHostname, | ||||||
|  | 			"metrics_prefix":                         c.Telemetry.MetricsPrefix, | ||||||
|  | 			"circonus_api_token":                     "", | ||||||
|  | 			"circonus_api_app":                       c.Telemetry.CirconusAPIApp, | ||||||
|  | 			"circonus_api_url":                       c.Telemetry.CirconusAPIURL, | ||||||
|  | 			"circonus_submission_interval":           c.Telemetry.CirconusSubmissionInterval, | ||||||
|  | 			"circonus_submission_url":                c.Telemetry.CirconusCheckSubmissionURL, | ||||||
|  | 			"circonus_check_id":                      c.Telemetry.CirconusCheckID, | ||||||
|  | 			"circonus_check_force_metric_activation": c.Telemetry.CirconusCheckForceMetricActivation, | ||||||
|  | 			"circonus_check_instance_id":             c.Telemetry.CirconusCheckInstanceID, | ||||||
|  | 			"circonus_check_search_tag":              c.Telemetry.CirconusCheckSearchTag, | ||||||
|  | 			"circonus_check_tags":                    c.Telemetry.CirconusCheckTags, | ||||||
|  | 			"circonus_check_display_name":            c.Telemetry.CirconusCheckDisplayName, | ||||||
|  | 			"circonus_broker_id":                     c.Telemetry.CirconusBrokerID, | ||||||
|  | 			"circonus_broker_select_tag":             c.Telemetry.CirconusBrokerSelectTag, | ||||||
|  | 			"dogstatsd_addr":                         c.Telemetry.DogStatsDAddr, | ||||||
|  | 			"dogstatsd_tags":                         c.Telemetry.DogStatsDTags, | ||||||
|  | 			"prometheus_retention_time":              c.Telemetry.PrometheusRetentionTime, | ||||||
|  | 			"stackdriver_project_id":                 c.Telemetry.StackdriverProjectID, | ||||||
|  | 			"stackdriver_location":                   c.Telemetry.StackdriverLocation, | ||||||
|  | 			"stackdriver_namespace":                  c.Telemetry.StackdriverNamespace, | ||||||
|  | 			"stackdriver_debug_logs":                 c.Telemetry.StackdriverDebugLogs, | ||||||
|  | 		} | ||||||
|  | 		result["telemetry"] = sanitizedTelemetry | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return result | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								internalshared/configutil/config_util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								internalshared/configutil/config_util.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | // +build !enterprise | ||||||
|  |  | ||||||
|  | package configutil | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type EntSharedConfig struct { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *EntSharedConfig) ParseConfig(list *ast.ObjectList) error { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ParseEntropy(result *SharedConfig, list *ast.ObjectList, blockName string) error { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										313
									
								
								internalshared/configutil/kms.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								internalshared/configutil/kms.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,313 @@ | |||||||
|  | // +build !enterprise | ||||||
|  |  | ||||||
|  | package configutil | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	"github.com/hashicorp/go-hclog" | ||||||
|  | 	wrapping "github.com/hashicorp/go-kms-wrapping" | ||||||
|  | 	aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead" | ||||||
|  | 	"github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms" | ||||||
|  | 	"github.com/hashicorp/go-kms-wrapping/wrappers/awskms" | ||||||
|  | 	"github.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault" | ||||||
|  | 	"github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms" | ||||||
|  | 	"github.com/hashicorp/go-kms-wrapping/wrappers/ocikms" | ||||||
|  | 	"github.com/hashicorp/go-kms-wrapping/wrappers/transit" | ||||||
|  | 	"github.com/hashicorp/go-multierror" | ||||||
|  | 	"github.com/hashicorp/hcl" | ||||||
|  | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	ConfigureWrapper             = configureWrapper | ||||||
|  | 	CreateSecureRandomReaderFunc = createSecureRandomReader | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Entropy contains Entropy configuration for the server | ||||||
|  | type EntropyMode int | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	EntropyUnknown EntropyMode = iota | ||||||
|  | 	EntropyAugmentation | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type Entropy struct { | ||||||
|  | 	Mode EntropyMode | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // KMS contains KMS configuration for the server | ||||||
|  | type KMS struct { | ||||||
|  | 	Type string | ||||||
|  | 	// Purpose can be used to allow a string-based specification of what this | ||||||
|  | 	// KMS is designated for, in situations where we want to allow more than | ||||||
|  | 	// one KMS to be specified | ||||||
|  | 	Purpose []string `hcl:"-"` | ||||||
|  |  | ||||||
|  | 	Disabled bool | ||||||
|  | 	Config   map[string]string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (k *KMS) GoString() string { | ||||||
|  | 	return fmt.Sprintf("*%#v", *k) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func parseKMS(result *SharedConfig, list *ast.ObjectList, blockName string, maxKMS int) error { | ||||||
|  | 	if len(list.Items) > maxKMS { | ||||||
|  | 		return fmt.Errorf("only two or less %q blocks are permitted", blockName) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	seals := make([]*KMS, 0, len(list.Items)) | ||||||
|  | 	for _, item := range list.Items { | ||||||
|  | 		key := blockName | ||||||
|  | 		if len(item.Keys) > 0 { | ||||||
|  | 			key = item.Keys[0].Token.Value().(string) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// We first decode into a map[string]interface{} because purpose isn't | ||||||
|  | 		// necessarily a string. Then we migrate everything else over to | ||||||
|  | 		// map[string]string and error if it doesn't work. | ||||||
|  | 		var m map[string]interface{} | ||||||
|  | 		if err := hcl.DecodeObject(&m, item.Val); err != nil { | ||||||
|  | 			return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		var purpose []string | ||||||
|  | 		var err error | ||||||
|  | 		if v, ok := m["purpose"]; ok { | ||||||
|  | 			if purpose, err = parseutil.ParseCommaStringSlice(v); err != nil { | ||||||
|  | 				return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in kms type %q: %w", key, err), fmt.Sprintf("%s.%s:", blockName, key)) | ||||||
|  | 			} | ||||||
|  | 			for i, p := range purpose { | ||||||
|  | 				purpose[i] = strings.ToLower(p) | ||||||
|  | 			} | ||||||
|  | 			delete(m, "purpose") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		var disabled bool | ||||||
|  | 		if v, ok := m["disabled"]; ok { | ||||||
|  | 			disabled, err = parseutil.ParseBool(v) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) | ||||||
|  | 			} | ||||||
|  | 			delete(m, "disabled") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		strMap := make(map[string]string, len(m)) | ||||||
|  | 		for k, v := range m { | ||||||
|  | 			if vs, ok := v.(string); ok { | ||||||
|  | 				strMap[k] = vs | ||||||
|  | 			} else { | ||||||
|  | 				return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in kms type %q: value could not be parsed as string", key), fmt.Sprintf("%s.%s:", blockName, key)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		seal := &KMS{ | ||||||
|  | 			Type:     strings.ToLower(key), | ||||||
|  | 			Purpose:  purpose, | ||||||
|  | 			Disabled: disabled, | ||||||
|  | 		} | ||||||
|  | 		if len(strMap) > 0 { | ||||||
|  | 			seal.Config = strMap | ||||||
|  | 		} | ||||||
|  | 		seals = append(seals, seal) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.Seals = append(result.Seals, seals...) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func configureWrapper(configKMS *KMS, infoKeys *[]string, info *map[string]string, logger hclog.Logger) (wrapping.Wrapper, error) { | ||||||
|  | 	var wrapper wrapping.Wrapper | ||||||
|  | 	var kmsInfo map[string]string | ||||||
|  | 	var err error | ||||||
|  |  | ||||||
|  | 	opts := &wrapping.WrapperOptions{ | ||||||
|  | 		Logger: logger, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch configKMS.Type { | ||||||
|  | 	case wrapping.Shamir: | ||||||
|  | 		return nil, nil | ||||||
|  |  | ||||||
|  | 	case wrapping.AEAD: | ||||||
|  | 		wrapper, kmsInfo, err = GetAEADKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.AliCloudKMS: | ||||||
|  | 		wrapper, kmsInfo, err = GetAliCloudKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.AWSKMS: | ||||||
|  | 		wrapper, kmsInfo, err = GetAWSKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.AzureKeyVault: | ||||||
|  | 		wrapper, kmsInfo, err = GetAzureKeyVaultKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.GCPCKMS: | ||||||
|  | 		wrapper, kmsInfo, err = GetGCPCKMSKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.OCIKMS: | ||||||
|  | 		wrapper, kmsInfo, err = GetOCIKMSKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.Transit: | ||||||
|  | 		wrapper, kmsInfo, err = GetTransitKMSFunc(opts, configKMS) | ||||||
|  |  | ||||||
|  | 	case wrapping.PKCS11: | ||||||
|  | 		return nil, fmt.Errorf("KMS type 'pkcs11' requires the Vault Enterprise HSM binary") | ||||||
|  |  | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf("Unknown KMS type %q", configKMS.Type) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for k, v := range kmsInfo { | ||||||
|  | 		*infoKeys = append(*infoKeys, k) | ||||||
|  | 		(*info)[k] = v | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return wrapper, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetAEADKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := aeadwrapper.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		str := "AEAD Type" | ||||||
|  | 		if len(kms.Purpose) > 0 { | ||||||
|  | 			str = fmt.Sprintf("%v %s", kms.Purpose, str) | ||||||
|  | 		} | ||||||
|  | 		info[str] = wrapperInfo["aead_type"] | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetAliCloudKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := alicloudkms.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// If the error is any other than logical.KeyNotFoundError, return the error | ||||||
|  | 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		info["AliCloud KMS Region"] = wrapperInfo["region"] | ||||||
|  | 		info["AliCloud KMS KeyID"] = wrapperInfo["kms_key_id"] | ||||||
|  | 		if domain, ok := wrapperInfo["domain"]; ok { | ||||||
|  | 			info["AliCloud KMS Domain"] = domain | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetAWSKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := awskms.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// If the error is any other than logical.KeyNotFoundError, return the error | ||||||
|  | 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		info["AWS KMS Region"] = wrapperInfo["region"] | ||||||
|  | 		info["AWS KMS KeyID"] = wrapperInfo["kms_key_id"] | ||||||
|  | 		if endpoint, ok := wrapperInfo["endpoint"]; ok { | ||||||
|  | 			info["AWS KMS Endpoint"] = endpoint | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetAzureKeyVaultKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := azurekeyvault.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// If the error is any other than logical.KeyNotFoundError, return the error | ||||||
|  | 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		info["Azure Environment"] = wrapperInfo["environment"] | ||||||
|  | 		info["Azure Vault Name"] = wrapperInfo["vault_name"] | ||||||
|  | 		info["Azure Key Name"] = wrapperInfo["key_name"] | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetGCPCKMSKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := gcpckms.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// If the error is any other than logical.KeyNotFoundError, return the error | ||||||
|  | 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		info["GCP KMS Project"] = wrapperInfo["project"] | ||||||
|  | 		info["GCP KMS Region"] = wrapperInfo["region"] | ||||||
|  | 		info["GCP KMS Key Ring"] = wrapperInfo["key_ring"] | ||||||
|  | 		info["GCP KMS Crypto Key"] = wrapperInfo["crypto_key"] | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetOCIKMSKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := ocikms.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		info["OCI KMS KeyID"] = wrapperInfo[ocikms.KMSConfigKeyID] | ||||||
|  | 		info["OCI KMS Crypto Endpoint"] = wrapperInfo[ocikms.KMSConfigCryptoEndpoint] | ||||||
|  | 		info["OCI KMS Management Endpoint"] = wrapperInfo[ocikms.KMSConfigManagementEndpoint] | ||||||
|  | 		info["OCI KMS Principal Type"] = wrapperInfo["principal_type"] | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetTransitKMSFunc(opts *wrapping.WrapperOptions, kms *KMS) (wrapping.Wrapper, map[string]string, error) { | ||||||
|  | 	wrapper := transit.NewWrapper(opts) | ||||||
|  | 	wrapperInfo, err := wrapper.SetConfig(kms.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// If the error is any other than logical.KeyNotFoundError, return the error | ||||||
|  | 		if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	info := make(map[string]string) | ||||||
|  | 	if wrapperInfo != nil { | ||||||
|  | 		info["Transit Address"] = wrapperInfo["address"] | ||||||
|  | 		info["Transit Mount Path"] = wrapperInfo["mount_path"] | ||||||
|  | 		info["Transit Key Name"] = wrapperInfo["key_name"] | ||||||
|  | 		if namespace, ok := wrapperInfo["namespace"]; ok { | ||||||
|  | 			info["Transit Namespace"] = namespace | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return wrapper, info, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func createSecureRandomReader(conf *SharedConfig, wrapper wrapping.Wrapper) (io.Reader, error) { | ||||||
|  | 	return rand.Reader, nil | ||||||
|  | } | ||||||
							
								
								
									
										315
									
								
								internalshared/configutil/listener.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								internalshared/configutil/listener.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,315 @@ | |||||||
|  | package configutil | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-multierror" | ||||||
|  | 	"github.com/hashicorp/go-sockaddr" | ||||||
|  | 	"github.com/hashicorp/hcl" | ||||||
|  | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/tlsutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type ListenerTelemetry struct { | ||||||
|  | 	UnauthenticatedMetricsAccess    bool        `hcl:"-"` | ||||||
|  | 	UnauthenticatedMetricsAccessRaw interface{} `hcl:"unauthenticated_metrics_access"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Listener is the listener configuration for the server. | ||||||
|  | type Listener struct { | ||||||
|  | 	RawConfig map[string]interface{} | ||||||
|  |  | ||||||
|  | 	Type       string | ||||||
|  | 	Purpose    []string    `hcl:"-"` | ||||||
|  | 	PurposeRaw interface{} `hcl:"purpose"` | ||||||
|  |  | ||||||
|  | 	Address                 string        `hcl:"address"` | ||||||
|  | 	ClusterAddress          string        `hcl:"cluster_address"` | ||||||
|  | 	MaxRequestSize          int64         `hcl:"-"` | ||||||
|  | 	MaxRequestSizeRaw       interface{}   `hcl:"max_request_size"` | ||||||
|  | 	MaxRequestDuration      time.Duration `hcl:"-"` | ||||||
|  | 	MaxRequestDurationRaw   interface{}   `hcl:"max_request_duration"` | ||||||
|  | 	RequireRequestHeader    bool          `hcl:"-"` | ||||||
|  | 	RequireRequestHeaderRaw interface{}   `hcl:"require_request_header"` | ||||||
|  |  | ||||||
|  | 	TLSDisable                       bool        `hcl:"-"` | ||||||
|  | 	TLSDisableRaw                    interface{} `hcl:"tls_disable"` | ||||||
|  | 	TLSCertFile                      string      `hcl:"tls_cert_file"` | ||||||
|  | 	TLSKeyFile                       string      `hcl:"tls_key_file"` | ||||||
|  | 	TLSMinVersion                    string      `hcl:"tls_min_version"` | ||||||
|  | 	TLSCipherSuites                  []uint16    `hcl:"-"` | ||||||
|  | 	TLSCipherSuitesRaw               string      `hcl:"tls_cipher_suites"` | ||||||
|  | 	TLSPreferServerCipherSuites      bool        `hcl:"-"` | ||||||
|  | 	TLSPreferServerCipherSuitesRaw   interface{} `hcl:"tls_prefer_server_cipher_suites"` | ||||||
|  | 	TLSRequireAndVerifyClientCert    bool        `hcl:"-"` | ||||||
|  | 	TLSRequireAndVerifyClientCertRaw interface{} `hcl:"tls_require_and_verify_client_cert"` | ||||||
|  | 	TLSClientCAFile                  string      `hcl:"tls_client_ca_file"` | ||||||
|  | 	TLSDisableClientCerts            bool        `hcl:"-"` | ||||||
|  | 	TLSDisableClientCertsRaw         interface{} `hcl:"tls_disable_client_certs"` | ||||||
|  |  | ||||||
|  | 	HTTPReadTimeout          time.Duration `hcl:"-"` | ||||||
|  | 	HTTPReadTimeoutRaw       interface{}   `hcl:"http_read_timeout"` | ||||||
|  | 	HTTPReadHeaderTimeout    time.Duration `hcl:"-"` | ||||||
|  | 	HTTPReadHeaderTimeoutRaw interface{}   `hcl:"http_read_header_timeout"` | ||||||
|  | 	HTTPWriteTimeout         time.Duration `hcl:"-"` | ||||||
|  | 	HTTPWriteTimeoutRaw      interface{}   `hcl:"http_write_timeout"` | ||||||
|  | 	HTTPIdleTimeout          time.Duration `hcl:"-"` | ||||||
|  | 	HTTPIdleTimeoutRaw       interface{}   `hcl:"http_idle_timeout"` | ||||||
|  |  | ||||||
|  | 	ProxyProtocolBehavior           string                        `hcl:"proxy_protocol_behavior"` | ||||||
|  | 	ProxyProtocolAuthorizedAddrs    []*sockaddr.SockAddrMarshaler `hcl:"-"` | ||||||
|  | 	ProxyProtocolAuthorizedAddrsRaw interface{}                   `hcl:"proxy_protocol_authorized_addrs"` | ||||||
|  |  | ||||||
|  | 	XForwardedForAuthorizedAddrs        []*sockaddr.SockAddrMarshaler `hcl:"-"` | ||||||
|  | 	XForwardedForAuthorizedAddrsRaw     interface{}                   `hcl:"x_forwarded_for_authorized_addrs"` | ||||||
|  | 	XForwardedForHopSkips               int64                         `hcl:"-"` | ||||||
|  | 	XForwardedForHopSkipsRaw            interface{}                   `hcl:"x_forwarded_for_hop_skips"` | ||||||
|  | 	XForwardedForRejectNotPresent       bool                          `hcl:"-"` | ||||||
|  | 	XForwardedForRejectNotPresentRaw    interface{}                   `hcl:"x_forwarded_for_reject_not_present"` | ||||||
|  | 	XForwardedForRejectNotAuthorized    bool                          `hcl:"-"` | ||||||
|  | 	XForwardedForRejectNotAuthorizedRaw interface{}                   `hcl:"x_forwarded_for_reject_not_authorized"` | ||||||
|  |  | ||||||
|  | 	SocketMode  string `hcl:"socket_mode"` | ||||||
|  | 	SocketUser  string `hcl:"socket_user"` | ||||||
|  | 	SocketGroup string `hcl:"socket_group"` | ||||||
|  |  | ||||||
|  | 	Telemetry ListenerTelemetry `hcl:"telemetry"` | ||||||
|  |  | ||||||
|  | 	// RandomPort is used only for some testing purposes | ||||||
|  | 	RandomPort bool `hcl:"-"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Listener) GoString() string { | ||||||
|  | 	return fmt.Sprintf("*%#v", *l) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ParseListeners(result *SharedConfig, list *ast.ObjectList) error { | ||||||
|  | 	var err error | ||||||
|  | 	result.Listeners = make([]*Listener, 0, len(list.Items)) | ||||||
|  | 	for i, item := range list.Items { | ||||||
|  | 		var l Listener | ||||||
|  | 		if err := hcl.DecodeObject(&l, item.Val); err != nil { | ||||||
|  | 			return multierror.Prefix(err, fmt.Sprintf("listeners.%d:", i)) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Hacky way, for now, to get the values we want for sanitizing | ||||||
|  | 		var m map[string]interface{} | ||||||
|  | 		if err := hcl.DecodeObject(&m, item.Val); err != nil { | ||||||
|  | 			return multierror.Prefix(err, fmt.Sprintf("listeners.%d:", i)) | ||||||
|  | 		} | ||||||
|  | 		l.RawConfig = m | ||||||
|  |  | ||||||
|  | 		// Base values | ||||||
|  | 		{ | ||||||
|  | 			switch { | ||||||
|  | 			case l.Type != "": | ||||||
|  | 			case len(item.Keys) == 1: | ||||||
|  | 				l.Type = strings.ToLower(item.Keys[0].Token.Value().(string)) | ||||||
|  | 			default: | ||||||
|  | 				return multierror.Prefix(errors.New("listener type must be specified"), fmt.Sprintf("listeners.%d:", i)) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			l.Type = strings.ToLower(l.Type) | ||||||
|  | 			switch l.Type { | ||||||
|  | 			case "tcp", "unix": | ||||||
|  | 			default: | ||||||
|  | 				return multierror.Prefix(fmt.Errorf("unsupported listener type %q", l.Type), fmt.Sprintf("listeners.%d:", i)) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.PurposeRaw != nil { | ||||||
|  | 				if l.Purpose, err = parseutil.ParseCommaStringSlice(l.PurposeRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in listener type %q: %w", l.Type, err), fmt.Sprintf("listeners.%d:", i)) | ||||||
|  | 				} | ||||||
|  | 				for i, v := range l.Purpose { | ||||||
|  | 					l.Purpose[i] = strings.ToLower(v) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Request Parameters | ||||||
|  | 		{ | ||||||
|  | 			if l.MaxRequestSizeRaw != nil { | ||||||
|  | 				if l.MaxRequestSize, err = parseutil.ParseInt(l.MaxRequestSizeRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing max_request_size: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if l.MaxRequestSize < 0 { | ||||||
|  | 					return multierror.Prefix(errors.New("max_request_size cannot be negative"), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.MaxRequestSizeRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.MaxRequestDurationRaw != nil { | ||||||
|  | 				if l.MaxRequestDuration, err = parseutil.ParseDurationSecond(l.MaxRequestDurationRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing max_request_duration: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  | 				if l.MaxRequestDuration < 0 { | ||||||
|  | 					return multierror.Prefix(errors.New("max_request_duration cannot be negative"), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.MaxRequestDurationRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.RequireRequestHeaderRaw != nil { | ||||||
|  | 				if l.RequireRequestHeader, err = parseutil.ParseBool(l.RequireRequestHeaderRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for require_request_header: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.RequireRequestHeaderRaw = nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// TLS Parameters | ||||||
|  | 		{ | ||||||
|  | 			if l.TLSDisableRaw != nil { | ||||||
|  | 				if l.TLSDisable, err = parseutil.ParseBool(l.TLSDisableRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for tls_disable: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.TLSDisableRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.TLSCipherSuitesRaw != "" { | ||||||
|  | 				if l.TLSCipherSuites, err = tlsutil.ParseCiphers(l.TLSCipherSuitesRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for tls_cipher_suites: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.TLSPreferServerCipherSuitesRaw != nil { | ||||||
|  | 				if l.TLSPreferServerCipherSuites, err = parseutil.ParseBool(l.TLSPreferServerCipherSuitesRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for tls_prefer_server_cipher_suites: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.TLSPreferServerCipherSuitesRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.TLSRequireAndVerifyClientCertRaw != nil { | ||||||
|  | 				if l.TLSRequireAndVerifyClientCert, err = parseutil.ParseBool(l.TLSRequireAndVerifyClientCertRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for tls_require_and_verify_client_cert: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.TLSRequireAndVerifyClientCertRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.TLSDisableClientCertsRaw != nil { | ||||||
|  | 				if l.TLSDisableClientCerts, err = parseutil.ParseBool(l.TLSDisableClientCertsRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for tls_disable_client_certs: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.TLSDisableClientCertsRaw = nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// HTTP timeouts | ||||||
|  | 		{ | ||||||
|  | 			if l.HTTPReadTimeoutRaw != nil { | ||||||
|  | 				if l.HTTPReadTimeout, err = parseutil.ParseDurationSecond(l.HTTPReadTimeoutRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing http_read_timeout: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.HTTPReadTimeoutRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.HTTPReadHeaderTimeoutRaw != nil { | ||||||
|  | 				if l.HTTPReadHeaderTimeout, err = parseutil.ParseDurationSecond(l.HTTPReadHeaderTimeoutRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing http_read_header_timeout: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.HTTPReadHeaderTimeoutRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.HTTPWriteTimeoutRaw != nil { | ||||||
|  | 				if l.HTTPWriteTimeout, err = parseutil.ParseDurationSecond(l.HTTPWriteTimeoutRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing http_write_timeout: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.HTTPWriteTimeoutRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.HTTPIdleTimeoutRaw != nil { | ||||||
|  | 				if l.HTTPIdleTimeout, err = parseutil.ParseDurationSecond(l.HTTPIdleTimeoutRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing http_idle_timeout: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.HTTPIdleTimeoutRaw = nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Proxy Protocol config | ||||||
|  | 		{ | ||||||
|  | 			if l.ProxyProtocolAuthorizedAddrsRaw != nil { | ||||||
|  | 				if l.ProxyProtocolAuthorizedAddrs, err = parseutil.ParseAddrs(l.ProxyProtocolAuthorizedAddrsRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing proxy_protocol_authorized_addrs: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				switch l.ProxyProtocolBehavior { | ||||||
|  | 				case "allow_authorized", "deny_authorized": | ||||||
|  | 					if len(l.ProxyProtocolAuthorizedAddrs) == 0 { | ||||||
|  | 						return multierror.Prefix(errors.New("proxy_protocol_behavior set to allow or deny only authorized addresses but no proxy_protocol_authorized_addrs value"), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.ProxyProtocolAuthorizedAddrsRaw = nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// X-Forwarded-For config | ||||||
|  | 		{ | ||||||
|  | 			if l.XForwardedForAuthorizedAddrsRaw != nil { | ||||||
|  | 				if l.XForwardedForAuthorizedAddrs, err = parseutil.ParseAddrs(l.XForwardedForAuthorizedAddrsRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing x_forwarded_for_authorized_addrs: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.XForwardedForAuthorizedAddrsRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.XForwardedForHopSkipsRaw != nil { | ||||||
|  | 				if l.XForwardedForHopSkips, err = parseutil.ParseInt(l.XForwardedForHopSkipsRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("error parsing x_forwarded_for_hop_skips: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if l.XForwardedForHopSkips < 0 { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("x_forwarded_for_hop_skips cannot be negative but set to %d", l.XForwardedForHopSkips), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.XForwardedForHopSkipsRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.XForwardedForRejectNotAuthorizedRaw != nil { | ||||||
|  | 				if l.XForwardedForRejectNotAuthorized, err = parseutil.ParseBool(l.XForwardedForRejectNotAuthorizedRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for x_forwarded_for_reject_not_authorized: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.XForwardedForRejectNotAuthorizedRaw = nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if l.XForwardedForRejectNotPresentRaw != nil { | ||||||
|  | 				if l.XForwardedForRejectNotPresent, err = parseutil.ParseBool(l.XForwardedForRejectNotPresentRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for x_forwarded_for_reject_not_present: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.XForwardedForRejectNotPresentRaw = nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Telemetry | ||||||
|  | 		{ | ||||||
|  | 			if l.Telemetry.UnauthenticatedMetricsAccessRaw != nil { | ||||||
|  | 				if l.Telemetry.UnauthenticatedMetricsAccess, err = parseutil.ParseBool(l.Telemetry.UnauthenticatedMetricsAccessRaw); err != nil { | ||||||
|  | 					return multierror.Prefix(fmt.Errorf("invalid value for telemetry.unauthenticated_metrics_access: %w", err), fmt.Sprintf("listeners.%d", i)) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				l.Telemetry.UnauthenticatedMetricsAccessRaw = nil | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		result.Listeners = append(result.Listeners, &l) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										65
									
								
								internalshared/configutil/merge.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								internalshared/configutil/merge.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | package configutil | ||||||
|  |  | ||||||
|  | func (c *SharedConfig) Merge(c2 *SharedConfig) *SharedConfig { | ||||||
|  | 	if c2 == nil { | ||||||
|  | 		return c | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result := new(SharedConfig) | ||||||
|  |  | ||||||
|  | 	for _, l := range c.Listeners { | ||||||
|  | 		result.Listeners = append(result.Listeners, l) | ||||||
|  | 	} | ||||||
|  | 	for _, l := range c2.Listeners { | ||||||
|  | 		result.Listeners = append(result.Listeners, l) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.Entropy = c.Entropy | ||||||
|  | 	if c2.Entropy != nil { | ||||||
|  | 		result.Entropy = c2.Entropy | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, s := range c.Seals { | ||||||
|  | 		result.Seals = append(result.Seals, s) | ||||||
|  | 	} | ||||||
|  | 	for _, s := range c2.Seals { | ||||||
|  | 		result.Seals = append(result.Seals, s) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.Telemetry = c.Telemetry | ||||||
|  | 	if c2.Telemetry != nil { | ||||||
|  | 		result.Telemetry = c2.Telemetry | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.DisableMlock = c.DisableMlock | ||||||
|  | 	if c2.DisableMlock { | ||||||
|  | 		result.DisableMlock = c2.DisableMlock | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.DefaultMaxRequestDuration = c.DefaultMaxRequestDuration | ||||||
|  | 	if c2.DefaultMaxRequestDuration > result.DefaultMaxRequestDuration { | ||||||
|  | 		result.DefaultMaxRequestDuration = c2.DefaultMaxRequestDuration | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.LogLevel = c.LogLevel | ||||||
|  | 	if c2.LogLevel != "" { | ||||||
|  | 		result.LogLevel = c2.LogLevel | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.LogFormat = c.LogFormat | ||||||
|  | 	if c2.LogFormat != "" { | ||||||
|  | 		result.LogFormat = c2.LogFormat | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.PidFile = c.PidFile | ||||||
|  | 	if c2.PidFile != "" { | ||||||
|  | 		result.PidFile = c2.PidFile | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	result.ClusterName = c.ClusterName | ||||||
|  | 	if c2.ClusterName != "" { | ||||||
|  | 		result.ClusterName = c2.ClusterName | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return result | ||||||
|  | } | ||||||
							
								
								
									
										339
									
								
								internalshared/configutil/telemetry.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								internalshared/configutil/telemetry.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,339 @@ | |||||||
|  | package configutil | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	monitoring "cloud.google.com/go/monitoring/apiv3" | ||||||
|  | 	"github.com/armon/go-metrics" | ||||||
|  | 	"github.com/armon/go-metrics/circonus" | ||||||
|  | 	"github.com/armon/go-metrics/datadog" | ||||||
|  | 	"github.com/armon/go-metrics/prometheus" | ||||||
|  | 	stackdriver "github.com/google/go-metrics-stackdriver" | ||||||
|  | 	stackdrivervault "github.com/google/go-metrics-stackdriver/vault" | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	"github.com/hashicorp/go-multierror" | ||||||
|  | 	"github.com/hashicorp/hcl" | ||||||
|  | 	"github.com/hashicorp/hcl/hcl/ast" | ||||||
|  | 	"github.com/hashicorp/vault/helper/metricsutil" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/parseutil" | ||||||
|  | 	"github.com/mitchellh/cli" | ||||||
|  | 	"google.golang.org/api/option" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	PrometheusDefaultRetentionTime = 24 * time.Hour | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Telemetry is the telemetry configuration for the server | ||||||
|  | type Telemetry struct { | ||||||
|  | 	StatsiteAddr string `hcl:"statsite_address"` | ||||||
|  | 	StatsdAddr   string `hcl:"statsd_address"` | ||||||
|  |  | ||||||
|  | 	DisableHostname     bool   `hcl:"disable_hostname"` | ||||||
|  | 	EnableHostnameLabel bool   `hcl:"enable_hostname_label"` | ||||||
|  | 	MetricsPrefix       string `hcl:"metrics_prefix"` | ||||||
|  |  | ||||||
|  | 	// Circonus: see https://github.com/circonus-labs/circonus-gometrics | ||||||
|  | 	// for more details on the various configuration options. | ||||||
|  | 	// Valid configuration combinations: | ||||||
|  | 	//    - CirconusAPIToken | ||||||
|  | 	//      metric management enabled (search for existing check or create a new one) | ||||||
|  | 	//    - CirconusSubmissionUrl | ||||||
|  | 	//      metric management disabled (use check with specified submission_url, | ||||||
|  | 	//      broker must be using a public SSL certificate) | ||||||
|  | 	//    - CirconusAPIToken + CirconusCheckSubmissionURL | ||||||
|  | 	//      metric management enabled (use check with specified submission_url) | ||||||
|  | 	//    - CirconusAPIToken + CirconusCheckID | ||||||
|  | 	//      metric management enabled (use check with specified id) | ||||||
|  |  | ||||||
|  | 	// CirconusAPIToken is a valid API Token used to create/manage check. If provided, | ||||||
|  | 	// metric management is enabled. | ||||||
|  | 	// Default: none | ||||||
|  | 	CirconusAPIToken string `hcl:"circonus_api_token"` | ||||||
|  | 	// CirconusAPIApp is an app name associated with API token. | ||||||
|  | 	// Default: "consul" | ||||||
|  | 	CirconusAPIApp string `hcl:"circonus_api_app"` | ||||||
|  | 	// CirconusAPIURL is the base URL to use for contacting the Circonus API. | ||||||
|  | 	// Default: "https://api.circonus.com/v2" | ||||||
|  | 	CirconusAPIURL string `hcl:"circonus_api_url"` | ||||||
|  | 	// CirconusSubmissionInterval is the interval at which metrics are submitted to Circonus. | ||||||
|  | 	// Default: 10s | ||||||
|  | 	CirconusSubmissionInterval string `hcl:"circonus_submission_interval"` | ||||||
|  | 	// CirconusCheckSubmissionURL is the check.config.submission_url field from a | ||||||
|  | 	// previously created HTTPTRAP check. | ||||||
|  | 	// Default: none | ||||||
|  | 	CirconusCheckSubmissionURL string `hcl:"circonus_submission_url"` | ||||||
|  | 	// CirconusCheckID is the check id (not check bundle id) from a previously created | ||||||
|  | 	// HTTPTRAP check. The numeric portion of the check._cid field. | ||||||
|  | 	// Default: none | ||||||
|  | 	CirconusCheckID string `hcl:"circonus_check_id"` | ||||||
|  | 	// CirconusCheckForceMetricActivation will force enabling metrics, as they are encountered, | ||||||
|  | 	// if the metric already exists and is NOT active. If check management is enabled, the default | ||||||
|  | 	// behavior is to add new metrics as they are encountered. If the metric already exists in the | ||||||
|  | 	// check, it will *NOT* be activated. This setting overrides that behavior. | ||||||
|  | 	// Default: "false" | ||||||
|  | 	CirconusCheckForceMetricActivation string `hcl:"circonus_check_force_metric_activation"` | ||||||
|  | 	// CirconusCheckInstanceID serves to uniquely identify the metrics coming from this "instance". | ||||||
|  | 	// It can be used to maintain metric continuity with transient or ephemeral instances as | ||||||
|  | 	// they move around within an infrastructure. | ||||||
|  | 	// Default: hostname:app | ||||||
|  | 	CirconusCheckInstanceID string `hcl:"circonus_check_instance_id"` | ||||||
|  | 	// CirconusCheckSearchTag is a special tag which, when coupled with the instance id, helps to | ||||||
|  | 	// narrow down the search results when neither a Submission URL or Check ID is provided. | ||||||
|  | 	// Default: service:app (e.g. service:consul) | ||||||
|  | 	CirconusCheckSearchTag string `hcl:"circonus_check_search_tag"` | ||||||
|  | 	// CirconusCheckTags is a comma separated list of tags to apply to the check. Note that | ||||||
|  | 	// the value of CirconusCheckSearchTag will always be added to the check. | ||||||
|  | 	// Default: none | ||||||
|  | 	CirconusCheckTags string `hcl:"circonus_check_tags"` | ||||||
|  | 	// CirconusCheckDisplayName is the name for the check which will be displayed in the Circonus UI. | ||||||
|  | 	// Default: value of CirconusCheckInstanceID | ||||||
|  | 	CirconusCheckDisplayName string `hcl:"circonus_check_display_name"` | ||||||
|  | 	// CirconusBrokerID is an explicit broker to use when creating a new check. The numeric portion | ||||||
|  | 	// of broker._cid. If metric management is enabled and neither a Submission URL nor Check ID | ||||||
|  | 	// is provided, an attempt will be made to search for an existing check using Instance ID and | ||||||
|  | 	// Search Tag. If one is not found, a new HTTPTRAP check will be created. | ||||||
|  | 	// Default: use Select Tag if provided, otherwise, a random Enterprise Broker associated | ||||||
|  | 	// with the specified API token or the default Circonus Broker. | ||||||
|  | 	// Default: none | ||||||
|  | 	CirconusBrokerID string `hcl:"circonus_broker_id"` | ||||||
|  | 	// CirconusBrokerSelectTag is a special tag which will be used to select a broker when | ||||||
|  | 	// a Broker ID is not provided. The best use of this is to as a hint for which broker | ||||||
|  | 	// should be used based on *where* this particular instance is running. | ||||||
|  | 	// (e.g. a specific geo location or datacenter, dc:sfo) | ||||||
|  | 	// Default: none | ||||||
|  | 	CirconusBrokerSelectTag string `hcl:"circonus_broker_select_tag"` | ||||||
|  |  | ||||||
|  | 	// Dogstats: | ||||||
|  | 	// DogStatsdAddr is the address of a dogstatsd instance. If provided, | ||||||
|  | 	// metrics will be sent to that instance | ||||||
|  | 	DogStatsDAddr string `hcl:"dogstatsd_addr"` | ||||||
|  |  | ||||||
|  | 	// DogStatsdTags are the global tags that should be sent with each packet to dogstatsd | ||||||
|  | 	// It is a list of strings, where each string looks like "my_tag_name:my_tag_value" | ||||||
|  | 	DogStatsDTags []string `hcl:"dogstatsd_tags"` | ||||||
|  |  | ||||||
|  | 	// Prometheus: | ||||||
|  | 	// PrometheusRetentionTime is the retention time for prometheus metrics if greater than 0. | ||||||
|  | 	// Default: 24h | ||||||
|  | 	PrometheusRetentionTime    time.Duration `hcl:"-"` | ||||||
|  | 	PrometheusRetentionTimeRaw interface{}   `hcl:"prometheus_retention_time"` | ||||||
|  |  | ||||||
|  | 	// Stackdriver: | ||||||
|  | 	// StackdriverProjectID is the project to publish stackdriver metrics to. | ||||||
|  | 	StackdriverProjectID string `hcl:"stackdriver_project_id"` | ||||||
|  | 	// StackdriverLocation is the GCP or AWS region of the monitored resource. | ||||||
|  | 	StackdriverLocation string `hcl:"stackdriver_location"` | ||||||
|  | 	// StackdriverNamespace is the namespace identifier, such as a cluster name. | ||||||
|  | 	StackdriverNamespace string `hcl:"stackdriver_namespace"` | ||||||
|  | 	// StackdriverDebugLogs will write additional stackdriver related debug logs to stderr. | ||||||
|  | 	StackdriverDebugLogs bool `hcl:"stackdriver_debug_logs"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (t *Telemetry) GoString() string { | ||||||
|  | 	return fmt.Sprintf("*%#v", *t) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func parseTelemetry(result *SharedConfig, list *ast.ObjectList) error { | ||||||
|  | 	if len(list.Items) > 1 { | ||||||
|  | 		return fmt.Errorf("only one 'telemetry' block is permitted") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get our one item | ||||||
|  | 	item := list.Items[0] | ||||||
|  |  | ||||||
|  | 	var t Telemetry | ||||||
|  | 	if err := hcl.DecodeObject(&t, item.Val); err != nil { | ||||||
|  | 		return multierror.Prefix(err, "telemetry:") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if result.Telemetry == nil { | ||||||
|  | 		result.Telemetry = &Telemetry{} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := hcl.DecodeObject(&result.Telemetry, item.Val); err != nil { | ||||||
|  | 		return multierror.Prefix(err, "telemetry:") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if result.Telemetry.PrometheusRetentionTimeRaw != nil { | ||||||
|  | 		var err error | ||||||
|  | 		if result.Telemetry.PrometheusRetentionTime, err = parseutil.ParseDurationSecond(result.Telemetry.PrometheusRetentionTimeRaw); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		result.Telemetry.PrometheusRetentionTimeRaw = nil | ||||||
|  | 	} else { | ||||||
|  | 		result.Telemetry.PrometheusRetentionTime = PrometheusDefaultRetentionTime | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type SetupTelemetryOpts struct { | ||||||
|  | 	Config      *Telemetry | ||||||
|  | 	Ui          cli.Ui | ||||||
|  | 	ServiceName string | ||||||
|  | 	DisplayName string | ||||||
|  | 	UserAgent   string | ||||||
|  | 	ClusterName string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SetupTelemetry is used to setup the telemetry sub-systems and returns the | ||||||
|  | // in-memory sink to be used in http configuration | ||||||
|  | func SetupTelemetry(opts *SetupTelemetryOpts) (*metrics.InmemSink, *metricsutil.ClusterMetricSink, bool, error) { | ||||||
|  | 	if opts == nil { | ||||||
|  | 		return nil, nil, false, errors.New("nil opts passed into SetupTelemetry") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if opts.Config == nil { | ||||||
|  | 		opts.Config = &Telemetry{} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* Setup telemetry | ||||||
|  | 	Aggregate on 10 second intervals for 1 minute. Expose the | ||||||
|  | 	metrics over stderr when there is a SIGUSR1 received. | ||||||
|  | 	*/ | ||||||
|  | 	inm := metrics.NewInmemSink(10*time.Second, time.Minute) | ||||||
|  | 	metrics.DefaultInmemSignal(inm) | ||||||
|  |  | ||||||
|  | 	if opts.Config.MetricsPrefix != "" { | ||||||
|  | 		opts.ServiceName = opts.Config.MetricsPrefix | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	metricsConf := metrics.DefaultConfig(opts.ServiceName) | ||||||
|  | 	metricsConf.EnableHostname = !opts.Config.DisableHostname | ||||||
|  | 	metricsConf.EnableHostnameLabel = opts.Config.EnableHostnameLabel | ||||||
|  |  | ||||||
|  | 	// Configure the statsite sink | ||||||
|  | 	var fanout metrics.FanoutSink | ||||||
|  | 	var prometheusEnabled bool | ||||||
|  |  | ||||||
|  | 	// Configure the Prometheus sink | ||||||
|  | 	if opts.Config.PrometheusRetentionTime != 0 { | ||||||
|  | 		prometheusEnabled = true | ||||||
|  | 		prometheusOpts := prometheus.PrometheusOpts{ | ||||||
|  | 			Expiration: opts.Config.PrometheusRetentionTime, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		sink, err := prometheus.NewPrometheusSinkFrom(prometheusOpts) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, false, err | ||||||
|  | 		} | ||||||
|  | 		fanout = append(fanout, sink) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if opts.Config.StatsiteAddr != "" { | ||||||
|  | 		sink, err := metrics.NewStatsiteSink(opts.Config.StatsiteAddr) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, false, err | ||||||
|  | 		} | ||||||
|  | 		fanout = append(fanout, sink) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Configure the statsd sink | ||||||
|  | 	if opts.Config.StatsdAddr != "" { | ||||||
|  | 		sink, err := metrics.NewStatsdSink(opts.Config.StatsdAddr) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, false, err | ||||||
|  | 		} | ||||||
|  | 		fanout = append(fanout, sink) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Configure the Circonus sink | ||||||
|  | 	if opts.Config.CirconusAPIToken != "" || opts.Config.CirconusCheckSubmissionURL != "" { | ||||||
|  | 		cfg := &circonus.Config{} | ||||||
|  | 		cfg.Interval = opts.Config.CirconusSubmissionInterval | ||||||
|  | 		cfg.CheckManager.API.TokenKey = opts.Config.CirconusAPIToken | ||||||
|  | 		cfg.CheckManager.API.TokenApp = opts.Config.CirconusAPIApp | ||||||
|  | 		cfg.CheckManager.API.URL = opts.Config.CirconusAPIURL | ||||||
|  | 		cfg.CheckManager.Check.SubmissionURL = opts.Config.CirconusCheckSubmissionURL | ||||||
|  | 		cfg.CheckManager.Check.ID = opts.Config.CirconusCheckID | ||||||
|  | 		cfg.CheckManager.Check.ForceMetricActivation = opts.Config.CirconusCheckForceMetricActivation | ||||||
|  | 		cfg.CheckManager.Check.InstanceID = opts.Config.CirconusCheckInstanceID | ||||||
|  | 		cfg.CheckManager.Check.SearchTag = opts.Config.CirconusCheckSearchTag | ||||||
|  | 		cfg.CheckManager.Check.DisplayName = opts.Config.CirconusCheckDisplayName | ||||||
|  | 		cfg.CheckManager.Check.Tags = opts.Config.CirconusCheckTags | ||||||
|  | 		cfg.CheckManager.Broker.ID = opts.Config.CirconusBrokerID | ||||||
|  | 		cfg.CheckManager.Broker.SelectTag = opts.Config.CirconusBrokerSelectTag | ||||||
|  |  | ||||||
|  | 		if cfg.CheckManager.API.TokenApp == "" { | ||||||
|  | 			cfg.CheckManager.API.TokenApp = opts.ServiceName | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if cfg.CheckManager.Check.DisplayName == "" { | ||||||
|  | 			cfg.CheckManager.Check.DisplayName = opts.DisplayName | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if cfg.CheckManager.Check.SearchTag == "" { | ||||||
|  | 			cfg.CheckManager.Check.SearchTag = fmt.Sprintf("service:%s", opts.ServiceName) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		sink, err := circonus.NewCirconusSink(cfg) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, false, err | ||||||
|  | 		} | ||||||
|  | 		sink.Start() | ||||||
|  | 		fanout = append(fanout, sink) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if opts.Config.DogStatsDAddr != "" { | ||||||
|  | 		var tags []string | ||||||
|  |  | ||||||
|  | 		if opts.Config.DogStatsDTags != nil { | ||||||
|  | 			tags = opts.Config.DogStatsDTags | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		sink, err := datadog.NewDogStatsdSink(opts.Config.DogStatsDAddr, metricsConf.HostName) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, false, errwrap.Wrapf("failed to start DogStatsD sink: {{err}}", err) | ||||||
|  | 		} | ||||||
|  | 		sink.SetTags(tags) | ||||||
|  | 		fanout = append(fanout, sink) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Configure the stackdriver sink | ||||||
|  | 	if opts.Config.StackdriverProjectID != "" { | ||||||
|  | 		client, err := monitoring.NewMetricClient(context.Background(), option.WithUserAgent(opts.UserAgent)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, false, fmt.Errorf("Failed to create stackdriver client: %v", err) | ||||||
|  | 		} | ||||||
|  | 		sink := stackdriver.NewSink(client, &stackdriver.Config{ | ||||||
|  | 			LabelExtractor: stackdrivervault.Extractor, | ||||||
|  | 			Bucketer:       stackdrivervault.Bucketer, | ||||||
|  | 			ProjectID:      opts.Config.StackdriverProjectID, | ||||||
|  | 			Location:       opts.Config.StackdriverLocation, | ||||||
|  | 			Namespace:      opts.Config.StackdriverNamespace, | ||||||
|  | 			DebugLogs:      opts.Config.StackdriverDebugLogs, | ||||||
|  | 		}) | ||||||
|  | 		fanout = append(fanout, sink) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Initialize the global sink | ||||||
|  | 	if len(fanout) > 1 { | ||||||
|  | 		// Hostname enabled will create poor quality metrics name for prometheus | ||||||
|  | 		if !opts.Config.DisableHostname { | ||||||
|  | 			opts.Ui.Warn("telemetry.disable_hostname has been set to false. Recommended setting is true for Prometheus to avoid poorly named metrics.") | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		metricsConf.EnableHostname = false | ||||||
|  | 	} | ||||||
|  | 	fanout = append(fanout, inm) | ||||||
|  | 	_, err := metrics.NewGlobal(metricsConf, fanout) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, false, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Intialize a wrapper around the global sink; this will be passed to Core | ||||||
|  | 	// and to any backend. | ||||||
|  | 	wrapper := &metricsutil.ClusterMetricSink{ | ||||||
|  | 		ClusterName:         opts.ClusterName, | ||||||
|  | 		MaxGaugeCardinality: 500, | ||||||
|  | 		GaugeInterval:       10 * time.Minute, | ||||||
|  | 		Sink:                fanout, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return inm, wrapper, prometheusEnabled, nil | ||||||
|  | } | ||||||
| @@ -11,13 +11,18 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/internalshared/reloadutil" | 	"github.com/hashicorp/vault/internalshared/reloadutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/parseutil" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/tlsutil" | 	"github.com/hashicorp/vault/sdk/helper/tlsutil" | ||||||
| 	"github.com/jefferai/isbadcipher" | 	"github.com/jefferai/isbadcipher" | ||||||
| 	"github.com/mitchellh/cli" | 	"github.com/mitchellh/cli" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | type Listener struct { | ||||||
|  | 	net.Listener | ||||||
|  | 	Config *configutil.Listener | ||||||
|  | } | ||||||
|  |  | ||||||
| type UnixSocketsConfig struct { | type UnixSocketsConfig struct { | ||||||
| 	User  string `hcl:"user"` | 	User  string `hcl:"user"` | ||||||
| 	Mode  string `hcl:"mode"` | 	Mode  string `hcl:"mode"` | ||||||
| @@ -67,92 +72,69 @@ func UnixSocketListener(path string, unixSocketsConfig *UnixSocketsConfig) (net. | |||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func WrapTLS( | func TLSConfig( | ||||||
| 	ln net.Listener, | 	l *configutil.Listener, | ||||||
| 	props map[string]string, | 	props map[string]string, | ||||||
| 	config map[string]interface{}, | 	ui cli.Ui) (*tls.Config, reloadutil.ReloadFunc, error) { | ||||||
| 	ui cli.Ui) (net.Listener, map[string]string, reloadutil.ReloadFunc, *tls.Config, error) { |  | ||||||
| 	props["tls"] = "disabled" | 	props["tls"] = "disabled" | ||||||
|  |  | ||||||
| 	if v, ok := config["tls_disable"]; ok { | 	if l.TLSDisable { | ||||||
| 		disabled, err := parseutil.ParseBool(v) | 		return nil, nil, nil | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, nil, nil, errwrap.Wrapf("invalid value for 'tls_disable': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		if disabled { |  | ||||||
| 			return ln, props, nil, nil, nil |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	certFileRaw, ok := config["tls_cert_file"] | 	cg := reloadutil.NewCertificateGetter(l.TLSCertFile, l.TLSKeyFile, "") | ||||||
| 	if !ok { | 	if err := cg.Reload(); err != nil { | ||||||
| 		return nil, nil, nil, nil, fmt.Errorf("'tls_cert_file' must be set") |  | ||||||
| 	} |  | ||||||
| 	certFile := certFileRaw.(string) |  | ||||||
| 	keyFileRaw, ok := config["tls_key_file"] |  | ||||||
| 	if !ok { |  | ||||||
| 		return nil, nil, nil, nil, fmt.Errorf("'tls_key_file' must be set") |  | ||||||
| 	} |  | ||||||
| 	keyFile := keyFileRaw.(string) |  | ||||||
|  |  | ||||||
| 	cg := reloadutil.NewCertificateGetter(certFile, keyFile, "") |  | ||||||
| 	if err := cg.Reload(config); err != nil { |  | ||||||
| 		// We try the key without a passphrase first and if we get an incorrect | 		// We try the key without a passphrase first and if we get an incorrect | ||||||
| 		// passphrase response, try again after prompting for a passphrase | 		// passphrase response, try again after prompting for a passphrase | ||||||
| 		if errwrap.Contains(err, x509.IncorrectPasswordError.Error()) { | 		if errwrap.Contains(err, x509.IncorrectPasswordError.Error()) { | ||||||
| 			var passphrase string | 			var passphrase string | ||||||
| 			passphrase, err = ui.AskSecret(fmt.Sprintf("Enter passphrase for %s:", keyFile)) | 			passphrase, err = ui.AskSecret(fmt.Sprintf("Enter passphrase for %s:", l.TLSKeyFile)) | ||||||
| 			if err == nil { | 			if err == nil { | ||||||
| 				cg = reloadutil.NewCertificateGetter(certFile, keyFile, passphrase) | 				cg = reloadutil.NewCertificateGetter(l.TLSCertFile, l.TLSKeyFile, passphrase) | ||||||
| 				if err = cg.Reload(config); err == nil { | 				if err = cg.Reload(); err == nil { | ||||||
| 					goto PASSPHRASECORRECT | 					goto PASSPHRASECORRECT | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return nil, nil, nil, nil, errwrap.Wrapf("error loading TLS cert: {{err}}", err) | 		return nil, nil, errwrap.Wrapf("error loading TLS cert: {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| PASSPHRASECORRECT: | PASSPHRASECORRECT: | ||||||
| 	var tlsvers string | 	tlsConf := &tls.Config{ | ||||||
| 	tlsversRaw, ok := config["tls_min_version"] | 		GetCertificate:           cg.GetCertificate, | ||||||
|  | 		NextProtos:               []string{"h2", "http/1.1"}, | ||||||
|  | 		ClientAuth:               tls.RequestClientCert, | ||||||
|  | 		PreferServerCipherSuites: l.TLSPreferServerCipherSuites, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if l.TLSMinVersion == "" { | ||||||
|  | 		l.TLSMinVersion = "tls12" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var ok bool | ||||||
|  | 	tlsConf.MinVersion, ok = tlsutil.TLSLookup[l.TLSMinVersion] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		tlsvers = "tls12" | 		return nil, nil, fmt.Errorf("'tls_min_version' value %q not supported, please specify one of [tls10,tls11,tls12,tls13]", l.TLSMinVersion) | ||||||
| 	} else { |  | ||||||
| 		tlsvers = tlsversRaw.(string) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	tlsConf := &tls.Config{} |  | ||||||
| 	tlsConf.GetCertificate = cg.GetCertificate |  | ||||||
| 	tlsConf.NextProtos = []string{"h2", "http/1.1"} |  | ||||||
| 	tlsConf.MinVersion, ok = tlsutil.TLSLookup[tlsvers] |  | ||||||
| 	if !ok { |  | ||||||
| 		return nil, nil, nil, nil, fmt.Errorf("'tls_min_version' value %q not supported, please specify one of [tls10,tls11,tls12,tls13]", tlsvers) |  | ||||||
| 	} |  | ||||||
| 	tlsConf.ClientAuth = tls.RequestClientCert |  | ||||||
|  |  | ||||||
| 	if v, ok := config["tls_cipher_suites"]; ok { |  | ||||||
| 		ciphers, err := tlsutil.ParseCiphers(v.(string)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, nil, nil, errwrap.Wrapf("invalid value for 'tls_cipher_suites': {{err}}", err) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if len(l.TLSCipherSuites) > 0 { | ||||||
| 		// HTTP/2 with TLS 1.2 blacklists several cipher suites. | 		// HTTP/2 with TLS 1.2 blacklists several cipher suites. | ||||||
| 		// https://tools.ietf.org/html/rfc7540#appendix-A | 		// https://tools.ietf.org/html/rfc7540#appendix-A | ||||||
| 		// | 		// | ||||||
| 		// Since the CLI (net/http) automatically uses HTTP/2 with TLS 1.2, | 		// Since the CLI (net/http) automatically uses HTTP/2 with TLS 1.2, | ||||||
| 		// we check here if all or some specified cipher suites are blacklisted. | 		// we check here if all or some specified cipher suites are blacklisted. | ||||||
| 		badCiphers := []string{} | 		badCiphers := []string{} | ||||||
| 		for _, cipher := range ciphers { | 		for _, cipher := range l.TLSCipherSuites { | ||||||
| 			if isbadcipher.IsBadCipher(cipher) { | 			if isbadcipher.IsBadCipher(cipher) { | ||||||
| 				// Get the name of the current cipher. | 				// Get the name of the current cipher. | ||||||
| 				cipherStr, err := tlsutil.GetCipherName(cipher) | 				cipherStr, err := tlsutil.GetCipherName(cipher) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					return nil, nil, nil, nil, errwrap.Wrapf("invalid value for 'tls_cipher_suites': {{err}}", err) | 					return nil, nil, errwrap.Wrapf("invalid value for 'tls_cipher_suites': {{err}}", err) | ||||||
| 				} | 				} | ||||||
| 				badCiphers = append(badCiphers, cipherStr) | 				badCiphers = append(badCiphers, cipherStr) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if len(badCiphers) == len(ciphers) { | 		if len(badCiphers) == len(l.TLSCipherSuites) { | ||||||
| 			ui.Warn(`WARNING! All cipher suites defined by 'tls_cipher_suites' are blacklisted by the | 			ui.Warn(`WARNING! All cipher suites defined by 'tls_cipher_suites' are blacklisted by the | ||||||
| HTTP/2 specification. HTTP/2 communication with TLS 1.2 will not work as intended | HTTP/2 specification. HTTP/2 communication with TLS 1.2 will not work as intended | ||||||
| and Vault will be unavailable via the CLI. | and Vault will be unavailable via the CLI. | ||||||
| @@ -163,54 +145,34 @@ blacklisted by the HTTP/2 specification: | |||||||
| %v | %v | ||||||
| Please see https://tools.ietf.org/html/rfc7540#appendix-A for further information.`, badCiphers)) | Please see https://tools.ietf.org/html/rfc7540#appendix-A for further information.`, badCiphers)) | ||||||
| 		} | 		} | ||||||
| 		tlsConf.CipherSuites = ciphers | 		tlsConf.CipherSuites = l.TLSCipherSuites | ||||||
| 	} | 	} | ||||||
| 	if v, ok := config["tls_prefer_server_cipher_suites"]; ok { |  | ||||||
| 		preferServer, err := parseutil.ParseBool(v) | 	if l.TLSRequireAndVerifyClientCert { | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, nil, nil, errwrap.Wrapf("invalid value for 'tls_prefer_server_cipher_suites': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		tlsConf.PreferServerCipherSuites = preferServer |  | ||||||
| 	} |  | ||||||
| 	var requireVerifyCerts bool |  | ||||||
| 	var err error |  | ||||||
| 	if v, ok := config["tls_require_and_verify_client_cert"]; ok { |  | ||||||
| 		requireVerifyCerts, err = parseutil.ParseBool(v) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, nil, nil, errwrap.Wrapf("invalid value for 'tls_require_and_verify_client_cert': {{err}}", err) |  | ||||||
| 		} |  | ||||||
| 		if requireVerifyCerts { |  | ||||||
| 		tlsConf.ClientAuth = tls.RequireAndVerifyClientCert | 		tlsConf.ClientAuth = tls.RequireAndVerifyClientCert | ||||||
| 		} | 		if l.TLSClientCAFile != "" { | ||||||
| 		if tlsClientCaFile, ok := config["tls_client_ca_file"]; ok { |  | ||||||
| 			caPool := x509.NewCertPool() | 			caPool := x509.NewCertPool() | ||||||
| 			data, err := ioutil.ReadFile(tlsClientCaFile.(string)) | 			data, err := ioutil.ReadFile(l.TLSClientCAFile) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, nil, nil, nil, errwrap.Wrapf("failed to read tls_client_ca_file: {{err}}", err) | 				return nil, nil, errwrap.Wrapf("failed to read tls_client_ca_file: {{err}}", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if !caPool.AppendCertsFromPEM(data) { | 			if !caPool.AppendCertsFromPEM(data) { | ||||||
| 				return nil, nil, nil, nil, fmt.Errorf("failed to parse CA certificate in tls_client_ca_file") | 				return nil, nil, fmt.Errorf("failed to parse CA certificate in tls_client_ca_file") | ||||||
| 			} | 			} | ||||||
| 			tlsConf.ClientCAs = caPool | 			tlsConf.ClientCAs = caPool | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if v, ok := config["tls_disable_client_certs"]; ok { |  | ||||||
| 		disableClientCerts, err := parseutil.ParseBool(v) | 	if l.TLSDisableClientCerts { | ||||||
| 		if err != nil { | 		if l.TLSRequireAndVerifyClientCert { | ||||||
| 			return nil, nil, nil, nil, errwrap.Wrapf("invalid value for 'tls_disable_client_certs': {{err}}", err) | 			return nil, nil, fmt.Errorf("'tls_disable_client_certs' and 'tls_require_and_verify_client_cert' are mutually exclusive") | ||||||
| 		} | 		} | ||||||
| 		if disableClientCerts && requireVerifyCerts { |  | ||||||
| 			return nil, nil, nil, nil, fmt.Errorf("'tls_disable_client_certs' and 'tls_require_and_verify_client_cert' are mutually exclusive") |  | ||||||
| 		} |  | ||||||
| 		if disableClientCerts { |  | ||||||
| 		tlsConf.ClientAuth = tls.NoClientCert | 		tlsConf.ClientAuth = tls.NoClientCert | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ln = tls.NewListener(ln, tlsConf) |  | ||||||
| 	props["tls"] = "enabled" | 	props["tls"] = "enabled" | ||||||
| 	return ln, props, cg.Reload, tlsConf, nil | 	return tlsConf, cg.Reload, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // setFilePermissions handles configuring ownership and permissions | // setFilePermissions handles configuring ownership and permissions | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| // ReloadFunc are functions that are called when a reload is requested | // ReloadFunc are functions that are called when a reload is requested | ||||||
| type ReloadFunc func(map[string]interface{}) error | type ReloadFunc func() error | ||||||
|  |  | ||||||
| // CertificateGetter satisfies ReloadFunc and its GetCertificate method | // CertificateGetter satisfies ReloadFunc and its GetCertificate method | ||||||
| // satisfies the tls.GetCertificate function signature.  Currently it does not | // satisfies the tls.GetCertificate function signature.  Currently it does not | ||||||
| @@ -36,7 +36,7 @@ func NewCertificateGetter(certFile, keyFile, passphrase string) *CertificateGett | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (cg *CertificateGetter) Reload(_ map[string]interface{}) error { | func (cg *CertificateGetter) Reload() error { | ||||||
| 	certPEMBlock, err := ioutil.ReadFile(cg.certFile) | 	certPEMBlock, err := ioutil.ReadFile(cg.certFile) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ opM24uvQT3Bc0UM0WNh3tdRFuboxDeBDh7PX/2RIoiaMuCCiRZ3O0A== | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cg := NewCertificateGetter(certFile, keyFile, "") | 	cg := NewCertificateGetter(certFile, keyFile, "") | ||||||
| 	err = cg.Reload(nil) | 	err = cg.Reload() | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatal("error expected") | 		t.Fatal("error expected") | ||||||
| 	} | 	} | ||||||
| @@ -68,7 +68,7 @@ opM24uvQT3Bc0UM0WNh3tdRFuboxDeBDh7PX/2RIoiaMuCCiRZ3O0A== | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cg = NewCertificateGetter(certFile, keyFile, password) | 	cg = NewCertificateGetter(certFile, keyFile, password) | ||||||
| 	if err := cg.Reload(nil); err != nil { | 	if err := cg.Reload(); err != nil { | ||||||
| 		t.Fatalf("err: %v", err) | 		t.Fatalf("err: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -473,7 +473,7 @@ func (c *Core) newAuditBackend(ctx context.Context, entry *MountEntry, view logi | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		c.reloadFuncs[key] = append(c.reloadFuncs[key], func(map[string]interface{}) error { | 		c.reloadFuncs[key] = append(c.reloadFuncs[key], func() error { | ||||||
| 			if auditLogger.IsInfo() { | 			if auditLogger.IsInfo() { | ||||||
| 				auditLogger.Info("reloading file audit backend", "path", entry.Path) | 				auditLogger.Info("reloading file audit backend", "path", entry.Path) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -829,7 +829,7 @@ func NewCore(conf *CoreConfig) (*Core, error) { | |||||||
|  |  | ||||||
| 	if c.seal == nil { | 	if c.seal == nil { | ||||||
| 		c.seal = NewDefaultSeal(&vaultseal.Access{ | 		c.seal = NewDefaultSeal(&vaultseal.Access{ | ||||||
| 			Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 			Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 				Logger: c.logger.Named("shamir"), | 				Logger: c.logger.Named("shamir"), | ||||||
| 			}), | 			}), | ||||||
| 		}) | 		}) | ||||||
| @@ -1069,7 +1069,7 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { | |||||||
| 		if sealToUse.BarrierType() == wrapping.Shamir && c.migrationInfo == nil { | 		if sealToUse.BarrierType() == wrapping.Shamir && c.migrationInfo == nil { | ||||||
| 			// If this is a legacy shamir seal this serves no purpose but it | 			// If this is a legacy shamir seal this serves no purpose but it | ||||||
| 			// doesn't hurt. | 			// doesn't hurt. | ||||||
| 			err = sealToUse.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(masterKey) | 			err = sealToUse.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(masterKey) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return false, err | 				return false, err | ||||||
| 			} | 			} | ||||||
| @@ -1286,7 +1286,7 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover | |||||||
| 		c.migrationInfo.shamirCombinedKey = make([]byte, len(recoveredKey)) | 		c.migrationInfo.shamirCombinedKey = make([]byte, len(recoveredKey)) | ||||||
| 		copy(c.migrationInfo.shamirCombinedKey, recoveredKey) | 		copy(c.migrationInfo.shamirCombinedKey, recoveredKey) | ||||||
| 		if seal.StoredKeysSupported() == vaultseal.StoredKeysSupportedShamirMaster { | 		if seal.StoredKeysSupported() == vaultseal.StoredKeysSupportedShamirMaster { | ||||||
| 			err = seal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(recoveredKey) | 			err = seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(recoveredKey) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, errwrap.Wrapf("failed to set master key in seal: {{err}}", err) | 				return nil, errwrap.Wrapf("failed to set master key in seal: {{err}}", err) | ||||||
| 			} | 			} | ||||||
| @@ -1360,7 +1360,7 @@ func (c *Core) migrateSeal(ctx context.Context) error { | |||||||
|  |  | ||||||
| 		// We have recovery keys; we're going to use them as the new | 		// We have recovery keys; we're going to use them as the new | ||||||
| 		// shamir KeK. | 		// shamir KeK. | ||||||
| 		err := c.seal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(c.migrationInfo.recoveryKey) | 		err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(c.migrationInfo.recoveryKey) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return errwrap.Wrapf("failed to set master key in seal: {{err}}", err) | 			return errwrap.Wrapf("failed to set master key in seal: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| @@ -2264,7 +2264,7 @@ func (c *Core) unsealKeyToMasterKey(ctx context.Context, combinedKey []byte) ([] | |||||||
|  |  | ||||||
| 	case vaultseal.StoredKeysSupportedShamirMaster: | 	case vaultseal.StoredKeysSupportedShamirMaster: | ||||||
| 		testseal := NewDefaultSeal(&vaultseal.Access{ | 		testseal := NewDefaultSeal(&vaultseal.Access{ | ||||||
| 			Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 			Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 				Logger: c.logger.Named("testseal"), | 				Logger: c.logger.Named("testseal"), | ||||||
| 			}), | 			}), | ||||||
| 		}) | 		}) | ||||||
| @@ -2274,7 +2274,7 @@ func (c *Core) unsealKeyToMasterKey(ctx context.Context, combinedKey []byte) ([] | |||||||
| 			return nil, errwrap.Wrapf("failed to setup test barrier config: {{err}}", err) | 			return nil, errwrap.Wrapf("failed to setup test barrier config: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		testseal.SetCachedBarrierConfig(cfg) | 		testseal.SetCachedBarrierConfig(cfg) | ||||||
| 		err = testseal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(combinedKey) | 		err = testseal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(combinedKey) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, errwrap.Wrapf("failed to setup unseal key: {{err}}", err) | 			return nil, errwrap.Wrapf("failed to setup unseal key: {{err}}", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -817,7 +817,7 @@ func (c *Core) reloadShamirKey(ctx context.Context) error { | |||||||
| 		} | 		} | ||||||
| 		shamirKey = keyring.masterKey | 		shamirKey = keyring.masterKey | ||||||
| 	} | 	} | ||||||
| 	return c.seal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(shamirKey) | 	return c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(shamirKey) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Core) performKeyUpgrades(ctx context.Context) error { | func (c *Core) performKeyUpgrades(ctx context.Context) error { | ||||||
|   | |||||||
| @@ -303,7 +303,7 @@ func (c *Core) Initialize(ctx context.Context, initParams *InitParams) (*InitRes | |||||||
| 	switch c.seal.StoredKeysSupported() { | 	switch c.seal.StoredKeysSupported() { | ||||||
| 	case seal.StoredKeysSupportedShamirMaster: | 	case seal.StoredKeysSupportedShamirMaster: | ||||||
| 		keysToStore := [][]byte{barrierKey} | 		keysToStore := [][]byte{barrierKey} | ||||||
| 		if err := c.seal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(sealKey); err != nil { | 		if err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(sealKey); err != nil { | ||||||
| 			c.logger.Error("failed to set seal key", "error", err) | 			c.logger.Error("failed to set seal key", "error", err) | ||||||
| 			return nil, errwrap.Wrapf("failed to set seal key: {{err}}", err) | 			return nil, errwrap.Wrapf("failed to set seal key: {{err}}", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -400,12 +400,12 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) | |||||||
| 	case c.seal.BarrierType() == wrapping.Shamir: | 	case c.seal.BarrierType() == wrapping.Shamir: | ||||||
| 		if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedShamirMaster { | 		if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedShamirMaster { | ||||||
| 			testseal := NewDefaultSeal(&seal.Access{ | 			testseal := NewDefaultSeal(&seal.Access{ | ||||||
| 				Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 				Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 					Logger: c.logger.Named("testseal"), | 					Logger: c.logger.Named("testseal"), | ||||||
| 				}), | 				}), | ||||||
| 			}) | 			}) | ||||||
| 			testseal.SetCore(c) | 			testseal.SetCore(c) | ||||||
| 			err = testseal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(recoveredKey) | 			err = testseal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(recoveredKey) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to setup unseal key: {{err}}", err).Error()) | 				return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to setup unseal key: {{err}}", err).Error()) | ||||||
| 			} | 			} | ||||||
| @@ -533,7 +533,7 @@ func (c *Core) performBarrierRekey(ctx context.Context, newSealKey []byte) logic | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.seal.StoredKeysSupported() != seal.StoredKeysSupportedGeneric { | 	if c.seal.StoredKeysSupported() != seal.StoredKeysSupportedGeneric { | ||||||
| 		err := c.seal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(newSealKey) | 		err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(newSealKey) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to update barrier seal key: {{err}}", err).Error()) | 			return logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to update barrier seal key: {{err}}", err).Error()) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	sockaddr "github.com/hashicorp/go-sockaddr" | 	sockaddr "github.com/hashicorp/go-sockaddr" | ||||||
| 	"github.com/hashicorp/vault/helper/identity" | 	"github.com/hashicorp/vault/helper/identity" | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
|  | 	"github.com/hashicorp/vault/internalshared/configutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/consts" | 	"github.com/hashicorp/vault/sdk/helper/consts" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/errutil" | 	"github.com/hashicorp/vault/sdk/helper/errutil" | ||||||
| @@ -41,12 +42,10 @@ var ( | |||||||
| // It's in this package to avoid a circular dependency | // It's in this package to avoid a circular dependency | ||||||
| type HandlerProperties struct { | type HandlerProperties struct { | ||||||
| 	Core                  *Core | 	Core                  *Core | ||||||
| 	MaxRequestSize               int64 | 	ListenerConfig        *configutil.Listener | ||||||
| 	MaxRequestDuration           time.Duration |  | ||||||
| 	DisablePrintableCheck bool | 	DisablePrintableCheck bool | ||||||
| 	RecoveryMode          bool | 	RecoveryMode          bool | ||||||
| 	RecoveryToken         *uberAtomic.String | 	RecoveryToken         *uberAtomic.String | ||||||
| 	UnauthenticatedMetricsAccess bool |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // fetchEntityAndDerivedPolicies returns the entity object for the given entity | // fetchEntityAndDerivedPolicies returns the entity object for the given entity | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ func NewTestSeal(t testing.T, opts *seal.TestSealOpts) Seal { | |||||||
| 	switch opts.StoredKeys { | 	switch opts.StoredKeys { | ||||||
| 	case seal.StoredKeysSupportedShamirMaster: | 	case seal.StoredKeysSupportedShamirMaster: | ||||||
| 		newSeal := NewDefaultSeal(&seal.Access{ | 		newSeal := NewDefaultSeal(&seal.Access{ | ||||||
| 			Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 			Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 				Logger: opts.Logger, | 				Logger: opts.Logger, | ||||||
| 			}), | 			}), | ||||||
| 		}) | 		}) | ||||||
| @@ -34,7 +34,7 @@ func NewTestSeal(t testing.T, opts *seal.TestSealOpts) Seal { | |||||||
| 		return newSeal | 		return newSeal | ||||||
| 	case seal.StoredKeysNotSupported: | 	case seal.StoredKeysNotSupported: | ||||||
| 		newSeal := NewDefaultSeal(&seal.Access{ | 		newSeal := NewDefaultSeal(&seal.Access{ | ||||||
| 			Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ | 			Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ | ||||||
| 				Logger: opts.Logger, | 				Logger: opts.Logger, | ||||||
| 			}), | 			}), | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
| @@ -1370,7 +1370,7 @@ func NewTestCluster(t testing.T, base *CoreConfig, opts *TestClusterOptions) *Te | |||||||
| 		} | 		} | ||||||
| 		certGetter := reloadutil.NewCertificateGetter(certFile, keyFile, "") | 		certGetter := reloadutil.NewCertificateGetter(certFile, keyFile, "") | ||||||
| 		certGetters = append(certGetters, certGetter) | 		certGetters = append(certGetters, certGetter) | ||||||
| 		certGetter.Reload(nil) | 		certGetter.Reload() | ||||||
| 		tlsConfig := &tls.Config{ | 		tlsConfig := &tls.Config{ | ||||||
| 			Certificates:   []tls.Certificate{tlsCert}, | 			Certificates:   []tls.Certificate{tlsCert}, | ||||||
| 			RootCAs:        testCluster.RootCAs, | 			RootCAs:        testCluster.RootCAs, | ||||||
| @@ -1590,8 +1590,8 @@ func NewTestCluster(t testing.T, base *CoreConfig, opts *TestClusterOptions) *Te | |||||||
| 		if opts != nil && opts.HandlerFunc != nil { | 		if opts != nil && opts.HandlerFunc != nil { | ||||||
| 			props := opts.DefaultHandlerProperties | 			props := opts.DefaultHandlerProperties | ||||||
| 			props.Core = c | 			props.Core = c | ||||||
| 			if props.MaxRequestDuration == 0 { | 			if props.ListenerConfig != nil && props.ListenerConfig.MaxRequestDuration == 0 { | ||||||
| 				props.MaxRequestDuration = DefaultMaxRequestDuration | 				props.ListenerConfig.MaxRequestDuration = DefaultMaxRequestDuration | ||||||
| 			} | 			} | ||||||
| 			handlers[i] = opts.HandlerFunc(&props) | 			handlers[i] = opts.HandlerFunc(&props) | ||||||
| 			servers[i].Handler = handlers[i] | 			servers[i].Handler = handlers[i] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jeff Mitchell
					Jeff Mitchell