Skip to content
This repository was archived by the owner on Mar 15, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ all: build lint test

.PHONY: build
build: vault.hcl
go install ./...

vault.hcl: vault.hcl.in
sed -e 's;@@GOBIN@@;$(GOBIN);g' < $< > $@
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ make dev
vault secrets enable -path=splunk -plugin-name=vault-plugin-splunk plugin || true
vault write splunk/config/local url="${SPLUNK_ADDR}" insecure_tls=true username=admin password="${SPLUNK_PASSWORD}" allowed_roles='*'
vault write splunk/roles/local-admin roles=admin email='[email protected]' connection=local default_ttl=30s max_ttl=5m
vault read splunk/roles/local-admin
Key Value
--- -----
connection local
default_app n/a
default_ttl 30s
email [email protected]
max_ttl 5m
roles [admin]
tz n/a
user_prefix vault
```

## Plugin Usage
Expand All @@ -82,9 +93,9 @@ Create temporary admin account:
password 439e831b-e395-9999-2cd7-856381db3394
roles [admin]
url https://localhost:8089
username vault_local-admin_okta-mweber_70c6c140-238d-e12b-3289-8e38f8c4d9f5_1553712516020311000
username vault_70c6c140-238d-e12b-3289-8e38f8c4d9f5

This creates a new user account `vault_local-admin_okta-mweber_70c6...`
This creates a new user account `vault_70c6c140-238d-e12b-3289-8e38f8c4d9f5`
with a new random password. The account was configured to have the
admin role. It will automatically be queued for deletion by vault
after the configured lease ends, in 5 minutes. We can use `vault
Expand Down
35 changes: 32 additions & 3 deletions backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func TestBackend_basic(t *testing.T) {
roleConfig := roleConfig{
Connection: "testconn",
Roles: []string{"admin"},
UserPrefix: defaultUserPrefix,
}

logicaltest.Test(t, logicaltest.TestCase{
Expand Down Expand Up @@ -85,22 +86,34 @@ func TestBackend_RoleCRUD(t *testing.T) {
t.Fatal(err)
}

roleConfig := roleConfig{
testRoleConfig := roleConfig{
Connection: "testconn",
Roles: []string{"admin"},
UserPrefix: "my-custom-prefix",
}

logicaltest.Test(t, logicaltest.TestCase{
LogicalBackend: b,
Steps: []logicaltest.TestStep{
testAccStepConfig(t),
testAccStepRole(t, "test", roleConfig),
testAccStepRole(t, "test", testRoleConfig),
testAccStepRoleMissingRoleName(t),
testAccStepRoleMissingRoles(t, "MISSING"),
testAccStepRoleRead(t, "test", roleConfig),
testAccStepRoleRead(t, "test", testRoleConfig),
testAccStepRoleDelete(t, "test"),
},
})
emptyUserPrefixConfig := roleConfig{
Connection: "testconn",
Roles: []string{"admin"},
UserPrefix: "",
}
logicaltest.Test(t, logicaltest.TestCase{
LogicalBackend: b,
Steps: []logicaltest.TestStep{
testEmptyUserPrefix(t, "test", emptyUserPrefixConfig),
},
})
}

// Test steps
Expand Down Expand Up @@ -188,6 +201,22 @@ func testAccStepRoleMissingRoleName(t *testing.T) logicaltest.TestStep {
}
}

func testEmptyUserPrefix(t *testing.T, role string, config roleConfig) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.CreateOperation,
Path: rolesPrefix + role,
Data: config.toResponseData(),
ErrorOk: true,
Check: func(resp *logical.Response) error {
if resp == nil {
return fmt.Errorf("response is nil")
}
assert.Error(t, resp.Error(), "user_prefix can't be set to empty string")
return nil
},
}
}

func testAccStepCredsRead(t *testing.T, role string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.ReadOperation,
Expand Down
8 changes: 5 additions & 3 deletions path_creds_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package splunk
import (
"context"
"fmt"
"time"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/strutil"
Expand Down Expand Up @@ -62,7 +60,11 @@ func (b *backend) credsReadHandler(ctx context.Context, req *logical.Request, d
if err != nil {
return nil, err
}
username := fmt.Sprintf("vault_%s_%s_%s_%d", name, req.DisplayName, userUUID, time.Now().UnixNano())
userPrefix := role.UserPrefix
if role.UserPrefix == defaultUserPrefix {
userPrefix = fmt.Sprintf("%s_%s", role.UserPrefix, req.DisplayName)
}
username := fmt.Sprintf("%s_%s", userPrefix, userUUID)
passwd, err := uuid.GenerateUUID()
if err != nil {
return nil, errwrap.Wrapf("error generating new password {{err}}", err)
Expand Down
12 changes: 12 additions & 0 deletions path_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

const rolesPrefix = "roles/"
const defaultUserPrefix = "vault"

func (b *backend) pathRoles() *framework.Path {
return &framework.Path{
Expand Down Expand Up @@ -47,6 +48,11 @@ func (b *backend) pathRoles() *framework.Path {
Type: framework.TypeString,
Description: "User time zone.",
},
"user_prefix": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Prefix for creating new users",
Default: defaultUserPrefix,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.rolesReadHandler,
Expand Down Expand Up @@ -124,6 +130,12 @@ func (b *backend) rolesWriteHandler(ctx context.Context, req *logical.Request, d
if tzRaw, ok := getValue(data, req.Operation, "tz"); ok {
role.TZ = tzRaw.(string)
}
if userPrefixRaw, ok := getValue(data, req.Operation, "user_prefix"); ok {
role.UserPrefix = userPrefixRaw.(string)
}
if role.UserPrefix == "" {
return logical.ErrorResponse("user_prefix can't be set to empty string"), nil
}

if err := role.store(ctx, req.Storage, name); err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions role.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type roleConfig struct {
DefaultApp string `json:"default_app,omitempty" structs:"default_app"`
Email string `json:"email,omitempty" structs:"email"`
TZ string `json:"tz,omitempty" structs:"tz"`
UserPrefix string `json:"user_prefix,omitempty" structs:"user_prefix"`
}

// Role returns nil if role named `name` does not exist in `storage`, otherwise
Expand Down