Add `-json` and `-t` flag for `nomad acl token create` command (#16055)

Signed-off-by: dttung2905 <ttdao.2015@accountancy.smu.edu.sg>
This commit is contained in:
Dao Thanh Tung 2023-02-07 19:05:41 +08:00 committed by GitHub
parent 45cf63d88f
commit ae720fe28d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 2 deletions

3
.changelog/16055.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
cli: Add `-json` and `-t` flag to `nomad acl token create` command
```

View File

@ -53,6 +53,12 @@ Create Options:
Specifies the time-to-live of the created ACL token. This takes the form of Specifies the time-to-live of the created ACL token. This takes the form of
a time duration such as "5m" and "1h". By default, tokens will be created a time duration such as "5m" and "1h". By default, tokens will be created
without a TTL and therefore never expire. without a TTL and therefore never expire.
-json
Output the ACL token information in JSON format.
-t
Format and display the ACL token information using a Go template.
` `
return strings.TrimSpace(helpText) return strings.TrimSpace(helpText)
} }
@ -67,6 +73,8 @@ func (c *ACLTokenCreateCommand) AutocompleteFlags() complete.Flags {
"role-id": complete.PredictAnything, "role-id": complete.PredictAnything,
"role-name": complete.PredictAnything, "role-name": complete.PredictAnything,
"ttl": complete.PredictAnything, "ttl": complete.PredictAnything,
"-json": complete.PredictNothing,
"-t": complete.PredictAnything,
}) })
} }
@ -81,8 +89,8 @@ func (c *ACLTokenCreateCommand) Synopsis() string {
func (c *ACLTokenCreateCommand) Name() string { return "acl token create" } func (c *ACLTokenCreateCommand) Name() string { return "acl token create" }
func (c *ACLTokenCreateCommand) Run(args []string) int { func (c *ACLTokenCreateCommand) Run(args []string) int {
var name, tokenType, ttl string var name, tokenType, ttl, tmpl string
var global bool var global, json bool
var policies []string var policies []string
flags := c.Meta.FlagSet(c.Name(), FlagSetClient) flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) } flags.Usage = func() { c.Ui.Output(c.Help()) }
@ -90,6 +98,8 @@ func (c *ACLTokenCreateCommand) Run(args []string) int {
flags.StringVar(&tokenType, "type", "client", "") flags.StringVar(&tokenType, "type", "client", "")
flags.BoolVar(&global, "global", false, "") flags.BoolVar(&global, "global", false, "")
flags.StringVar(&ttl, "ttl", "", "") flags.StringVar(&ttl, "ttl", "", "")
flags.BoolVar(&json, "json", false, "")
flags.StringVar(&tmpl, "t", "", "")
flags.Var((funcVar)(func(s string) error { flags.Var((funcVar)(func(s string) error {
policies = append(policies, s) policies = append(policies, s)
return nil return nil
@ -148,6 +158,16 @@ func (c *ACLTokenCreateCommand) Run(args []string) int {
return 1 return 1
} }
if json || len(tmpl) > 0 {
out, err := Format(json, tmpl, token)
if err != nil {
c.Ui.Error(err.Error())
return 1
}
c.Ui.Output(out)
return 0
}
// Format the output // Format the output
outputACLToken(c.Ui, token) outputACLToken(c.Ui, token)
return 0 return 0

View File

@ -1,6 +1,7 @@
package command package command
import ( import (
"encoding/json"
"testing" "testing"
"github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/api"
@ -45,12 +46,50 @@ func TestACLTokenCreateCommand(t *testing.T) {
ui.OutputWriter.Reset() ui.OutputWriter.Reset()
ui.ErrorWriter.Reset() ui.ErrorWriter.Reset()
// Test with a no-expiry token and -json/-t flag
testCasesNoTTL := []string{"-json", "-t='{{ .Policies }}'"}
var jsonMap map[string]interface{}
for _, outputFormatFlag := range testCasesNoTTL {
code = cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID, "-policy=foo", "-type=client", outputFormatFlag})
require.Equal(t, 0, code)
// Check the output
out = ui.OutputWriter.String()
require.Contains(t, out, "foo")
if outputFormatFlag == "-json" {
err := json.Unmarshal([]byte(out), &jsonMap)
require.Nil(t, err, "Output not in JSON format")
}
ui.OutputWriter.Reset()
ui.ErrorWriter.Reset()
}
// Create a new token that has an expiry TTL set and check the response. // Create a new token that has an expiry TTL set and check the response.
code = cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID, "-type=management", "-ttl=10m"}) code = cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID, "-type=management", "-ttl=10m"})
require.Equal(t, 0, code) require.Equal(t, 0, code)
out = ui.OutputWriter.String() out = ui.OutputWriter.String()
require.NotContains(t, out, "Expiry Time = <none>") require.NotContains(t, out, "Expiry Time = <none>")
ui.OutputWriter.Reset()
ui.ErrorWriter.Reset()
// Test with a token that has expiry TTL set and -json/-t flag
testCasesWithTTL := [][]string{{"-json", "ExpirationTTL"}, {"-t='{{ .ExpirationTTL }}'", "10m0s"}}
for _, outputFormatFlag := range testCasesWithTTL {
code = cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID, "-type=management", "-ttl=10m", outputFormatFlag[0]})
require.Equal(t, 0, code)
// Check the output
out = ui.OutputWriter.String()
if outputFormatFlag[0] == "-json" {
err := json.Unmarshal([]byte(out), &jsonMap)
require.Nil(t, err, "Output not in JSON format")
}
require.Contains(t, out, outputFormatFlag[1])
ui.OutputWriter.Reset()
ui.ErrorWriter.Reset()
}
} }
func Test_generateACLTokenRoleLinks(t *testing.T) { func Test_generateACLTokenRoleLinks(t *testing.T) {

View File

@ -44,6 +44,10 @@ The `acl token create` command requires no arguments.
form of a time duration such as "5m" and "1h". By default, tokens will be form of a time duration such as "5m" and "1h". By default, tokens will be
created without a TTL and therefore never expire. created without a TTL and therefore never expire.
- `-json`:Output the ACL token information in JSON format.
- `-t`: Format and display the ACL token information using a Go template.
## Examples ## Examples
Create a new ACL token linked to an ACL Policy and Role: Create a new ACL token linked to an ACL Policy and Role: