consul/command/acl/token/clone/token_clone_test.go
Matt Keeler a704ebe639
Add Namespace support to the API module and the CLI commands (#6874)
Also update the Docs and fixup the HTTP API to return proper errors when someone attempts to use Namespaces with an OSS agent.

Add Namespace HTTP API docs

Make all API endpoints disallow unknown fields
2019-12-06 11:14:56 -05:00

170 lines
4.0 KiB
Go

package tokenclone
import (
"os"
"regexp"
"strconv"
"strings"
"testing"
"github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/testrpc"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
)
func parseCloneOutput(t *testing.T, output string) *api.ACLToken {
// This will only work for non-legacy tokens
re := regexp.MustCompile("Token cloned successfully.\n" +
"AccessorID: ([a-zA-Z0-9\\-]{36})\n" +
"SecretID: ([a-zA-Z0-9\\-]{36})\n" +
"(?:Namespace: default\n)?" +
"Description: ([^\n]*)\n" +
"Local: (true|false)\n" +
"Create Time: ([^\n]+)\n" +
"Policies:\n" +
"( [a-zA-Z0-9\\-]{36} - [^\n]+\n)*")
submatches := re.FindStringSubmatch(output)
require.Lenf(t, submatches, 7, "Didn't match: %q", output)
local, err := strconv.ParseBool(submatches[4])
require.NoError(t, err)
token := &api.ACLToken{
AccessorID: submatches[1],
SecretID: submatches[2],
Description: submatches[3],
Local: local,
}
if len(submatches[6]) > 0 {
policyRe := regexp.MustCompile(" ([a-zA-Z0-9\\-]{36}) - ([^\n]+)")
for _, m := range policyRe.FindAllStringSubmatch(submatches[6], -1) {
token.Policies = append(token.Policies, &api.ACLTokenPolicyLink{ID: m[1], Name: m[2]})
}
}
return token
}
func TestTokenCloneCommand_noTabs(t *testing.T) {
t.Parallel()
if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') {
t.Fatal("help has tabs")
}
}
func TestTokenCloneCommand(t *testing.T) {
t.Parallel()
req := require.New(t)
testDir := testutil.TempDir(t, "acl")
defer os.RemoveAll(testDir)
a := agent.NewTestAgent(t, t.Name(), `
primary_datacenter = "dc1"
acl {
enabled = true
tokens {
master = "root"
}
}`)
a.Agent.LogWriter = logger.NewLogWriter(512)
defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
// Create a policy
client := a.Client()
_, _, err := client.ACL().PolicyCreate(
&api.ACLPolicy{Name: "test-policy"},
&api.WriteOptions{Token: "root"},
)
req.NoError(err)
// create a token
token, _, err := client.ACL().TokenCreate(
&api.ACLToken{Description: "test", Policies: []*api.ACLTokenPolicyLink{&api.ACLTokenPolicyLink{Name: "test-policy"}}},
&api.WriteOptions{Token: "root"},
)
req.NoError(err)
// clone with description
t.Run("Description", func(t *testing.T) {
ui := cli.NewMockUi()
cmd := New(ui)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-id=" + token.AccessorID,
"-token=root",
"-description=test cloned",
}
code := cmd.Run(args)
req.Empty(ui.ErrorWriter.String())
req.Equal(code, 0)
cloned := parseCloneOutput(t, ui.OutputWriter.String())
req.Equal("test cloned", cloned.Description)
req.Len(cloned.Policies, 1)
apiToken, _, err := client.ACL().TokenRead(
cloned.AccessorID,
&api.QueryOptions{Token: "root"},
)
req.NoError(err)
req.NotNil(apiToken)
req.Equal(cloned.AccessorID, apiToken.AccessorID)
req.Equal(cloned.SecretID, apiToken.SecretID)
req.Equal(cloned.Description, apiToken.Description)
req.Equal(cloned.Local, apiToken.Local)
req.Equal(cloned.Policies, apiToken.Policies)
})
// clone without description
t.Run("Without Description", func(t *testing.T) {
ui := cli.NewMockUi()
cmd := New(ui)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-id=" + token.AccessorID,
"-token=root",
}
code := cmd.Run(args)
req.Equal(code, 0)
req.Empty(ui.ErrorWriter.String())
cloned := parseCloneOutput(t, ui.OutputWriter.String())
req.Equal("test", cloned.Description)
req.Len(cloned.Policies, 1)
apiToken, _, err := client.ACL().TokenRead(
cloned.AccessorID,
&api.QueryOptions{Token: "root"},
)
req.NoError(err)
req.NotNil(apiToken)
req.Equal(cloned.AccessorID, apiToken.AccessorID)
req.Equal(cloned.SecretID, apiToken.SecretID)
req.Equal(cloned.Description, apiToken.Description)
req.Equal(cloned.Local, apiToken.Local)
req.Equal(cloned.Policies, apiToken.Policies)
})
}