Add API functions for token helpers

This commit is contained in:
Seth Vargo
2017-09-02 18:48:48 -04:00
parent b67f9404a8
commit 08b39ecc49
4 changed files with 2010 additions and 32 deletions

View File

@@ -1,59 +1,131 @@
package api_test
import (
"context"
"database/sql"
"encoding/base64"
"fmt"
"net"
"net/http"
"testing"
"time"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/builtin/logical/database"
"github.com/hashicorp/vault/builtin/logical/pki"
"github.com/hashicorp/vault/builtin/logical/transit"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/vault"
auditFile "github.com/hashicorp/vault/builtin/audit/file"
credUserpass "github.com/hashicorp/vault/builtin/credential/userpass"
vaulthttp "github.com/hashicorp/vault/http"
logxi "github.com/mgutz/logxi/v1"
dockertest "gopkg.in/ory-am/dockertest.v3"
)
var testVaultServerDefaultBackends = map[string]logical.Factory{
"transit": transit.Factory,
"pki": pki.Factory,
}
// testVaultServer creates a test vault cluster and returns a configured API
// client and closer function.
func testVaultServer(t testing.TB) (*api.Client, func()) {
return testVaultServerBackends(t, testVaultServerDefaultBackends)
t.Helper()
client, _, closer := testVaultServerUnseal(t)
return client, closer
}
func testVaultServerBackends(t testing.TB, backends map[string]logical.Factory) (*api.Client, func()) {
coreConfig := &vault.CoreConfig{
DisableMlock: true,
DisableCache: true,
Logger: logxi.NullLog,
LogicalBackends: backends,
}
// testVaultServerUnseal creates a test vault cluster and returns a configured
// API client, list of unseal keys (as strings), and a closer function.
func testVaultServerUnseal(t testing.TB) (*api.Client, []string, func()) {
t.Helper()
return testVaultServerCoreConfig(t, &vault.CoreConfig{
DisableMlock: true,
DisableCache: true,
Logger: logxi.NullLog,
CredentialBackends: map[string]logical.Factory{
"userpass": credUserpass.Factory,
},
AuditBackends: map[string]audit.Factory{
"file": auditFile.Factory,
},
LogicalBackends: map[string]logical.Factory{
"database": database.Factory,
"generic-leased": vault.LeasedPassthroughBackendFactory,
"pki": pki.Factory,
"transit": transit.Factory,
},
})
}
// testVaultServerCoreConfig creates a new vault cluster with the given core
// configuration. This is a lower-level test helper.
func testVaultServerCoreConfig(t testing.TB, coreConfig *vault.CoreConfig) (*api.Client, []string, func()) {
t.Helper()
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
// make it easy to get access to the active
// Make it easy to get access to the active
core := cluster.Cores[0].Core
vault.TestWaitActive(t, core)
// Get the client already setup for us!
client := cluster.Cores[0].Client
client.SetToken(cluster.RootToken)
// Sanity check
secret, err := client.Auth().Token().LookupSelf()
// Convert the unseal keys to base64 encoded, since these are how the user
// will get them.
unsealKeys := make([]string, len(cluster.BarrierKeys))
for i := range unsealKeys {
unsealKeys[i] = base64.StdEncoding.EncodeToString(cluster.BarrierKeys[i])
}
return client, unsealKeys, func() { defer cluster.Cleanup() }
}
// testVaultServerBad creates an http server that returns a 500 on each request
// to simulate failures.
func testVaultServerBad(t testing.TB) (*api.Client, func()) {
t.Helper()
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
if secret == nil || secret.Data["id"].(string) != cluster.RootToken {
t.Fatalf("token mismatch: %#v vs %q", secret, cluster.RootToken)
server := &http.Server{
Addr: "127.0.0.1:0",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "500 internal server error", http.StatusInternalServerError)
}),
ReadTimeout: 1 * time.Second,
ReadHeaderTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
IdleTimeout: 1 * time.Second,
}
go func() {
if err := server.Serve(listener); err != nil && err != http.ErrServerClosed {
t.Fatal(err)
}
}()
client, err := api.NewClient(&api.Config{
Address: "http://" + listener.Addr().String(),
})
if err != nil {
t.Fatal(err)
}
return client, func() {
ctx, done := context.WithTimeout(context.Background(), 5*time.Second)
defer done()
server.Shutdown(ctx)
}
return client, func() { defer cluster.Cleanup() }
}
// testPostgresDB creates a testing postgres database in a Docker container,