Skip to content

Commit

Permalink
Add ability to skip 'LIST ALL' check
Browse files Browse the repository at this point in the history
Currently whenever we start a new C* session in the database plugin, we
run `LIST ALL` to determine whether we are a superuser, or otherwise
have permissions on roles. This is a fairly sensible way of checking
this, except it can be really slow when you have a lot of roles (C*
isn't so good at listing things). It's also really intensive to C* and
leads to a lot of data transfer. We've seen timeout issues when doing
this query, and can of course raise the timeout, but we'd probably
prefer to be able to switch it off.
  • Loading branch information
jackkleeman committed Oct 11, 2019
1 parent 051fcb3 commit 94356c1
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
25 changes: 14 additions & 11 deletions plugins/database/cassandra/connection_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type cassandraConnectionProducer struct {
LocalDatacenter string `json:"local_datacenter" structs:"local_datacenter" mapstructure:"local_datacenter"`
PemBundle string `json:"pem_bundle" structs:"pem_bundle" mapstructure:"pem_bundle"`
PemJSON string `json:"pem_json" structs:"pem_json" mapstructure:"pem_json"`
SkipVerification bool `json:"skip_verification" structs:"skip_verification" mapstructure:"skip_verification"`

connectTimeout time.Duration
socketKeepAlive time.Duration
Expand Down Expand Up @@ -257,19 +258,21 @@ func (c *cassandraConnectionProducer) createSession(ctx context.Context) (*gocql
}

// Verify the info
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 {
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 {
session.Close()
return nil, errwrap.Wrapf("error validating connection info: No role create permissions found, previous error: {{err}}", err)
return nil, errwrap.Wrapf("error validating connection info: {{err}}", err)
}
} else if err != nil {
session.Close()
return nil, errwrap.Wrapf("error validating connection info: {{err}}", err)
}

return session, nil
Expand Down
4 changes: 4 additions & 0 deletions website/source/api/secret/databases/cassandra.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ has a number of parameters to further configure a connection.
`issue` command from the `pki` secrets engine; see
[the pki documentation](/docs/secrets/pki/index.html).

- `skip_verification` `(bool: false)` - Skip permissions checks when a connection to Cassandra
is first created. These checks ensure that Vault is able to create roles, but can be resource
intensive in clusters with many roles.

- `protocol_version` `(int: 2)` – Specifies the CQL protocol version to use.

- `connect_timeout` `(string: "5s")` – Specifies the connection timeout to use.
Expand Down

0 comments on commit 94356c1

Please sign in to comment.