d0e2badbae
The result will still pass gofmtcheck and won't trigger additional changes if someone isn't using goimports, but it will avoid the piecemeal imports changes we've been seeing.
124 lines
2.9 KiB
Go
124 lines
2.9 KiB
Go
package cassandra
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gocql/gocql"
|
|
uuid "github.com/hashicorp/go-uuid"
|
|
"github.com/hashicorp/vault/helper/strutil"
|
|
"github.com/hashicorp/vault/logical"
|
|
"github.com/hashicorp/vault/logical/framework"
|
|
)
|
|
|
|
func pathCredsCreate(b *backend) *framework.Path {
|
|
return &framework.Path{
|
|
Pattern: "creds/" + framework.GenericNameRegex("name"),
|
|
Fields: map[string]*framework.FieldSchema{
|
|
"name": &framework.FieldSchema{
|
|
Type: framework.TypeString,
|
|
Description: "Name of the role",
|
|
},
|
|
},
|
|
|
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
|
logical.ReadOperation: b.pathCredsCreateRead,
|
|
},
|
|
|
|
HelpSynopsis: pathCredsCreateReadHelpSyn,
|
|
HelpDescription: pathCredsCreateReadHelpDesc,
|
|
}
|
|
}
|
|
|
|
func (b *backend) pathCredsCreateRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
|
name := data.Get("name").(string)
|
|
|
|
// Get the role
|
|
role, err := getRole(ctx, req.Storage, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if role == nil {
|
|
return logical.ErrorResponse(fmt.Sprintf("Unknown role: %s", name)), nil
|
|
}
|
|
|
|
displayName := req.DisplayName
|
|
userUUID, err := uuid.GenerateUUID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
username := fmt.Sprintf("vault_%s_%s_%s_%d", name, displayName, userUUID, time.Now().Unix())
|
|
username = strings.Replace(username, "-", "_", -1)
|
|
password, err := uuid.GenerateUUID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Get our connection
|
|
session, err := b.DB(ctx, req.Storage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Set consistency
|
|
if role.Consistency != "" {
|
|
consistencyValue, err := gocql.ParseConsistencyWrapper(role.Consistency)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
session.SetConsistency(consistencyValue)
|
|
}
|
|
|
|
// Execute each query
|
|
for _, query := range strutil.ParseArbitraryStringSlice(role.CreationCQL, ";") {
|
|
query = strings.TrimSpace(query)
|
|
if len(query) == 0 {
|
|
continue
|
|
}
|
|
|
|
err = session.Query(substQuery(query, map[string]string{
|
|
"username": username,
|
|
"password": password,
|
|
})).Exec()
|
|
if err != nil {
|
|
for _, query := range strutil.ParseArbitraryStringSlice(role.RollbackCQL, ";") {
|
|
query = strings.TrimSpace(query)
|
|
if len(query) == 0 {
|
|
continue
|
|
}
|
|
|
|
session.Query(substQuery(query, map[string]string{
|
|
"username": username,
|
|
"password": password,
|
|
})).Exec()
|
|
}
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Return the secret
|
|
resp := b.Secret(SecretCredsType).Response(map[string]interface{}{
|
|
"username": username,
|
|
"password": password,
|
|
}, map[string]interface{}{
|
|
"username": username,
|
|
"role": name,
|
|
})
|
|
resp.Secret.TTL = role.Lease
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
const pathCredsCreateReadHelpSyn = `
|
|
Request database credentials for a certain role.
|
|
`
|
|
|
|
const pathCredsCreateReadHelpDesc = `
|
|
This path creates database credentials for a certain role. The
|
|
database credentials will be generated on demand and will be automatically
|
|
revoked when the lease is up.
|
|
`
|