mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
VAULT-29784: Skip connection verification on DB config read (#28139)
* skip connection verification on config read * ensure appropriate default on config update call that results in a creation * changelog * leave verify_connection in config read response * update test to handle output of verify_connection parameter * fix remaining tests
This commit is contained in:
@@ -291,6 +291,18 @@ func (b *databaseBackend) GetConnection(ctx context.Context, s logical.Storage,
|
|||||||
return b.GetConnectionWithConfig(ctx, name, config)
|
return b.GetConnectionWithConfig(ctx, name, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *databaseBackend) GetConnectionSkipVerify(ctx context.Context, s logical.Storage, name string) (*dbPluginInstance, error) {
|
||||||
|
config, err := b.DatabaseConfig(ctx, s, name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force the skip verifying the connection
|
||||||
|
config.VerifyConnection = false
|
||||||
|
|
||||||
|
return b.GetConnectionWithConfig(ctx, name, config)
|
||||||
|
}
|
||||||
|
|
||||||
func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name string, config *DatabaseConfig) (*dbPluginInstance, error) {
|
func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name string, config *DatabaseConfig) (*dbPluginInstance, error) {
|
||||||
// fast path, reuse the existing connection
|
// fast path, reuse the existing connection
|
||||||
dbi := b.connections.Get(name)
|
dbi := b.connections.Get(name)
|
||||||
@@ -331,7 +343,7 @@ func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name stri
|
|||||||
|
|
||||||
initReq := v5.InitializeRequest{
|
initReq := v5.InitializeRequest{
|
||||||
Config: config.ConnectionDetails,
|
Config: config.ConnectionDetails,
|
||||||
VerifyConnection: true,
|
VerifyConnection: config.VerifyConnection,
|
||||||
}
|
}
|
||||||
_, err = dbw.Initialize(ctx, initReq)
|
_, err = dbw.Initialize(ctx, initReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ func TestBackend_config_connection(t *testing.T) {
|
|||||||
"root_credentials_rotate_statements": []string{},
|
"root_credentials_rotate_statements": []string{},
|
||||||
"password_policy": "",
|
"password_policy": "",
|
||||||
"plugin_version": "",
|
"plugin_version": "",
|
||||||
|
"verify_connection": false,
|
||||||
}
|
}
|
||||||
configReq.Operation = logical.ReadOperation
|
configReq.Operation = logical.ReadOperation
|
||||||
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
|
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
|
||||||
@@ -264,6 +265,7 @@ func TestBackend_config_connection(t *testing.T) {
|
|||||||
"root_credentials_rotate_statements": []string{},
|
"root_credentials_rotate_statements": []string{},
|
||||||
"password_policy": "",
|
"password_policy": "",
|
||||||
"plugin_version": "",
|
"plugin_version": "",
|
||||||
|
"verify_connection": false,
|
||||||
}
|
}
|
||||||
configReq.Operation = logical.ReadOperation
|
configReq.Operation = logical.ReadOperation
|
||||||
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
|
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
|
||||||
@@ -307,6 +309,7 @@ func TestBackend_config_connection(t *testing.T) {
|
|||||||
"root_credentials_rotate_statements": []string{},
|
"root_credentials_rotate_statements": []string{},
|
||||||
"password_policy": "",
|
"password_policy": "",
|
||||||
"plugin_version": "",
|
"plugin_version": "",
|
||||||
|
"verify_connection": false,
|
||||||
}
|
}
|
||||||
configReq.Operation = logical.ReadOperation
|
configReq.Operation = logical.ReadOperation
|
||||||
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
|
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
|
||||||
@@ -764,6 +767,7 @@ func TestBackend_connectionCrud(t *testing.T) {
|
|||||||
"root_credentials_rotate_statements": []any{},
|
"root_credentials_rotate_statements": []any{},
|
||||||
"password_policy": "",
|
"password_policy": "",
|
||||||
"plugin_version": "",
|
"plugin_version": "",
|
||||||
|
"verify_connection": false,
|
||||||
}
|
}
|
||||||
resp, err = client.Read("database/config/plugin-test")
|
resp, err = client.Read("database/config/plugin-test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ type DatabaseConfig struct {
|
|||||||
|
|
||||||
RootCredentialsRotateStatements []string `json:"root_credentials_rotate_statements" structs:"root_credentials_rotate_statements" mapstructure:"root_credentials_rotate_statements"`
|
RootCredentialsRotateStatements []string `json:"root_credentials_rotate_statements" structs:"root_credentials_rotate_statements" mapstructure:"root_credentials_rotate_statements"`
|
||||||
|
|
||||||
PasswordPolicy string `json:"password_policy" structs:"password_policy" mapstructure:"password_policy"`
|
PasswordPolicy string `json:"password_policy" structs:"password_policy" mapstructure:"password_policy"`
|
||||||
|
VerifyConnection bool `json:"verify_connection" structs:"verify_connection" mapstructure:"verify_connection"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DatabaseConfig) SupportsCredentialType(credentialType v5.CredentialType) bool {
|
func (c *DatabaseConfig) SupportsCredentialType(credentialType v5.CredentialType) bool {
|
||||||
@@ -378,7 +379,7 @@ func (b *databaseBackend) connectionReadHandler() framework.OperationFunc {
|
|||||||
delete(config.ConnectionDetails, "service_account_json")
|
delete(config.ConnectionDetails, "service_account_json")
|
||||||
|
|
||||||
resp := &logical.Response{}
|
resp := &logical.Response{}
|
||||||
if dbi, err := b.GetConnection(ctx, req.Storage, name); err == nil {
|
if dbi, err := b.GetConnectionSkipVerify(ctx, req.Storage, name); err == nil {
|
||||||
config.RunningPluginVersion = dbi.runningPluginVersion
|
config.RunningPluginVersion = dbi.runningPluginVersion
|
||||||
if config.PluginVersion != "" && config.PluginVersion != config.RunningPluginVersion {
|
if config.PluginVersion != "" && config.PluginVersion != config.RunningPluginVersion {
|
||||||
warning := fmt.Sprintf("Plugin version is configured as %q, but running %q", config.PluginVersion, config.RunningPluginVersion)
|
warning := fmt.Sprintf("Plugin version is configured as %q, but running %q", config.PluginVersion, config.RunningPluginVersion)
|
||||||
@@ -422,15 +423,15 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
|
|||||||
// both builtin and plugin database types.
|
// both builtin and plugin database types.
|
||||||
func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
||||||
return func(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
return func(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
verifyConnection := data.Get("verify_connection").(bool)
|
|
||||||
|
|
||||||
name := data.Get("name").(string)
|
name := data.Get("name").(string)
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return logical.ErrorResponse(respErrEmptyName), nil
|
return logical.ErrorResponse(respErrEmptyName), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Baseline
|
// Baseline
|
||||||
config := &DatabaseConfig{}
|
config := &DatabaseConfig{
|
||||||
|
VerifyConnection: true,
|
||||||
|
}
|
||||||
|
|
||||||
entry, err := req.Storage.Get(ctx, fmt.Sprintf("config/%s", name))
|
entry, err := req.Storage.Get(ctx, fmt.Sprintf("config/%s", name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -442,6 +443,13 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this value was provided as part of the request we want to set it to this value
|
||||||
|
if verifyConnectionRaw, ok := data.GetOk("verify_connection"); ok {
|
||||||
|
config.VerifyConnection = verifyConnectionRaw.(bool)
|
||||||
|
} else if req.Operation == logical.CreateOperation {
|
||||||
|
config.VerifyConnection = data.Get("verify_connection").(bool)
|
||||||
|
}
|
||||||
|
|
||||||
if pluginNameRaw, ok := data.GetOk("plugin_name"); ok {
|
if pluginNameRaw, ok := data.GetOk("plugin_name"); ok {
|
||||||
config.PluginName = pluginNameRaw.(string)
|
config.PluginName = pluginNameRaw.(string)
|
||||||
} else if req.Operation == logical.CreateOperation {
|
} else if req.Operation == logical.CreateOperation {
|
||||||
@@ -509,7 +517,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
|||||||
|
|
||||||
initReq := v5.InitializeRequest{
|
initReq := v5.InitializeRequest{
|
||||||
Config: config.ConnectionDetails,
|
Config: config.ConnectionDetails,
|
||||||
VerifyConnection: verifyConnection,
|
VerifyConnection: config.VerifyConnection,
|
||||||
}
|
}
|
||||||
initResp, err := dbw.Initialize(ctx, initReq)
|
initResp, err := dbw.Initialize(ctx, initReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
3
changelog/28139.txt
Normal file
3
changelog/28139.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:bug
|
||||||
|
secrets/database: Skip connection verification on reading existing DB connection configuration
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user