test/plugin: test external plugin workflows (#19090)

* test/plugin: test external plugin workflows

* update secrets engine test
This commit is contained in:
John-Michael Faircloth 2023-02-09 10:16:16 -06:00 committed by GitHub
parent 720ab09feb
commit 34fd57ac08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 254 additions and 0 deletions

View File

@ -0,0 +1,254 @@
package plugin_test
import (
"context"
"fmt"
"testing"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/api/auth/approle"
"github.com/hashicorp/vault/helper/testhelpers/consul"
"github.com/hashicorp/vault/helper/testhelpers/corehelpers"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/vault"
)
// TestExternalPlugin_AuthMethod tests that we can build, register and use an
// external auth method
func TestExternalPlugin_AuthMethod(t *testing.T) {
pluginDir, cleanup := corehelpers.MakeTestPluginDir(t)
t.Cleanup(func() { cleanup(t) })
coreConfig := &vault.CoreConfig{
BuiltinRegistry: corehelpers.NewMockBuiltinRegistry(),
PluginDirectory: pluginDir,
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
Plugins: &vault.TestPluginConfig{
Typ: consts.PluginTypeCredential,
Versions: []string{""},
},
HandlerFunc: vaulthttp.Handler,
})
plugin := cluster.Plugins[0]
cluster.Start()
defer cluster.Cleanup()
cores := cluster.Cores
vault.TestWaitActive(t, cores[0].Core)
client := cores[0].Client
client.SetToken(cluster.RootToken)
// Register
if err := client.Sys().RegisterPlugin(&api.RegisterPluginInput{
Name: plugin.Name,
Type: api.PluginType(plugin.Typ),
Command: plugin.Name,
SHA256: plugin.Sha256,
Version: plugin.Version,
}); err != nil {
t.Fatal(err)
}
pluginPath := fmt.Sprintf("%s-%d", plugin.Name, 0)
// Enable
if err := client.Sys().EnableAuthWithOptions(pluginPath, &api.EnableAuthOptions{
Type: plugin.Name,
}); err != nil {
t.Fatal(err)
}
// Configure
_, err := client.Logical().Write("auth/"+pluginPath+"/role/role1", map[string]interface{}{
"bind_secret_id": "true",
"period": "300",
})
if err != nil {
t.Fatal(err)
}
secret, err := client.Logical().Write("auth/"+pluginPath+"/role/role1/secret-id", nil)
if err != nil {
t.Fatal(err)
}
secretID := secret.Data["secret_id"].(string)
secret, err = client.Logical().Read("auth/" + pluginPath + "/role/role1/role-id")
if err != nil {
t.Fatal(err)
}
roleID := secret.Data["role_id"].(string)
// Login - expect SUCCESS
authMethod, err := approle.NewAppRoleAuth(
roleID,
&approle.SecretID{FromString: secretID},
approle.WithMountPath(pluginPath),
)
if err != nil {
t.Fatal(err)
}
_, err = client.Auth().Login(context.Background(), authMethod)
if err != nil {
t.Fatal(err)
}
// Reset root token
client.SetToken(cluster.RootToken)
// Reload plugin
if _, err := client.Sys().ReloadPlugin(&api.ReloadPluginInput{
Plugin: plugin.Name,
}); err != nil {
t.Fatal(err)
}
// Login - expect SUCCESS
resp, err := client.Auth().Login(context.Background(), authMethod)
if err != nil {
t.Fatal(err)
}
// Renew
resp, err = client.Auth().Token().RenewSelf(30)
if err != nil {
t.Fatal(err)
}
// Login - expect SUCCESS
resp, err = client.Auth().Login(context.Background(), authMethod)
if err != nil {
t.Fatal(err)
}
revokeToken := resp.Auth.ClientToken
// Revoke
if err = client.Auth().Token().RevokeSelf(revokeToken); err != nil {
t.Fatal(err)
}
// Reset root token
client.SetToken(cluster.RootToken)
// Lookup - expect FAILURE
resp, err = client.Auth().Token().Lookup(revokeToken)
if err == nil {
t.Fatalf("expected error, got nil")
}
// Reset root token
client.SetToken(cluster.RootToken)
// Deregister
if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{
Name: plugin.Name,
Type: api.PluginType(plugin.Typ),
Version: plugin.Version,
}); err != nil {
t.Fatal(err)
}
}
// TestExternalPlugin_SecretsEngine tests that we can build, register and use an
// external secrets engine
func TestExternalPlugin_SecretsEngine(t *testing.T) {
pluginDir, cleanup := corehelpers.MakeTestPluginDir(t)
t.Cleanup(func() { cleanup(t) })
coreConfig := &vault.CoreConfig{
BuiltinRegistry: corehelpers.NewMockBuiltinRegistry(),
PluginDirectory: pluginDir,
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
Plugins: &vault.TestPluginConfig{
Typ: consts.PluginTypeSecrets,
Versions: []string{""},
},
HandlerFunc: vaulthttp.Handler,
})
plugin := cluster.Plugins[0]
cluster.Start()
defer cluster.Cleanup()
cores := cluster.Cores
vault.TestWaitActive(t, cores[0].Core)
client := cores[0].Client
client.SetToken(cluster.RootToken)
// Register
if err := client.Sys().RegisterPlugin(&api.RegisterPluginInput{
Name: plugin.Name,
Type: api.PluginType(plugin.Typ),
Command: plugin.Name,
SHA256: plugin.Sha256,
Version: plugin.Version,
}); err != nil {
t.Fatal(err)
}
// Enable
if err := client.Sys().Mount(plugin.Name, &api.EnableAuthOptions{
Type: plugin.Name,
}); err != nil {
t.Fatal(err)
}
// Configure
cleanupConsul, consulConfig := consul.PrepareTestContainer(t, "", false, true)
defer cleanupConsul()
_, err := client.Logical().Write(plugin.Name+"/config/access", map[string]interface{}{
"address": consulConfig.Address(),
"token": consulConfig.Token,
})
if err != nil {
t.Fatal(err)
}
_, err = client.Logical().Write(plugin.Name+"/roles/test", map[string]interface{}{
"consul_policies": []string{"test"},
"ttl": "6h",
"local": false,
})
if err != nil {
t.Fatal(err)
}
resp, err := client.Logical().Read(plugin.Name + "/creds/test")
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("read creds response is nil")
}
// Reload plugin
if _, err := client.Sys().ReloadPlugin(&api.ReloadPluginInput{
Plugin: plugin.Name,
}); err != nil {
t.Fatal(err)
}
resp, err = client.Logical().Read(plugin.Name + "/creds/test")
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("read creds response is nil")
}
// Deregister
if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{
Name: plugin.Name,
Type: api.PluginType(plugin.Typ),
Version: plugin.Version,
}); err != nil {
t.Fatal(err)
}
}