open-vault/command/agent/alicloud_end_to_end_test.go
2018-09-11 11:10:50 -07:00

214 lines
5.4 KiB
Go

package agent
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"os"
"strings"
"testing"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/providers"
"github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-uuid"
vaultalicloud "github.com/hashicorp/vault-plugin-auth-alicloud"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/command/agent/auth"
agentalicloud "github.com/hashicorp/vault/command/agent/auth/alicloud"
"github.com/hashicorp/vault/command/agent/sink"
"github.com/hashicorp/vault/command/agent/sink/file"
"github.com/hashicorp/vault/helper/logging"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/vault"
)
const (
envVarRunAccTests = "VAULT_ACC"
envVarAccessKey = "ALICLOUD_TEST_ACCESS_KEY"
envVarSecretKey = "ALICLOUD_TEST_SECRET_KEY"
envVarRoleArn = "ALICLOUD_TEST_ROLE_ARN"
)
var runAcceptanceTests = os.Getenv(envVarRunAccTests) == "1"
func TestAliCloudEndToEnd(t *testing.T) {
if !runAcceptanceTests {
t.SkipNow()
}
logger := logging.NewVaultLogger(hclog.Trace)
coreConfig := &vault.CoreConfig{
Logger: logger,
CredentialBackends: map[string]logical.Factory{
"alicloud": vaultalicloud.Factory,
},
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
defer cluster.Cleanup()
vault.TestWaitActive(t, cluster.Cores[0].Core)
client := cluster.Cores[0].Client
// Setup Vault
if err := client.Sys().EnableAuthWithOptions("alicloud", &api.EnableAuthOptions{
Type: "alicloud",
}); err != nil {
t.Fatal(err)
}
if _, err := client.Logical().Write("auth/alicloud/role/test", map[string]interface{}{
"arn": os.Getenv(envVarRoleArn),
}); err != nil {
t.Fatal(err)
}
ctx, cancelFunc := context.WithCancel(context.Background())
timer := time.AfterFunc(30*time.Second, func() {
cancelFunc()
})
defer timer.Stop()
// We're going to feed alicloud auth creds via env variables.
if err := setAliCloudEnvCreds(); err != nil {
t.Fatal(err)
}
defer func() {
if err := unsetAliCloudEnvCreds(); err != nil {
t.Fatal(err)
}
}()
am, err := agentalicloud.NewAliCloudAuthMethod(&auth.AuthConfig{
Logger: logger.Named("auth.alicloud"),
MountPath: "auth/alicloud",
Config: map[string]interface{}{
"role": "test",
"region": "us-west-1",
"credential_poll_interval": 1,
},
})
if err != nil {
t.Fatal(err)
}
ahConfig := &auth.AuthHandlerConfig{
Logger: logger.Named("auth.handler"),
Client: client,
}
ah := auth.NewAuthHandler(ahConfig)
go ah.Run(ctx, am)
defer func() {
<-ah.DoneCh
}()
tmpFile, err := ioutil.TempFile("", "auth.tokensink.test.")
if err != nil {
t.Fatal(err)
}
tokenSinkFileName := tmpFile.Name()
tmpFile.Close()
os.Remove(tokenSinkFileName)
t.Logf("output: %s", tokenSinkFileName)
config := &sink.SinkConfig{
Logger: logger.Named("sink.file"),
Config: map[string]interface{}{
"path": tokenSinkFileName,
},
WrapTTL: 10 * time.Second,
}
fs, err := file.NewFileSink(config)
if err != nil {
t.Fatal(err)
}
config.Sink = fs
ss := sink.NewSinkServer(&sink.SinkServerConfig{
Logger: logger.Named("sink.server"),
Client: client,
})
go ss.Run(ctx, ah.OutputCh, []*sink.SinkConfig{config})
defer func() {
<-ss.DoneCh
}()
if stat, err := os.Lstat(tokenSinkFileName); err == nil {
t.Fatalf("expected err but got %s", stat)
} else if !os.IsNotExist(err) {
t.Fatal("expected notexist err")
}
// Wait 2 seconds for the env variables to be detected and an auth to be generated.
time.Sleep(time.Second * 2)
token, err := readToken(tokenSinkFileName)
if err != nil {
t.Fatal(err)
}
if token.Token == "" {
t.Fatal("expected token but didn't receive it")
}
}
func readToken(fileName string) (*logical.HTTPWrapInfo, error) {
b, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, err
}
wrapper := &logical.HTTPWrapInfo{}
if err := json.NewDecoder(bytes.NewReader(b)).Decode(wrapper); err != nil {
return nil, err
}
return wrapper, nil
}
func setAliCloudEnvCreds() error {
config := sdk.NewConfig()
config.Scheme = "https"
client, err := sts.NewClientWithOptions("us-west-1", config, credentials.NewAccessKeyCredential(os.Getenv(envVarAccessKey), os.Getenv(envVarSecretKey)))
if err != nil {
return err
}
roleSessionName, err := uuid.GenerateUUID()
if err != nil {
return err
}
assumeRoleReq := sts.CreateAssumeRoleRequest()
assumeRoleReq.RoleArn = os.Getenv(envVarRoleArn)
assumeRoleReq.RoleSessionName = strings.Replace(roleSessionName, "-", "", -1)
assumeRoleResp, err := client.AssumeRole(assumeRoleReq)
if err != nil {
return err
}
if err := os.Setenv(providers.EnvVarAccessKeyID, assumeRoleResp.Credentials.AccessKeyId); err != nil {
return err
}
if err := os.Setenv(providers.EnvVarAccessKeySecret, assumeRoleResp.Credentials.AccessKeySecret); err != nil {
return err
}
return os.Setenv(providers.EnvVarAccessKeyStsToken, assumeRoleResp.Credentials.SecurityToken)
}
func unsetAliCloudEnvCreds() error {
if err := os.Unsetenv(providers.EnvVarAccessKeyID); err != nil {
return err
}
if err := os.Unsetenv(providers.EnvVarAccessKeySecret); err != nil {
return err
}
return os.Unsetenv(providers.EnvVarAccessKeyStsToken)
}