2017-05-11 21:38:54 +00:00
package cassandra
2017-04-13 20:48:32 +00:00
import (
2017-12-14 22:03:11 +00:00
"context"
2017-04-13 20:48:32 +00:00
"crypto/tls"
"fmt"
"strings"
"sync"
"time"
"github.com/mitchellh/mapstructure"
"github.com/gocql/gocql"
2018-03-21 19:05:56 +00:00
"github.com/hashicorp/errwrap"
Combined Database Backend: Static Accounts (#6834)
* Add priority queue to sdk
* fix issue of storing pointers and now copy
* update to use copy structure
* Remove file, put Item struct def. into other file
* add link
* clean up docs
* refactor internal data structure to hide heap method implementations. Other cleanup after feedback
* rename PushItem and PopItem to just Push/Pop, after encapsulating the heap methods
* updates after feedback
* refactoring/renaming
* guard against pushing a nil item
* minor updates after feedback
* Add SetCredentials, GenerateCredentials gRPC methods to combined database backend gPRC
* Initial Combined database backend implementation of static accounts and automatic rotation
* vendor updates
* initial implementation of static accounts with Combined database backend, starting with PostgreSQL implementation
* add lock and setup of rotation queue
* vendor the queue
* rebase on new method signature of queue
* remove mongo tests for now
* update default role sql
* gofmt after rebase
* cleanup after rebasing to remove checks for ErrNotFound error
* rebase cdcr-priority-queue
* vendor dependencies with 'go mod vendor'
* website database docs for Static Role support
* document the rotate-role API endpoint
* postgres specific static role docs
* use constants for paths
* updates from review
* remove dead code
* combine and clarify error message for older plugins
* Update builtin/logical/database/backend.go
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* cleanups from feedback
* code and comment cleanups
* move db.RLock higher to protect db.GenerateCredentials call
* Return output with WALID if we failed to delete the WAL
* Update builtin/logical/database/path_creds_create.go
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* updates after running 'make fmt'
* update after running 'make proto'
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* update comment and remove and rearrange some dead code
* Update website/source/api/secret/databases/index.html.md
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* cleanups after review
* Update sdk/database/dbplugin/grpc_transport.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* code cleanup after feedback
* remove PasswordLastSet; it's not used
* document GenerateCredentials and SetCredentials
* Update builtin/logical/database/path_rotate_credentials.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* wrap pop and popbykey in backend methods to protect against nil cred rotation queue
* use strings.HasPrefix instead of direct equality check for path
* Forgot to commit this
* updates after feedback
* re-purpose an outdated test to now check that static and dynamic roles cannot share a name
* check for unique name across dynamic and static roles
* refactor loadStaticWALs to return a map of name/setCredentialsWAL struct to consolidate where we're calling set credentials
* remove commented out code
* refactor to have loadstaticwals filter out wals for roles that no longer exist
* return error if nil input given
* add nil check for input into setStaticAccount
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* add constant for queue tick time in seconds, used for comparrison in updates
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* code cleanup after review
* remove misplaced code comment
* remove commented out code
* create a queue in the Factory method, even if it's never used
* update path_roles to use a common set of fields, with specific overrides for dynamic/static roles by type
* document new method
* move rotation things into a specific file
* rename test file and consolidate some static account tests
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* update code comments, method names, and move more methods into rotation.go
* update comments to be capitalized
* remove the item from the queue before we try to destroy it
* findStaticWAL returns an error
* use lowercase keys when encoding WAL entries
* small cleanups
* remove vestigial static account check
* remove redundant DeleteWAL call in populate queue
* if we error on loading role, push back to queue with 10 second backoff
* poll in initqueue to make sure the backend is setup and can write/delete data
* add revoke_user_on_delete flag to allow users to opt-in to revoking the static database user on delete of the Vault role. Default false
* add code comments on read-only loop
* code comment updates
* re-push if error returned from find static wal
* add locksutil and acquire locks when pop'ing from the queue
* grab exclusive locks for updating static roles
* Add SetCredentials and GenerateCredentials stubs to mockPlugin
* add a switch in initQueue to listen for cancelation
* remove guard on zero time, it should have no affect
* create a new context in Factory to pass on and use for closing the backend queue
* restore master copy of vendor dir
2019-06-19 19:45:39 +00:00
"github.com/hashicorp/vault/sdk/database/dbplugin"
2019-04-15 18:10:07 +00:00
"github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/sdk/database/helper/dbutil"
2019-04-12 21:54:35 +00:00
"github.com/hashicorp/vault/sdk/helper/certutil"
"github.com/hashicorp/vault/sdk/helper/parseutil"
2019-04-12 22:26:54 +00:00
"github.com/hashicorp/vault/sdk/helper/tlsutil"
2017-04-13 20:48:32 +00:00
)
2017-05-11 21:38:54 +00:00
// cassandraConnectionProducer implements ConnectionProducer and provides an
2017-04-13 20:48:32 +00:00
// interface for cassandra databases to make connections.
2017-05-11 21:38:54 +00:00
type cassandraConnectionProducer struct {
2019-02-10 23:34:50 +00:00
Hosts string ` json:"hosts" structs:"hosts" mapstructure:"hosts" `
Port int ` json:"port" structs:"port" mapstructure:"port" `
Username string ` json:"username" structs:"username" mapstructure:"username" `
Password string ` json:"password" structs:"password" mapstructure:"password" `
TLS bool ` json:"tls" structs:"tls" mapstructure:"tls" `
InsecureTLS bool ` json:"insecure_tls" structs:"insecure_tls" mapstructure:"insecure_tls" `
ProtocolVersion int ` json:"protocol_version" structs:"protocol_version" mapstructure:"protocol_version" `
ConnectTimeoutRaw interface { } ` json:"connect_timeout" structs:"connect_timeout" mapstructure:"connect_timeout" `
SocketKeepAliveRaw interface { } ` json:"socket_keep_alive" structs:"socket_keep_alive" mapstructure:"socket_keep_alive" `
TLSMinVersion string ` json:"tls_min_version" structs:"tls_min_version" mapstructure:"tls_min_version" `
Consistency string ` json:"consistency" structs:"consistency" mapstructure:"consistency" `
2019-03-18 13:28:20 +00:00
LocalDatacenter string ` json:"local_datacenter" structs:"local_datacenter" mapstructure:"local_datacenter" `
2019-02-10 23:34:50 +00:00
PemBundle string ` json:"pem_bundle" structs:"pem_bundle" mapstructure:"pem_bundle" `
PemJSON string ` json:"pem_json" structs:"pem_json" mapstructure:"pem_json" `
2019-10-14 22:36:49 +00:00
SkipVerification bool ` json:"skip_verification" structs:"skip_verification" mapstructure:"skip_verification" `
2019-02-10 23:34:50 +00:00
connectTimeout time . Duration
socketKeepAlive time . Duration
certificate string
privateKey string
issuingCA string
rawConfig map [ string ] interface { }
2017-05-03 22:36:49 +00:00
Initialized bool
Type string
session * gocql . Session
2017-04-13 20:48:32 +00:00
sync . Mutex
}
2017-12-14 22:03:11 +00:00
func ( c * cassandraConnectionProducer ) Initialize ( ctx context . Context , conf map [ string ] interface { } , verifyConnection bool ) error {
2018-03-21 19:05:56 +00:00
_ , err := c . Init ( ctx , conf , verifyConnection )
return err
}
func ( c * cassandraConnectionProducer ) Init ( ctx context . Context , conf map [ string ] interface { } , verifyConnection bool ) ( map [ string ] interface { } , error ) {
2017-04-13 20:48:32 +00:00
c . Lock ( )
defer c . Unlock ( )
2018-03-21 19:05:56 +00:00
c . rawConfig = conf
2017-06-15 01:59:27 +00:00
err := mapstructure . WeakDecode ( conf , c )
2017-04-13 20:48:32 +00:00
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , err
2017-04-13 20:48:32 +00:00
}
2017-05-03 20:45:27 +00:00
if c . ConnectTimeoutRaw == nil {
c . ConnectTimeoutRaw = "0s"
}
2017-05-03 20:11:30 +00:00
c . connectTimeout , err = parseutil . ParseDurationSecond ( c . ConnectTimeoutRaw )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "invalid connect_timeout: {{err}}" , err )
2017-05-03 20:11:30 +00:00
}
2019-02-10 23:34:50 +00:00
if c . SocketKeepAliveRaw == nil {
c . SocketKeepAliveRaw = "0s"
}
c . socketKeepAlive , err = parseutil . ParseDurationSecond ( c . SocketKeepAliveRaw )
if err != nil {
return nil , errwrap . Wrapf ( "invalid socket_keep_alive: {{err}}" , err )
}
2017-05-03 22:36:49 +00:00
switch {
case len ( c . Hosts ) == 0 :
2018-03-21 19:05:56 +00:00
return nil , fmt . Errorf ( "hosts cannot be empty" )
2017-05-03 22:36:49 +00:00
case len ( c . Username ) == 0 :
2018-03-21 19:05:56 +00:00
return nil , fmt . Errorf ( "username cannot be empty" )
2017-05-03 22:36:49 +00:00
case len ( c . Password ) == 0 :
2018-03-21 19:05:56 +00:00
return nil , fmt . Errorf ( "password cannot be empty" )
2017-05-03 22:36:49 +00:00
}
var certBundle * certutil . CertBundle
var parsedCertBundle * certutil . ParsedCertBundle
switch {
case len ( c . PemJSON ) != 0 :
parsedCertBundle , err = certutil . ParsePKIJSON ( [ ] byte ( c . PemJSON ) )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "could not parse given JSON; it must be in the format of the output of the PKI backend certificate issuing command: {{err}}" , err )
2017-05-03 22:36:49 +00:00
}
certBundle , err = parsedCertBundle . ToCertBundle ( )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "Error marshaling PEM information: {{err}}" , err )
2017-05-03 22:36:49 +00:00
}
c . certificate = certBundle . Certificate
c . privateKey = certBundle . PrivateKey
c . issuingCA = certBundle . IssuingCA
c . TLS = true
case len ( c . PemBundle ) != 0 :
parsedCertBundle , err = certutil . ParsePEMBundle ( c . PemBundle )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "Error parsing the given PEM information: {{err}}" , err )
2017-05-03 22:36:49 +00:00
}
certBundle , err = parsedCertBundle . ToCertBundle ( )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "Error marshaling PEM information: {{err}}" , err )
2017-05-03 22:36:49 +00:00
}
c . certificate = certBundle . Certificate
c . privateKey = certBundle . PrivateKey
c . issuingCA = certBundle . IssuingCA
c . TLS = true
}
2017-05-11 21:38:54 +00:00
// Set initialized to true at this point since all fields are set,
// and the connection can be established at a later time.
c . Initialized = true
2017-04-13 20:48:32 +00:00
if verifyConnection {
2017-12-14 22:03:11 +00:00
if _ , err := c . Connection ( ctx ) ; err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "error verifying connection: {{err}}" , err )
2017-04-13 20:48:32 +00:00
}
}
2017-05-11 21:38:54 +00:00
2018-03-21 19:05:56 +00:00
return conf , nil
2017-04-13 20:48:32 +00:00
}
2019-06-21 21:04:50 +00:00
func ( c * cassandraConnectionProducer ) Connection ( ctx context . Context ) ( interface { } , error ) {
2017-04-13 20:48:32 +00:00
if ! c . Initialized {
2017-05-11 21:38:54 +00:00
return nil , connutil . ErrNotInitialized
2017-04-13 20:48:32 +00:00
}
// If we already have a DB, return it
2017-12-19 15:26:46 +00:00
if c . session != nil && ! c . session . Closed ( ) {
2017-04-13 20:48:32 +00:00
return c . session , nil
}
2019-06-21 21:04:50 +00:00
session , err := c . createSession ( ctx )
2017-04-13 20:48:32 +00:00
if err != nil {
return nil , err
}
// Store the session in backend for reuse
c . session = session
return session , nil
}
2017-05-11 21:38:54 +00:00
func ( c * cassandraConnectionProducer ) Close ( ) error {
2017-04-13 20:48:32 +00:00
// Grab the write lock
c . Lock ( )
defer c . Unlock ( )
if c . session != nil {
c . session . Close ( )
}
c . session = nil
return nil
}
2019-06-21 21:04:50 +00:00
func ( c * cassandraConnectionProducer ) createSession ( ctx context . Context ) ( * gocql . Session , error ) {
2017-09-08 03:04:40 +00:00
hosts := strings . Split ( c . Hosts , "," )
clusterConfig := gocql . NewCluster ( hosts ... )
2017-04-13 20:48:32 +00:00
clusterConfig . Authenticator = gocql . PasswordAuthenticator {
Username : c . Username ,
Password : c . Password ,
}
2017-09-08 03:04:40 +00:00
if c . Port != 0 {
clusterConfig . Port = c . Port
}
2017-04-13 20:48:32 +00:00
clusterConfig . ProtoVersion = c . ProtocolVersion
if clusterConfig . ProtoVersion == 0 {
clusterConfig . ProtoVersion = 2
}
2017-05-03 20:11:30 +00:00
clusterConfig . Timeout = c . connectTimeout
2019-02-10 23:34:50 +00:00
clusterConfig . SocketKeepalive = c . socketKeepAlive
2017-04-13 20:48:32 +00:00
if c . TLS {
var tlsConfig * tls . Config
2017-05-03 22:36:49 +00:00
if len ( c . certificate ) > 0 || len ( c . issuingCA ) > 0 {
if len ( c . certificate ) > 0 && len ( c . privateKey ) == 0 {
2017-04-23 01:02:57 +00:00
return nil , fmt . Errorf ( "found certificate for TLS authentication but no private key" )
2017-04-13 20:48:32 +00:00
}
certBundle := & certutil . CertBundle { }
2017-05-03 22:36:49 +00:00
if len ( c . certificate ) > 0 {
certBundle . Certificate = c . certificate
certBundle . PrivateKey = c . privateKey
2017-04-13 20:48:32 +00:00
}
2017-05-03 22:36:49 +00:00
if len ( c . issuingCA ) > 0 {
certBundle . IssuingCA = c . issuingCA
2017-04-13 20:48:32 +00:00
}
parsedCertBundle , err := certBundle . ToParsedCertBundle ( )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "failed to parse certificate bundle: {{err}}" , err )
2017-04-13 20:48:32 +00:00
}
tlsConfig , err = parsedCertBundle . GetTLSConfig ( certutil . TLSClient )
if err != nil || tlsConfig == nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( fmt . Sprintf ( "failed to get TLS configuration: tlsConfig:%#v err:{{err}}" , tlsConfig ) , err )
2017-04-13 20:48:32 +00:00
}
tlsConfig . InsecureSkipVerify = c . InsecureTLS
if c . TLSMinVersion != "" {
var ok bool
tlsConfig . MinVersion , ok = tlsutil . TLSLookup [ c . TLSMinVersion ]
if ! ok {
return nil , fmt . Errorf ( "invalid 'tls_min_version' in config" )
}
} else {
// MinVersion was not being set earlier. Reset it to
// zero to gracefully handle upgrades.
tlsConfig . MinVersion = 0
}
}
clusterConfig . SslOpts = & gocql . SslOptions {
2017-04-19 18:19:29 +00:00
Config : tlsConfig ,
2017-04-13 20:48:32 +00:00
}
}
2019-03-14 20:37:28 +00:00
if c . LocalDatacenter != "" {
clusterConfig . PoolConfig . HostSelectionPolicy = gocql . DCAwareRoundRobinPolicy ( c . LocalDatacenter )
}
2017-04-13 20:48:32 +00:00
session , err := clusterConfig . CreateSession ( )
if err != nil {
2018-03-21 19:05:56 +00:00
return nil , errwrap . Wrapf ( "error creating session: {{err}}" , err )
2017-04-13 20:48:32 +00:00
}
// Set consistency
if c . Consistency != "" {
consistencyValue , err := gocql . ParseConsistencyWrapper ( c . Consistency )
if err != nil {
2019-10-10 18:45:59 +00:00
session . Close ( )
2017-04-13 20:48:32 +00:00
return nil , err
}
session . SetConsistency ( consistencyValue )
}
// Verify the info
2019-10-14 22:36:49 +00:00
if ! c . SkipVerification {
err = session . Query ( ` LIST ALL ` ) . WithContext ( ctx ) . Exec ( )
if err != nil && len ( c . Username ) != 0 && strings . Contains ( err . Error ( ) , "not authorized" ) {
rowNum := session . Query ( dbutil . QueryHelper ( ` LIST CREATE ON ALL ROLES OF ' {{ username }} '; ` , map [ string ] string {
"username" : c . Username ,
} ) ) . Iter ( ) . NumRows ( )
if rowNum < 1 {
session . Close ( )
return nil , errwrap . Wrapf ( "error validating connection info: No role create permissions found, previous error: {{err}}" , err )
}
} else if err != nil {
2019-10-10 18:45:59 +00:00
session . Close ( )
2019-10-14 22:36:49 +00:00
return nil , errwrap . Wrapf ( "error validating connection info: {{err}}" , err )
2018-10-15 15:06:03 +00:00
}
2017-04-13 20:48:32 +00:00
}
return session , nil
}
2018-03-21 19:05:56 +00:00
func ( c * cassandraConnectionProducer ) secretValues ( ) map [ string ] interface { } {
return map [ string ] interface { } {
c . Password : "[password]" ,
c . PemBundle : "[pem_bundle]" ,
c . PemJSON : "[pem_json]" ,
}
}
Combined Database Backend: Static Accounts (#6834)
* Add priority queue to sdk
* fix issue of storing pointers and now copy
* update to use copy structure
* Remove file, put Item struct def. into other file
* add link
* clean up docs
* refactor internal data structure to hide heap method implementations. Other cleanup after feedback
* rename PushItem and PopItem to just Push/Pop, after encapsulating the heap methods
* updates after feedback
* refactoring/renaming
* guard against pushing a nil item
* minor updates after feedback
* Add SetCredentials, GenerateCredentials gRPC methods to combined database backend gPRC
* Initial Combined database backend implementation of static accounts and automatic rotation
* vendor updates
* initial implementation of static accounts with Combined database backend, starting with PostgreSQL implementation
* add lock and setup of rotation queue
* vendor the queue
* rebase on new method signature of queue
* remove mongo tests for now
* update default role sql
* gofmt after rebase
* cleanup after rebasing to remove checks for ErrNotFound error
* rebase cdcr-priority-queue
* vendor dependencies with 'go mod vendor'
* website database docs for Static Role support
* document the rotate-role API endpoint
* postgres specific static role docs
* use constants for paths
* updates from review
* remove dead code
* combine and clarify error message for older plugins
* Update builtin/logical/database/backend.go
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* cleanups from feedback
* code and comment cleanups
* move db.RLock higher to protect db.GenerateCredentials call
* Return output with WALID if we failed to delete the WAL
* Update builtin/logical/database/path_creds_create.go
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* updates after running 'make fmt'
* update after running 'make proto'
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* update comment and remove and rearrange some dead code
* Update website/source/api/secret/databases/index.html.md
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* cleanups after review
* Update sdk/database/dbplugin/grpc_transport.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* code cleanup after feedback
* remove PasswordLastSet; it's not used
* document GenerateCredentials and SetCredentials
* Update builtin/logical/database/path_rotate_credentials.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* wrap pop and popbykey in backend methods to protect against nil cred rotation queue
* use strings.HasPrefix instead of direct equality check for path
* Forgot to commit this
* updates after feedback
* re-purpose an outdated test to now check that static and dynamic roles cannot share a name
* check for unique name across dynamic and static roles
* refactor loadStaticWALs to return a map of name/setCredentialsWAL struct to consolidate where we're calling set credentials
* remove commented out code
* refactor to have loadstaticwals filter out wals for roles that no longer exist
* return error if nil input given
* add nil check for input into setStaticAccount
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* add constant for queue tick time in seconds, used for comparrison in updates
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Jim Kalafut <jim@kalafut.net>
* code cleanup after review
* remove misplaced code comment
* remove commented out code
* create a queue in the Factory method, even if it's never used
* update path_roles to use a common set of fields, with specific overrides for dynamic/static roles by type
* document new method
* move rotation things into a specific file
* rename test file and consolidate some static account tests
* Update builtin/logical/database/path_roles.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* Update builtin/logical/database/rotation.go
Co-Authored-By: Brian Kassouf <briankassouf@users.noreply.github.com>
* update code comments, method names, and move more methods into rotation.go
* update comments to be capitalized
* remove the item from the queue before we try to destroy it
* findStaticWAL returns an error
* use lowercase keys when encoding WAL entries
* small cleanups
* remove vestigial static account check
* remove redundant DeleteWAL call in populate queue
* if we error on loading role, push back to queue with 10 second backoff
* poll in initqueue to make sure the backend is setup and can write/delete data
* add revoke_user_on_delete flag to allow users to opt-in to revoking the static database user on delete of the Vault role. Default false
* add code comments on read-only loop
* code comment updates
* re-push if error returned from find static wal
* add locksutil and acquire locks when pop'ing from the queue
* grab exclusive locks for updating static roles
* Add SetCredentials and GenerateCredentials stubs to mockPlugin
* add a switch in initQueue to listen for cancelation
* remove guard on zero time, it should have no affect
* create a new context in Factory to pass on and use for closing the backend queue
* restore master copy of vendor dir
2019-06-19 19:45:39 +00:00
// SetCredentials uses provided information to set/create a user in the
// database. Unlike CreateUser, this method requires a username be provided and
// uses the name given, instead of generating a name. This is used for creating
// and setting the password of static accounts, as well as rolling back
// passwords in the database in the event an updated database fails to save in
// Vault's storage.
func ( c * cassandraConnectionProducer ) SetCredentials ( ctx context . Context , statements dbplugin . Statements , staticUser dbplugin . StaticUserConfig ) ( username , password string , err error ) {
return "" , "" , dbutil . Unimplemented ( )
}