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

cli: add acl token list command, documentation #5557

Merged
merged 1 commit into from
Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
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
117 changes: 117 additions & 0 deletions command/acl_token_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package command

import (
"fmt"
"strings"

"github.com/hashicorp/nomad/api"
"github.com/posener/complete"
)

type ACLTokenListCommand struct {
Meta
}

func (c *ACLTokenListCommand) Help() string {
helpText := `
Usage: nomad acl token list

List is used to list existing ACL tokens.

General Options:

` + generalOptionsUsage() + `

List Options:

-json
Output the ACL tokens in a JSON format.

-t
Format and display the ACL tokens using a Go template.
`

return strings.TrimSpace(helpText)
}

func (c *ACLTokenListCommand) AutocompleteFlags() complete.Flags {
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
complete.Flags{
"-json": complete.PredictNothing,
"-t": complete.PredictAnything,
})
}

func (c *ACLTokenListCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}

func (c *ACLTokenListCommand) Synopsis() string {
return "List ACL tokens"
}

func (c *ACLTokenListCommand) Name() string { return "acl token list" }

func (c *ACLTokenListCommand) Run(args []string) int {
var json bool
var tmpl string

flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&json, "json", false, "")
flags.StringVar(&tmpl, "t", "", "")

if err := flags.Parse(args); err != nil {
return 1
}

// Check that we got no arguments
args = flags.Args()
if l := len(args); l != 0 {
c.Ui.Error("This command takes no arguments")
c.Ui.Error(commandErrorText(c))
return 1
}

// Get the HTTP client
client, err := c.Meta.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
return 1
}

// Fetch info on the policy
tokens, _, err := client.ACLTokens().List(nil)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error listing ACL tokens: %s", err))
return 1
}

if json || len(tmpl) > 0 {
out, err := Format(json, tmpl, tokens)
if err != nil {
c.Ui.Error(err.Error())
return 1
}

c.Ui.Output(out)
return 0
}

c.Ui.Output(formatTokens(tokens))
return 0
}

func formatTokens(tokens []*api.ACLTokenListStub) string {
if len(tokens) == 0 {
return "No tokens found"
}

output := make([]string, 0, len(tokens)+1)
output = append(output, fmt.Sprintf("Name|Type|Global|Accessor ID"))
for _, p := range tokens {
output = append(output, fmt.Sprintf("%s|%s|%t|%s", p.Name, p.Type, p.Global, p.AccessorID))
}

return formatList(output)
}
63 changes: 63 additions & 0 deletions command/acl_token_list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package command

import (
"strings"
"testing"

"github.com/hashicorp/nomad/acl"
"github.com/hashicorp/nomad/command/agent"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/assert"
)

func TestACLTokenListCommand(t *testing.T) {
assert := assert.New(t)
t.Parallel()
config := func(c *agent.Config) {
c.ACL.Enabled = true
}

srv, _, url := testServer(t, true, config)
state := srv.Agent.Server().State()
defer srv.Shutdown()

// Bootstrap an initial ACL token
token := srv.RootToken
assert.NotNil(token, "failed to bootstrap ACL token")

// Create a valid token
mockToken := mock.ACLToken()
mockToken.Policies = []string{acl.PolicyWrite}
mockToken.SetHash()
assert.Nil(state.UpsertACLTokens(1000, []*structs.ACLToken{mockToken}))

ui := new(cli.MockUi)
cmd := &ACLTokenListCommand{Meta: Meta{Ui: ui, flagAddress: url}}

// Attempt to list tokens without a valid management token
invalidToken := mock.ACLToken()
code := cmd.Run([]string{"-address=" + url, "-token=" + invalidToken.SecretID})
assert.Equal(1, code)

// Apply a token with a valid management token
code = cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID})
assert.Equal(0, code)

// Check the output
out := ui.OutputWriter.String()
if !strings.Contains(out, mockToken.Name) {
t.Fatalf("bad: %v", out)
}

// List json
if code := cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID, "-json"}); code != 0 {
t.Fatalf("expected exit 0, got: %d; %v", code, ui.ErrorWriter.String())
}
out = ui.OutputWriter.String()
if !strings.Contains(out, "CreateIndex") {
t.Fatalf("expected json output, got: %s", out)
}
ui.OutputWriter.Reset()
}
5 changes: 5 additions & 0 deletions command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
Meta: meta,
}, nil
},
"acl token list": func() (cli.Command, error) {
return &ACLTokenListCommand{
Meta: meta,
}, nil
},
"acl token self": func() (cli.Command, error) {
return &ACLTokenSelfCommand{
Meta: meta,
Expand Down
12 changes: 6 additions & 6 deletions website/source/docs/commands/acl/policy-list.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: >
The policy list command is used to list available ACL policies.
---

# Command: acl policy info
# Command: acl policy list

The `acl policy list` command is used to list available ACL policies.

Expand All @@ -22,17 +22,17 @@ nomad acl policy list
#
## List Options

* `-json` : Output the namespaces in their JSON format.
* `-json` : Output the policies in their JSON format.

* `-t` : Format and display the namespaces using a Go template.
* `-t` : Format and display the policies using a Go template.

## Examples

List all ACL policies:

```
$ nomad acl policy list
Name Description
default-ns Write access to the default namespace
node-read Node read access
Name Description
policy-1 The first policy
policy-2 The second policy
```
38 changes: 38 additions & 0 deletions website/source/docs/commands/acl/token-list.html.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
layout: "docs"
page_title: "Commands: acl token list"
sidebar_current: "docs-commands-acl-token-list"
description: >
The token list command is used to list existing ACL tokens.
---

# Command: acl token list

The `acl token list` command is used to list existing ACL tokens.

## Usage

```
nomad acl token list
```

## General Options

<%= partial "docs/commands/_general_options" %>
#
## List Options

* `-json` : Output the tokens in their JSON format.

* `-t` : Format and display the tokens using a Go template.

## Examples

List all ACL tokens:

```
$ nomad acl token list
Name Type Global Accessor ID
Bootstrap Token management true 32b61154-47f1-3694-1430-a5544bafcd3e
<none> client false fcf2bf84-a257-8f39-9d16-a954ed25b5be
```
2 changes: 1 addition & 1 deletion website/source/docs/commands/acl/token-self.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Fetch information about an existing ACL token:
```
$ export NOMAD_TOKEN=d532c40a-30f1-695c-19e5-c35b882b0efd

$ nomad acl tokenjself
$ nomad acl token self
Accessor ID = d532c40a-30f1-695c-19e5-c35b882b0efd
Secret ID = 85310d07-9afa-ef53-0933-0c043cd673c7
Name = my token
Expand Down
3 changes: 3 additions & 0 deletions website/source/layouts/docs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
<li<%= sidebar_current("docs-commands-acl-token-info") %>>
<a href="/docs/commands/acl/token-info.html">token info</a>
</li>
<li<%= sidebar_current("docs-commands-acl-token-list") %>>
<a href="/docs/commands/acl/token-list.html">token list</a>
</li>
<li<%= sidebar_current("docs-commands-acl-token-self") %>>
<a href="/docs/commands/acl/token-self.html">token self</a>
</li>
Expand Down