mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 09:42:25 +00:00
Add OSS stub functions for Self-Managed Static Roles (#28199)
This commit is contained in:
@@ -9,9 +9,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
|||||||
@@ -17,13 +17,12 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/sdk/helper/locksutil"
|
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/vault/sdk/framework"
|
"github.com/hashicorp/vault/sdk/framework"
|
||||||
"github.com/hashicorp/vault/sdk/helper/certutil"
|
"github.com/hashicorp/vault/sdk/helper/certutil"
|
||||||
"github.com/hashicorp/vault/sdk/helper/cidrutil"
|
"github.com/hashicorp/vault/sdk/helper/cidrutil"
|
||||||
|
"github.com/hashicorp/vault/sdk/helper/locksutil"
|
||||||
"github.com/hashicorp/vault/sdk/helper/ocsp"
|
"github.com/hashicorp/vault/sdk/helper/ocsp"
|
||||||
"github.com/hashicorp/vault/sdk/helper/policyutil"
|
"github.com/hashicorp/vault/sdk/helper/policyutil"
|
||||||
"github.com/hashicorp/vault/sdk/logical"
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
|
|||||||
@@ -217,6 +217,11 @@ func staticFields() map[string]*framework.FieldSchema {
|
|||||||
this functionality. See the plugin's API page for more information on
|
this functionality. See the plugin's API page for more information on
|
||||||
support and formatting for this parameter.`,
|
support and formatting for this parameter.`,
|
||||||
},
|
},
|
||||||
|
"self_managed_password": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Used to connect to a self-managed static account. Must
|
||||||
|
be provided by the user when root credentials are not provided.`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
@@ -628,6 +633,10 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if smPasswordRaw, ok := data.GetOk("self_managed_password"); ok && createRole {
|
||||||
|
role.StaticAccount.SelfManagedPassword = smPasswordRaw.(string)
|
||||||
|
}
|
||||||
|
|
||||||
var credentialConfig map[string]string
|
var credentialConfig map[string]string
|
||||||
if raw, ok := data.GetOk("credential_config"); ok {
|
if raw, ok := data.GetOk("credential_config"); ok {
|
||||||
credentialConfig = raw.(map[string]string)
|
credentialConfig = raw.(map[string]string)
|
||||||
@@ -785,6 +794,12 @@ type staticAccount struct {
|
|||||||
// Username to create or assume management for static accounts
|
// Username to create or assume management for static accounts
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
|
||||||
|
// SelfManagedPassword is used to make a dedicated connection to the DB
|
||||||
|
// user specified by Username. The credentials will leverage the existing
|
||||||
|
// static role mechanisms to handle password rotations. Required when root
|
||||||
|
// credentials are not provided.
|
||||||
|
SelfManagedPassword string `json:"self_managed_password"`
|
||||||
|
|
||||||
// Password is the current password credential for static accounts. As an input,
|
// Password is the current password credential for static accounts. As an input,
|
||||||
// this is used/required when trying to assume management of an existing static
|
// this is used/required when trying to assume management of an existing static
|
||||||
// account. Returned on credential request if the role's credential type is
|
// account. Returned on credential request if the role's credential type is
|
||||||
|
|||||||
@@ -413,6 +413,11 @@ func (b *databaseBackend) setStaticAccount(ctx context.Context, s logical.Storag
|
|||||||
Commands: input.Role.Statements.Rotation,
|
Commands: input.Role.Statements.Rotation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add external password to request so we can use static account connection
|
||||||
|
if input.Role.StaticAccount.SelfManagedPassword != "" {
|
||||||
|
updateReq.SelfManagedPassword = input.Role.StaticAccount.SelfManagedPassword
|
||||||
|
}
|
||||||
|
|
||||||
// Use credential from input if available. This happens if we're restoring from
|
// Use credential from input if available. This happens if we're restoring from
|
||||||
// a WAL item or processing the rotation queue with an item that has a WAL
|
// a WAL item or processing the rotation queue with an item that has a WAL
|
||||||
// associated with it
|
// associated with it
|
||||||
@@ -529,6 +534,12 @@ func (b *databaseBackend) setStaticAccount(ctx context.Context, s logical.Storag
|
|||||||
}
|
}
|
||||||
modified = true
|
modified = true
|
||||||
|
|
||||||
|
// static user password successfully updated in external system
|
||||||
|
// update self-managed password if available for future connections
|
||||||
|
if input.Role.StaticAccount.SelfManagedPassword != "" {
|
||||||
|
input.Role.StaticAccount.SelfManagedPassword = input.Role.StaticAccount.Password
|
||||||
|
}
|
||||||
|
|
||||||
// Store updated role information
|
// Store updated role information
|
||||||
// lvr is the known LastVaultRotation
|
// lvr is the known LastVaultRotation
|
||||||
lvr := time.Now()
|
lvr := time.Now()
|
||||||
|
|||||||
3
changelog/28199.txt
Normal file
3
changelog/28199.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:feature
|
||||||
|
**Self-Managed Static Roles**: Self-Managed Static Roles are now supported for select SQL database engines (Postgres, Oracle). Requires Vault Enterprise.
|
||||||
|
```
|
||||||
@@ -50,6 +50,10 @@ func PrepareTestContainer(t *testing.T) (func(), string) {
|
|||||||
return cleanup, url
|
return cleanup, url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PrepareTestContainerSelfManaged(t *testing.T) (func(), *url.URL) {
|
||||||
|
return prepareTestContainerSelfManaged(t, defaultRunOpts(t), defaultPGPass, true, false, false)
|
||||||
|
}
|
||||||
|
|
||||||
func PrepareTestContainerMultiHost(t *testing.T) (func(), string) {
|
func PrepareTestContainerMultiHost(t *testing.T) (func(), string) {
|
||||||
_, cleanup, url, _ := prepareTestContainer(t, defaultRunOpts(t), defaultPGPass, true, false, true)
|
_, cleanup, url, _ := prepareTestContainer(t, defaultRunOpts(t), defaultPGPass, true, false, true)
|
||||||
|
|
||||||
@@ -198,6 +202,25 @@ func prepareTestContainer(t *testing.T, runOpts docker.RunOptions, password stri
|
|||||||
return runner, svc.Cleanup, svc.Config.URL().String(), containerID
|
return runner, svc.Cleanup, svc.Config.URL().String(), containerID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prepareTestContainerSelfManaged(t *testing.T, runOpts docker.RunOptions, password string, addSuffix, forceLocalAddr, useFallback bool,
|
||||||
|
) (func(), *url.URL) {
|
||||||
|
if os.Getenv("PG_URL") != "" {
|
||||||
|
return func() {}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
runner, err := docker.NewServiceRunner(runOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not start docker Postgres: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
svc, _, err := runner.StartNewService(context.Background(), addSuffix, forceLocalAddr, connectPostgres(password, runOpts.ImageRepo, useFallback))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not start docker Postgres: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.Cleanup, svc.Config.URL()
|
||||||
|
}
|
||||||
|
|
||||||
func getPostgresSSLConfig(t *testing.T, host, sslMode, caCert, clientCert, clientKey string, useFallback bool) docker.ServiceConfig {
|
func getPostgresSSLConfig(t *testing.T, host, sslMode, caCert, clientCert, clientKey string, useFallback bool) docker.ServiceConfig {
|
||||||
if useFallback {
|
if useFallback {
|
||||||
// set the first host to a bad address so we can test the fallback logic
|
// set the first host to a bad address so we can test the fallback logic
|
||||||
|
|||||||
@@ -199,6 +199,15 @@ func (p *PostgreSQL) getConnection(ctx context.Context) (*sql.DB, error) {
|
|||||||
return db.(*sql.DB), nil
|
return db.(*sql.DB), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PostgreSQL) getStaticConnection(ctx context.Context, username, password string) (*sql.DB, error) {
|
||||||
|
db, err := p.StaticConnection(ctx, username, password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PostgreSQL) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) {
|
func (p *PostgreSQL) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) {
|
||||||
if req.Username == "" {
|
if req.Username == "" {
|
||||||
return dbplugin.UpdateUserResponse{}, fmt.Errorf("missing username")
|
return dbplugin.UpdateUserResponse{}, fmt.Errorf("missing username")
|
||||||
@@ -209,17 +218,17 @@ func (p *PostgreSQL) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequ
|
|||||||
|
|
||||||
merr := &multierror.Error{}
|
merr := &multierror.Error{}
|
||||||
if req.Password != nil {
|
if req.Password != nil {
|
||||||
err := p.changeUserPassword(ctx, req.Username, req.Password)
|
err := p.changeUserPassword(ctx, req.Username, req.Password, req.SelfManagedPassword)
|
||||||
merr = multierror.Append(merr, err)
|
merr = multierror.Append(merr, err)
|
||||||
}
|
}
|
||||||
if req.Expiration != nil {
|
if req.Expiration != nil {
|
||||||
err := p.changeUserExpiration(ctx, req.Username, req.Expiration)
|
err := p.changeUserExpiration(ctx, req.Username, req.Expiration, req.SelfManagedPassword)
|
||||||
merr = multierror.Append(merr, err)
|
merr = multierror.Append(merr, err)
|
||||||
}
|
}
|
||||||
return dbplugin.UpdateUserResponse{}, merr.ErrorOrNil()
|
return dbplugin.UpdateUserResponse{}, merr.ErrorOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, changePass *dbplugin.ChangePassword) error {
|
func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, changePass *dbplugin.ChangePassword, selfManagedPass string) error {
|
||||||
stmts := changePass.Statements.Commands
|
stmts := changePass.Statements.Commands
|
||||||
if len(stmts) == 0 {
|
if len(stmts) == 0 {
|
||||||
stmts = []string{defaultChangePasswordStatement}
|
stmts = []string{defaultChangePasswordStatement}
|
||||||
@@ -233,9 +242,18 @@ func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, ch
|
|||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
|
|
||||||
db, err := p.getConnection(ctx)
|
var db *sql.DB
|
||||||
if err != nil {
|
var err error
|
||||||
return fmt.Errorf("unable to get connection: %w", err)
|
if selfManagedPass == "" {
|
||||||
|
db, err = p.getConnection(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get connection: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
db, err = p.getStaticConnection(ctx, username, selfManagedPass)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get static connection from cache: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the role exists
|
// Check if the role exists
|
||||||
@@ -285,7 +303,7 @@ func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, ch
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string, changeExp *dbplugin.ChangeExpiration) error {
|
func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string, changeExp *dbplugin.ChangeExpiration, selfManagedPass string) error {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
|
|
||||||
@@ -294,9 +312,18 @@ func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string,
|
|||||||
renewStmts = []string{defaultExpirationStatement}
|
renewStmts = []string{defaultExpirationStatement}
|
||||||
}
|
}
|
||||||
|
|
||||||
db, err := p.getConnection(ctx)
|
var db *sql.DB
|
||||||
if err != nil {
|
var err error
|
||||||
return err
|
if selfManagedPass == "" {
|
||||||
|
db, err = p.getConnection(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get connection: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
db, err = p.getStaticConnection(ctx, username, selfManagedPass)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get static connection from cache: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := db.BeginTx(ctx, nil)
|
tx, err := db.BeginTx(ctx, nil)
|
||||||
|
|||||||
@@ -640,6 +640,94 @@ func TestPostgreSQL_Initialize_CloudGCP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPostgreSQL_Initialize_SelfManaged_OSS tests the initialization of
|
||||||
|
// the self-managed flow and ensures an error is returned on OSS.
|
||||||
|
func TestPostgreSQL_Initialize_SelfManaged_OSS(t *testing.T) {
|
||||||
|
cleanup, url := postgresql.PrepareTestContainerSelfManaged(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
connURL := fmt.Sprintf("postgresql://{{username}}:{{password}}@%s/postgres?sslmode=disable", url.Host)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
connectionDetails map[string]interface{}
|
||||||
|
wantErr bool
|
||||||
|
errContains string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no parameters set",
|
||||||
|
connectionDetails: map[string]interface{}{
|
||||||
|
"connection_url": connURL,
|
||||||
|
"self_managed": false,
|
||||||
|
"username": "",
|
||||||
|
"password": "",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
errContains: "must either provide username/password or set self-managed to 'true'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "both sets of parameters set",
|
||||||
|
connectionDetails: map[string]interface{}{
|
||||||
|
"connection_url": connURL,
|
||||||
|
"self_managed": true,
|
||||||
|
"username": "test",
|
||||||
|
"password": "test",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
errContains: "cannot use both self-managed and vault-managed workflows",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "either username/password with self-managed",
|
||||||
|
connectionDetails: map[string]interface{}{
|
||||||
|
"connection_url": connURL,
|
||||||
|
"self_managed": true,
|
||||||
|
"username": "test",
|
||||||
|
"password": "",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
errContains: "cannot use both self-managed and vault-managed workflows",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache not implemented",
|
||||||
|
connectionDetails: map[string]interface{}{
|
||||||
|
"connection_url": connURL,
|
||||||
|
"self_managed": true,
|
||||||
|
"username": "",
|
||||||
|
"password": "",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
errContains: "self-managed static roles only available in Vault Enterprise",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
req := dbplugin.InitializeRequest{
|
||||||
|
Config: tc.connectionDetails,
|
||||||
|
VerifyConnection: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
db := new()
|
||||||
|
_, err := dbtesting.VerifyInitialize(t, db, req)
|
||||||
|
if err == nil && tc.wantErr {
|
||||||
|
t.Fatalf("got: %s, wantErr: %t", err, tc.wantErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil && !strings.Contains(err.Error(), tc.errContains) {
|
||||||
|
t.Fatalf("expected error: %s, received error: %s", tc.errContains, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tc.wantErr && !db.Initialized {
|
||||||
|
t.Fatal("Database should be initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Close(); err != nil {
|
||||||
|
t.Fatalf("err closing DB: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestPostgreSQL_PasswordAuthentication tests that the default "password_authentication" is "none", and that
|
// TestPostgreSQL_PasswordAuthentication tests that the default "password_authentication" is "none", and that
|
||||||
// an error is returned if an invalid "password_authentication" is provided.
|
// an error is returned if an invalid "password_authentication" is provided.
|
||||||
func TestPostgreSQL_PasswordAuthentication(t *testing.T) {
|
func TestPostgreSQL_PasswordAuthentication(t *testing.T) {
|
||||||
@@ -1045,6 +1133,37 @@ func TestUpdateUser_Password(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestUpdateUser_SelfManaged_OSS checks basic validation
|
||||||
|
// for self-managed fields and confirms an error is returned on OSS
|
||||||
|
func TestUpdateUser_SelfManaged_OSS(t *testing.T) {
|
||||||
|
// Shared test container for speed - there should not be any overlap between the tests
|
||||||
|
db, cleanup := getPostgreSQL(t, nil)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
updateReq := dbplugin.UpdateUserRequest{
|
||||||
|
Username: "static",
|
||||||
|
Password: &dbplugin.ChangePassword{
|
||||||
|
NewPassword: "somenewpassword",
|
||||||
|
Statements: dbplugin.Statements{
|
||||||
|
Commands: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SelfManagedPassword: "test",
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedErr := "self-managed static roles only available in Vault Enterprise"
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
_, err := db.UpdateUser(ctx, updateReq)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("err expected, got nil")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), expectedErr) {
|
||||||
|
t.Fatalf("err expected: %s, got: %s", expectedErr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateUser_Expiration(t *testing.T) {
|
func TestUpdateUser_Expiration(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
initialExpiration time.Time
|
initialExpiration time.Time
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ func TestConversionsHaveAllFields(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SelfManagedPassword: "test-password",
|
||||||
}
|
}
|
||||||
|
|
||||||
protoReq, err := updateUserReqToProto(req)
|
protoReq, err := updateUserReqToProto(req)
|
||||||
@@ -194,6 +195,7 @@ func TestConversionsHaveAllFields(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SelfManagedPassword: "test-password",
|
||||||
}
|
}
|
||||||
|
|
||||||
protoReq, err := getUpdateUserRequest(req)
|
protoReq, err := getUpdateUserRequest(req)
|
||||||
|
|||||||
@@ -181,6 +181,13 @@ type UpdateUserRequest struct {
|
|||||||
// Expiration indicates the new expiration date to change to.
|
// Expiration indicates the new expiration date to change to.
|
||||||
// If nil, no change is requested.
|
// If nil, no change is requested.
|
||||||
Expiration *ChangeExpiration
|
Expiration *ChangeExpiration
|
||||||
|
|
||||||
|
// SelfManagedPassword is the password for an externally managed user in the DB.
|
||||||
|
// If this field is supplied, a DB connection is retrieved from the static
|
||||||
|
// account cache for the particular DB plugin and used to update the password of
|
||||||
|
// the self-managed static role.
|
||||||
|
// *ENTERPRISE-ONLY*
|
||||||
|
SelfManagedPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangePublicKey of a given user
|
// ChangePublicKey of a given user
|
||||||
|
|||||||
@@ -199,11 +199,12 @@ func updateUserReqToProto(req UpdateUserRequest) (*proto.UpdateUserRequest, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
rpcReq := &proto.UpdateUserRequest{
|
rpcReq := &proto.UpdateUserRequest{
|
||||||
Username: req.Username,
|
Username: req.Username,
|
||||||
CredentialType: int32(req.CredentialType),
|
CredentialType: int32(req.CredentialType),
|
||||||
Password: password,
|
Password: password,
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
Expiration: expiration,
|
Expiration: expiration,
|
||||||
|
SelfManagedPassword: req.SelfManagedPassword,
|
||||||
}
|
}
|
||||||
return rpcReq, nil
|
return rpcReq, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,11 +222,12 @@ func getUpdateUserRequest(req *proto.UpdateUserRequest) (UpdateUserRequest, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbReq := UpdateUserRequest{
|
dbReq := UpdateUserRequest{
|
||||||
Username: req.GetUsername(),
|
Username: req.GetUsername(),
|
||||||
CredentialType: CredentialType(req.GetCredentialType()),
|
CredentialType: CredentialType(req.GetCredentialType()),
|
||||||
Password: password,
|
Password: password,
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
Expiration: expiration,
|
Expiration: expiration,
|
||||||
|
SelfManagedPassword: req.SelfManagedPassword,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasChange(dbReq) {
|
if !hasChange(dbReq) {
|
||||||
|
|||||||
@@ -343,11 +343,12 @@ type UpdateUserRequest struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||||
Password *ChangePassword `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
Password *ChangePassword `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||||
Expiration *ChangeExpiration `protobuf:"bytes,3,opt,name=expiration,proto3" json:"expiration,omitempty"`
|
Expiration *ChangeExpiration `protobuf:"bytes,3,opt,name=expiration,proto3" json:"expiration,omitempty"`
|
||||||
PublicKey *ChangePublicKey `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
PublicKey *ChangePublicKey `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||||
CredentialType int32 `protobuf:"varint,5,opt,name=credential_type,json=credentialType,proto3" json:"credential_type,omitempty"`
|
CredentialType int32 `protobuf:"varint,5,opt,name=credential_type,json=credentialType,proto3" json:"credential_type,omitempty"`
|
||||||
|
SelfManagedPassword string `protobuf:"bytes,6,opt,name=self_managed_password,json=selfManagedPassword,proto3" json:"self_managed_password,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *UpdateUserRequest) Reset() {
|
func (x *UpdateUserRequest) Reset() {
|
||||||
@@ -417,6 +418,13 @@ func (x *UpdateUserRequest) GetCredentialType() int32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *UpdateUserRequest) GetSelfManagedPassword() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.SelfManagedPassword
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type ChangePassword struct {
|
type ChangePassword struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -910,7 +918,7 @@ var file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = []byte{
|
|||||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22,
|
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22,
|
||||||
0x2d, 0x0a, 0x0f, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
0x2d, 0x0a, 0x0f, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||||
0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8d,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xc1,
|
||||||
0x02, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71,
|
0x02, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71,
|
||||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
|
0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
@@ -927,76 +935,79 @@ var file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = []byte{
|
|||||||
0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c,
|
0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c,
|
||||||
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
|
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
|
||||||
0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e,
|
0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e,
|
||||||
0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6c,
|
0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x32,
|
||||||
0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
|
0x0a, 0x15, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x70,
|
||||||
0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
|
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77,
|
0x65, 0x6c, 0x66, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
|
||||||
0x6f, 0x72, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
0x72, 0x64, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73,
|
||||||
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67,
|
0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73,
|
||||||
0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73,
|
0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x50,
|
||||||
0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x70, 0x0a, 0x0f,
|
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||||
0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12,
|
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x62,
|
||||||
0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65,
|
0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d,
|
||||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x50, 0x75, 0x62, 0x6c,
|
0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73,
|
||||||
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
|
0x22, 0x70, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
|
||||||
0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c,
|
0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||||
0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77,
|
||||||
0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x8e,
|
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61,
|
||||||
0x01, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74,
|
0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
|
||||||
0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72,
|
0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
|
||||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
0x74, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70,
|
||||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x45, 0x78, 0x70, 0x69,
|
0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x65,
|
||||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d,
|
0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x62, 0x70,
|
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||||
0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
|
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6e, 0x65, 0x77,
|
||||||
0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22,
|
0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74,
|
||||||
0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73,
|
0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55,
|
0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61,
|
||||||
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73,
|
0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
|
||||||
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73,
|
0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65,
|
||||||
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d,
|
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x44, 0x65, 0x6c,
|
||||||
0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x62, 0x70,
|
0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a,
|
||||||
0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
|
0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||||
0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22,
|
0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74,
|
||||||
0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73,
|
0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73,
|
0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61,
|
||||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
|
0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x22, 0x28, 0x0a, 0x0a, 0x53, 0x74, 0x61,
|
0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65,
|
||||||
0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
|
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x54, 0x79, 0x70,
|
||||||
0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
|
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70,
|
||||||
0x6e, 0x64, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0xa5, 0x03, 0x0a,
|
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x22, 0x28, 0x0a,
|
||||||
0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x49, 0x6e, 0x69,
|
0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x43,
|
||||||
0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67,
|
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x43,
|
||||||
0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65,
|
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67,
|
0x32, 0xa5, 0x03, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x4d, 0x0a,
|
||||||
0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65,
|
0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x2e, 0x64, 0x62,
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55,
|
0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61,
|
||||||
0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76,
|
0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62,
|
||||||
0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61,
|
||||||
0x1a, 0x1c, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x4e,
|
0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x07,
|
||||||
0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d,
|
0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67,
|
||||||
0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x64,
|
0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71,
|
||||||
0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
|
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e,
|
||||||
0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64,
|
0x76, 0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||||
0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
|
0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
|
||||||
0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a,
|
0x12, 0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x55,
|
||||||
0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x64, 0x62,
|
0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||||
0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x55,
|
||||||
0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62,
|
0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12,
|
||||||
0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04,
|
0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x44, 0x65,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e,
|
0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||||
0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75,
|
0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x44, 0x65,
|
||||||
0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||||
0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x64,
|
0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75,
|
||||||
0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x64,
|
||||||
0x1a, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45,
|
0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52,
|
||||||
0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x73, 0x65,
|
||||||
0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61, 0x75,
|
0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45,
|
||||||
0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f,
|
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e,
|
||||||
0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68,
|
||||||
0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||||
|
0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62,
|
||||||
|
0x61, 0x73, 0x65, 0x2f, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, 0x35, 0x2f,
|
||||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ message UpdateUserRequest {
|
|||||||
ChangeExpiration expiration = 3;
|
ChangeExpiration expiration = 3;
|
||||||
ChangePublicKey public_key = 4;
|
ChangePublicKey public_key = 4;
|
||||||
int32 credential_type = 5;
|
int32 credential_type = 5;
|
||||||
|
string self_managed_password = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ChangePassword {
|
message ChangePassword {
|
||||||
|
|||||||
16
sdk/database/helper/cacheutil/cache_stubs_oss.go
Normal file
16
sdk/database/helper/cacheutil/cache_stubs_oss.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//go:build !enterprise
|
||||||
|
|
||||||
|
package cacheutil
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
type EvictionFunc func(key interface{}, value interface{})
|
||||||
|
|
||||||
|
type Cache struct{}
|
||||||
|
|
||||||
|
func NewCache(_ int, _ EvictionFunc) (*Cache, error) {
|
||||||
|
return nil, errors.New("self-managed static roles only available in Vault Enterprise")
|
||||||
|
}
|
||||||
@@ -15,9 +15,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
|
log "github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/hashicorp/vault/sdk/database/dbplugin"
|
"github.com/hashicorp/vault/sdk/database/dbplugin"
|
||||||
|
"github.com/hashicorp/vault/sdk/database/helper/cacheutil"
|
||||||
"github.com/hashicorp/vault/sdk/database/helper/dbutil"
|
"github.com/hashicorp/vault/sdk/database/helper/dbutil"
|
||||||
"github.com/hashicorp/vault/sdk/helper/pluginutil"
|
"github.com/hashicorp/vault/sdk/helper/pluginutil"
|
||||||
"github.com/jackc/pgx/v4"
|
"github.com/jackc/pgx/v4"
|
||||||
@@ -34,6 +36,12 @@ const (
|
|||||||
const (
|
const (
|
||||||
dbTypePostgres = "pgx"
|
dbTypePostgres = "pgx"
|
||||||
cloudSQLPostgres = "cloudsql-postgres"
|
cloudSQLPostgres = "cloudsql-postgres"
|
||||||
|
|
||||||
|
// controls the size of the static account cache
|
||||||
|
// as part of the self-managed workflow
|
||||||
|
defaultStaticCacheSize = 4
|
||||||
|
defaultSelfManagedUsername = "self-managed-user"
|
||||||
|
defaultSelfManagedPassword = "self-managed-password"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ ConnectionProducer = &SQLConnectionProducer{}
|
var _ ConnectionProducer = &SQLConnectionProducer{}
|
||||||
@@ -46,6 +54,7 @@ type SQLConnectionProducer struct {
|
|||||||
MaxConnectionLifetimeRaw interface{} `json:"max_connection_lifetime" mapstructure:"max_connection_lifetime" structs:"max_connection_lifetime"`
|
MaxConnectionLifetimeRaw interface{} `json:"max_connection_lifetime" mapstructure:"max_connection_lifetime" structs:"max_connection_lifetime"`
|
||||||
DisableEscaping bool `json:"disable_escaping" mapstructure:"disable_escaping" structs:"disable_escaping"`
|
DisableEscaping bool `json:"disable_escaping" mapstructure:"disable_escaping" structs:"disable_escaping"`
|
||||||
usePrivateIP bool `json:"use_private_ip" mapstructure:"use_private_ip" structs:"use_private_ip"`
|
usePrivateIP bool `json:"use_private_ip" mapstructure:"use_private_ip" structs:"use_private_ip"`
|
||||||
|
SelfManaged bool `json:"self_managed" mapstructure:"self_managed" structs:"self_managed"`
|
||||||
|
|
||||||
// Username/Password is the default auth type when AuthType is not set
|
// Username/Password is the default auth type when AuthType is not set
|
||||||
Username string `json:"username" mapstructure:"username" structs:"username"`
|
Username string `json:"username" mapstructure:"username" structs:"username"`
|
||||||
@@ -66,6 +75,7 @@ type SQLConnectionProducer struct {
|
|||||||
maxConnectionLifetime time.Duration
|
maxConnectionLifetime time.Duration
|
||||||
Initialized bool
|
Initialized bool
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
staticAccountsCache *cacheutil.Cache
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +99,11 @@ func (c *SQLConnectionProducer) Init(ctx context.Context, conf map[string]interf
|
|||||||
return nil, fmt.Errorf("connection_url cannot be empty")
|
return nil, fmt.Errorf("connection_url cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isTemplatedURL := true
|
||||||
|
if !strings.Contains(c.ConnectionURL, "{{username}}") || !strings.Contains(c.ConnectionURL, "{{password}}") {
|
||||||
|
isTemplatedURL = false
|
||||||
|
}
|
||||||
|
|
||||||
// Do not allow the username or password template pattern to be used as
|
// Do not allow the username or password template pattern to be used as
|
||||||
// part of the user-supplied username or password
|
// part of the user-supplied username or password
|
||||||
if strings.Contains(c.Username, "{{username}}") ||
|
if strings.Contains(c.Username, "{{username}}") ||
|
||||||
@@ -99,16 +114,40 @@ func (c *SQLConnectionProducer) Init(ctx context.Context, conf map[string]interf
|
|||||||
return nil, fmt.Errorf("username and/or password cannot contain the template variables")
|
return nil, fmt.Errorf("username and/or password cannot contain the template variables")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't escape special characters for MySQL password
|
// validate that at least one of username/password / self_managed is set
|
||||||
// Also don't escape special characters for the username and password if
|
if !c.SelfManaged && (c.Username == "" && c.Password == "") && isTemplatedURL {
|
||||||
// the disable_escaping parameter is set to true
|
return nil, fmt.Errorf("must either provide username/password or set self-managed to 'true'")
|
||||||
username := c.Username
|
|
||||||
password := c.Password
|
|
||||||
if !c.DisableEscaping {
|
|
||||||
username = url.PathEscape(c.Username)
|
|
||||||
}
|
}
|
||||||
if (c.Type != "mysql") && !c.DisableEscaping {
|
|
||||||
password = url.PathEscape(c.Password)
|
// validate that self-managed and username/password are mutually exclusive
|
||||||
|
if c.SelfManaged {
|
||||||
|
if (c.Username != "" || c.Password != "") || !isTemplatedURL {
|
||||||
|
return nil, fmt.Errorf("cannot use both self-managed and vault-managed workflows")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var username string
|
||||||
|
var password string
|
||||||
|
if !c.SelfManaged {
|
||||||
|
// Default behavior
|
||||||
|
username = c.Username
|
||||||
|
password = c.Password
|
||||||
|
|
||||||
|
// Don't escape special characters for MySQL password
|
||||||
|
// Also don't escape special characters for the username and password if
|
||||||
|
// the disable_escaping parameter is set to true
|
||||||
|
if !c.DisableEscaping {
|
||||||
|
username = url.PathEscape(c.Username)
|
||||||
|
}
|
||||||
|
if (c.Type != "mysql") && !c.DisableEscaping {
|
||||||
|
password = url.PathEscape(c.Password)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// this is added to make middleware happy
|
||||||
|
// these placeholders are replaced when we make the actual static connection
|
||||||
|
username = defaultSelfManagedUsername
|
||||||
|
password = defaultSelfManagedPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryHelper doesn't do any SQL escaping, but if it starts to do so
|
// QueryHelper doesn't do any SQL escaping, but if it starts to do so
|
||||||
@@ -159,11 +198,35 @@ func (c *SQLConnectionProducer) Init(ctx context.Context, conf map[string]interf
|
|||||||
c.cloudDialerCleanup = dialerCleanup
|
c.cloudDialerCleanup = dialerCleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.SelfManaged && c.staticAccountsCache == nil {
|
||||||
|
logger := log.New(&log.LoggerOptions{
|
||||||
|
Level: log.Trace,
|
||||||
|
})
|
||||||
|
|
||||||
|
closer := func(key interface{}, value interface{}) {
|
||||||
|
logger.Trace(fmt.Sprintf("Evicting key %s from static LRU cache", key))
|
||||||
|
conn, ok := value.(*sql.DB)
|
||||||
|
if !ok {
|
||||||
|
logger.Error(fmt.Sprintf("error retrieving connection %s from static LRU cache, err=%s", key, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := conn.Close(); err != nil {
|
||||||
|
logger.Error(fmt.Sprintf("error closing connection for %s, err=%s", key, err))
|
||||||
|
}
|
||||||
|
logger.Trace(fmt.Sprintf("closed DB connection for %s", key))
|
||||||
|
}
|
||||||
|
c.staticAccountsCache, err = cacheutil.NewCache(defaultStaticCacheSize, closer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error initializing static account cache: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set initialized to true at this point since all fields are set,
|
// Set initialized to true at this point since all fields are set,
|
||||||
// and the connection can be established at a later time.
|
// and the connection can be established at a later time.
|
||||||
c.Initialized = true
|
c.Initialized = true
|
||||||
|
|
||||||
if verifyConnection {
|
// only verify if not self-managed
|
||||||
|
if verifyConnection && !c.SelfManaged {
|
||||||
if _, err := c.Connection(ctx); err != nil {
|
if _, err := c.Connection(ctx); err != nil {
|
||||||
return nil, errwrap.Wrapf("error verifying connection: {{err}}", err)
|
return nil, errwrap.Wrapf("error verifying connection: {{err}}", err)
|
||||||
}
|
}
|
||||||
@@ -210,22 +273,8 @@ func (c *SQLConnectionProducer) Connection(ctx context.Context) (interface{}, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, attempt to make connection
|
// Otherwise, attempt to make connection
|
||||||
conn := c.ConnectionURL
|
// Apply PostgreSQL specific settings if needed
|
||||||
|
conn := applyPostgresSettings(c.ConnectionURL)
|
||||||
// PostgreSQL specific settings
|
|
||||||
if strings.HasPrefix(conn, "postgres://") || strings.HasPrefix(conn, "postgresql://") {
|
|
||||||
// Ensure timezone is set to UTC for all the connections
|
|
||||||
if strings.Contains(conn, "?") {
|
|
||||||
conn += "&timezone=UTC"
|
|
||||||
} else {
|
|
||||||
conn += "?timezone=UTC"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure a reasonable application_name is set
|
|
||||||
if !strings.Contains(conn, "application_name") {
|
|
||||||
conn += "&application_name=vault"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if driverName == dbTypePostgres && c.TLSConfig != nil {
|
if driverName == dbTypePostgres && c.TLSConfig != nil {
|
||||||
config, err := pgx.ParseConfig(conn)
|
config, err := pgx.ParseConfig(conn)
|
||||||
@@ -312,6 +361,25 @@ func (c *SQLConnectionProducer) SetCredentials(ctx context.Context, statements d
|
|||||||
return "", "", dbutil.Unimplemented()
|
return "", "", dbutil.Unimplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyPostgresSettings(connURL string) string {
|
||||||
|
res := connURL
|
||||||
|
if strings.HasPrefix(res, "postgres://") || strings.HasPrefix(res, "postgresql://") {
|
||||||
|
// Ensure timezone is set to UTC for all the connections
|
||||||
|
if strings.Contains(res, "?") {
|
||||||
|
res += "&timezone=UTC"
|
||||||
|
} else {
|
||||||
|
res += "?timezone=UTC"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure a reasonable application_name is set
|
||||||
|
if !strings.Contains(res, "application_name") {
|
||||||
|
res += "&application_name=vault"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
var configurableAuthTypes = map[string]bool{
|
var configurableAuthTypes = map[string]bool{
|
||||||
AuthTypeUsernamePassword: true,
|
AuthTypeUsernamePassword: true,
|
||||||
AuthTypeCert: true,
|
AuthTypeCert: true,
|
||||||
|
|||||||
16
sdk/database/helper/connutil/sql_stubs_oss.go
Normal file
16
sdk/database/helper/connutil/sql_stubs_oss.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//go:build !enterprise
|
||||||
|
|
||||||
|
package connutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *SQLConnectionProducer) StaticConnection(_ context.Context, _, _ string) (*sql.DB, error) {
|
||||||
|
return nil, errors.New("self-managed static roles only available in Vault Enterprise")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user