Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

acl: add DisplayName field to auth methods #7769

Merged
merged 3 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions agent/consul/acl_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3336,6 +3336,7 @@ func TestACLEndpoint_AuthMethodSet(t *testing.T) {

t.Run("Update - allow type to default", func(t *testing.T) {
reqMethod := newAuthMethod("test")
reqMethod.DisplayName = "updated display name 1"
reqMethod.Description = "test modified 1"
reqMethod.Type = "" // unset

Expand All @@ -3355,12 +3356,14 @@ func TestACLEndpoint_AuthMethodSet(t *testing.T) {
method := methodResp.AuthMethod

require.Equal(t, method.Name, "test")
require.Equal(t, method.DisplayName, "updated display name 1")
require.Equal(t, method.Description, "test modified 1")
require.Equal(t, method.Type, "testing")
})

t.Run("Update - specify type", func(t *testing.T) {
reqMethod := newAuthMethod("test")
reqMethod.DisplayName = "updated display name 2"
reqMethod.Description = "test modified 2"

req := structs.ACLAuthMethodSetRequest{
Expand All @@ -3379,6 +3382,7 @@ func TestACLEndpoint_AuthMethodSet(t *testing.T) {
method := methodResp.AuthMethod

require.Equal(t, method.Name, "test")
require.Equal(t, method.DisplayName, "updated display name 2")
require.Equal(t, method.Description, "test modified 2")
require.Equal(t, method.Type, "testing")
})
Expand Down
13 changes: 10 additions & 3 deletions agent/structs/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,8 +994,9 @@ func (rules ACLBindingRules) Sort() {

type ACLAuthMethodListStub struct {
Name string
Description string
Type string
DisplayName string `json:",omitempty"`
Description string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64
EnterpriseMeta
Expand All @@ -1004,8 +1005,9 @@ type ACLAuthMethodListStub struct {
func (p *ACLAuthMethod) Stub() *ACLAuthMethodListStub {
return &ACLAuthMethodListStub{
Name: p.Name,
Description: p.Description,
Type: p.Type,
DisplayName: p.DisplayName,
Description: p.Description,
CreateIndex: p.CreateIndex,
ModifyIndex: p.ModifyIndex,
EnterpriseMeta: p.EnterpriseMeta,
Expand Down Expand Up @@ -1038,8 +1040,13 @@ type ACLAuthMethod struct {
// Immutable once set and only settable during create.
Type string

// DisplayName is an optional name to use instead of the Name field when
// displaying information about this auth method in any kind of user
// interface.
DisplayName string `json:",omitempty"`

// Description is just an optional bunch of explanatory text.
Description string
Description string `json:",omitempty"`

// Configuration is arbitrary configuration for the auth method. This
// should only contain primitive values and containers (such as lists and
Expand Down
8 changes: 6 additions & 2 deletions api/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type ACLToken struct {
Roles []*ACLTokenRoleLink `json:",omitempty"`
ServiceIdentities []*ACLServiceIdentity `json:",omitempty"`
Local bool
AuthMethod string `json:",omitempty"`
ExpirationTTL time.Duration `json:",omitempty"`
ExpirationTime *time.Time `json:",omitempty"`
CreateTime time.Time `json:",omitempty"`
Expand All @@ -60,6 +61,7 @@ type ACLTokenListEntry struct {
Roles []*ACLTokenRoleLink `json:",omitempty"`
ServiceIdentities []*ACLServiceIdentity `json:",omitempty"`
Local bool
AuthMethod string `json:",omitempty"`
ExpirationTime *time.Time `json:",omitempty"`
CreateTime time.Time
Hash []byte
Expand Down Expand Up @@ -180,7 +182,8 @@ type ACLBindingRule struct {
type ACLAuthMethod struct {
Name string
Type string
Description string
DisplayName string `json:",omitempty"`
Description string `json:",omitempty"`

// Configuration is arbitrary configuration for the auth method. This
// should only contain primitive values and containers (such as lists and
Expand All @@ -198,7 +201,8 @@ type ACLAuthMethod struct {
type ACLAuthMethodListEntry struct {
Name string
Type string
Description string
DisplayName string `json:",omitempty"`
Description string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64

Expand Down
8 changes: 8 additions & 0 deletions command/acl/authmethod/create/authmethod_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type cmd struct {

authMethodType string
name string
displayName string
description string

k8sHost string
Expand Down Expand Up @@ -62,6 +63,12 @@ func (c *cmd) init() {
"",
"The new auth method's name. This flag is required.",
)
c.flags.StringVar(
&c.displayName,
"display-name",
"",
"An optional name to use instead of the name when displaying this auth method in a UI.",
)
c.flags.StringVar(
&c.description,
"description",
Expand Down Expand Up @@ -130,6 +137,7 @@ func (c *cmd) Run(args []string) int {
newAuthMethod := &api.ACLAuthMethod{
Type: c.authMethodType,
Name: c.name,
DisplayName: c.displayName,
Description: c.description,
}

Expand Down
95 changes: 87 additions & 8 deletions command/acl/authmethod/create/authmethod_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import (

"github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/command/acl"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/go-uuid"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

// activate testing auth method
Expand Down Expand Up @@ -46,6 +47,7 @@ func TestAuthMethodCreateCommand(t *testing.T) {

defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
client := a.Client()

t.Run("type required", func(t *testing.T) {
args := []string{
Expand Down Expand Up @@ -98,6 +100,8 @@ func TestAuthMethodCreateCommand(t *testing.T) {
"-token=root",
"-type=testing",
"-name=test",
"-description=desc",
"-display-name=display",
}

ui := cli.NewMockUi()
Expand All @@ -106,6 +110,15 @@ func TestAuthMethodCreateCommand(t *testing.T) {
code := cmd.Run(args)
require.Equal(t, code, 0)
require.Empty(t, ui.ErrorWriter.String())

got := getTestMethod(t, client, "test")
expect := &api.ACLAuthMethod{
Name: "test",
Type: "testing",
DisplayName: "display",
Description: "desc",
}
require.Equal(t, expect, got)
})
}

Expand All @@ -126,6 +139,7 @@ func TestAuthMethodCreateCommand_JSON(t *testing.T) {

defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
client := a.Client()

t.Run("type required", func(t *testing.T) {
args := []string{
Expand All @@ -148,6 +162,8 @@ func TestAuthMethodCreateCommand_JSON(t *testing.T) {
"-token=root",
"-type=testing",
"-name=test",
"-description=desc",
"-display-name=display",
"-format=json",
}

Expand All @@ -162,8 +178,16 @@ func TestAuthMethodCreateCommand_JSON(t *testing.T) {
require.Contains(t, out, "test")

var jsonOutput json.RawMessage
err := json.Unmarshal([]byte(out), &jsonOutput)
assert.NoError(t, err)
require.NoError(t, json.Unmarshal([]byte(out), &jsonOutput))

got := getTestMethod(t, client, "test")
expect := &api.ACLAuthMethod{
Name: "test",
Type: "testing",
DisplayName: "display",
Description: "desc",
}
require.Equal(t, expect, got)
})
}

Expand All @@ -184,13 +208,15 @@ func TestAuthMethodCreateCommand_k8s(t *testing.T) {

defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
client := a.Client()

t.Run("k8s host required", func(t *testing.T) {
name := getTestName(t)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
"-type=kubernetes",
"-name=k8s",
"-name", name,
}

ui := cli.NewMockUi()
Expand All @@ -202,11 +228,12 @@ func TestAuthMethodCreateCommand_k8s(t *testing.T) {
})

t.Run("k8s ca cert required", func(t *testing.T) {
name := getTestName(t)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
"-type=kubernetes",
"-name=k8s",
"-name", name,
"-kubernetes-host=https://foo.internal:8443",
}

Expand All @@ -221,11 +248,12 @@ func TestAuthMethodCreateCommand_k8s(t *testing.T) {
ca := connect.TestCA(t, nil)

t.Run("k8s jwt required", func(t *testing.T) {
name := getTestName(t)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
"-type=kubernetes",
"-name=k8s",
"-name", name,
"-kubernetes-host=https://foo.internal:8443",
"-kubernetes-ca-cert", ca.RootCert,
}
Expand All @@ -239,11 +267,12 @@ func TestAuthMethodCreateCommand_k8s(t *testing.T) {
})

t.Run("create k8s", func(t *testing.T) {
name := getTestName(t)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
"-type=kubernetes",
"-name=k8s",
"-name", name,
"-kubernetes-host", "https://foo.internal:8443",
"-kubernetes-ca-cert", ca.RootCert,
"-kubernetes-service-account-jwt", acl.TestKubernetesJWT_A,
Expand All @@ -255,17 +284,30 @@ func TestAuthMethodCreateCommand_k8s(t *testing.T) {
code := cmd.Run(args)
require.Equal(t, code, 0)
require.Empty(t, ui.ErrorWriter.String())

got := getTestMethod(t, client, name)
expect := &api.ACLAuthMethod{
Name: name,
Type: "kubernetes",
Config: map[string]interface{}{
"Host": "https://foo.internal:8443",
"CACert": ca.RootCert,
"ServiceAccountJWT": acl.TestKubernetesJWT_A,
},
}
require.Equal(t, expect, got)
})

caFile := filepath.Join(testDir, "ca.crt")
require.NoError(t, ioutil.WriteFile(caFile, []byte(ca.RootCert), 0600))

t.Run("create k8s with cert file", func(t *testing.T) {
name := getTestName(t)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
"-type=kubernetes",
"-name=k8s",
"-name", name,
"-kubernetes-host", "https://foo.internal:8443",
"-kubernetes-ca-cert", "@" + caFile,
"-kubernetes-service-account-jwt", acl.TestKubernetesJWT_A,
Expand All @@ -277,5 +319,42 @@ func TestAuthMethodCreateCommand_k8s(t *testing.T) {
code := cmd.Run(args)
require.Equal(t, code, 0)
require.Empty(t, ui.ErrorWriter.String())

got := getTestMethod(t, client, name)
expect := &api.ACLAuthMethod{
Name: name,
Type: "kubernetes",
Config: map[string]interface{}{
"Host": "https://foo.internal:8443",
"CACert": ca.RootCert,
"ServiceAccountJWT": acl.TestKubernetesJWT_A,
},
}
require.Equal(t, expect, got)
})
}

func getTestMethod(t *testing.T, client *api.Client, methodName string) *api.ACLAuthMethod {
t.Helper()

method, _, err := client.ACL().AuthMethodRead(
methodName,
&api.QueryOptions{Token: "root"},
)
require.NoError(t, err)
require.NotNil(t, method)

// zero these out since we don't really care
method.CreateIndex = 0
method.ModifyIndex = 0

return method
}

func getTestName(t *testing.T) string {
t.Helper()

id, err := uuid.GenerateUUID()
require.NoError(t, err)
return "test-" + id
}
6 changes: 6 additions & 0 deletions command/acl/authmethod/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ func (f *prettyFormatter) FormatAuthMethod(method *api.ACLAuthMethod) (string, e
if method.Namespace != "" {
buffer.WriteString(fmt.Sprintf("Namespace: %s\n", method.Namespace))
}
if method.DisplayName != "" {
buffer.WriteString(fmt.Sprintf("DisplayName: %s\n", method.DisplayName))
}
buffer.WriteString(fmt.Sprintf("Description: %s\n", method.Description))
if f.showMeta {
buffer.WriteString(fmt.Sprintf("Create Index: %d\n", method.CreateIndex))
Expand Down Expand Up @@ -87,6 +90,9 @@ func (f *prettyFormatter) formatAuthMethodListEntry(method *api.ACLAuthMethodLis
if method.Namespace != "" {
buffer.WriteString(fmt.Sprintf(" Namespace: %s\n", method.Namespace))
}
if method.DisplayName != "" {
buffer.WriteString(fmt.Sprintf(" DisplayName: %s\n", method.DisplayName))
}
buffer.WriteString(fmt.Sprintf(" Description: %s\n", method.Description))
if f.showMeta {
buffer.WriteString(fmt.Sprintf(" Create Index: %d\n", method.CreateIndex))
Expand Down
Loading