diff --git a/ci/integration/integration_test.go b/ci/integration/integration_test.go index 940bcbf1..8727d3ec 100644 --- a/ci/integration/integration_test.go +++ b/ci/integration/integration_test.go @@ -61,6 +61,22 @@ func TestCoderCLI(t *testing.T) { tcli.Success(), ) + c.Run(ctx, "coder envs ls -o json").Assert(t, + tcli.Success(), + ) + + c.Run(ctx, "coder tokens").Assert(t, + tcli.Success(), + ) + + c.Run(ctx, "coder tokens ls").Assert(t, + tcli.Success(), + ) + + c.Run(ctx, "coder tokens ls -o json").Assert(t, + tcli.Success(), + ) + c.Run(ctx, "coder urls").Assert(t, tcli.Success(), ) @@ -80,6 +96,10 @@ func TestCoderCLI(t *testing.T) { c.Run(ctx, "coder envs ls").Assert(t, tcli.Error(), ) + + c.Run(ctx, "coder tokens ls").Assert(t, + tcli.Error(), + ) }) } diff --git a/docs/coder.md b/docs/coder.md index d83ee5eb..2ac30553 100644 --- a/docs/coder.md +++ b/docs/coder.md @@ -19,6 +19,7 @@ coder provides a CLI for working with an existing Coder Enterprise installation * [coder logout](coder_logout.md) - Remove local authentication credentials if any exist * [coder sh](coder_sh.md) - Open a shell and execute commands in a Coder environment * [coder sync](coder_sync.md) - Establish a one way directory sync to a Coder environment +* [coder tokens](coder_tokens.md) - manage Coder API tokens for the active user * [coder urls](coder_urls.md) - Interact with environment DevURLs * [coder users](coder_users.md) - Interact with Coder user accounts diff --git a/docs/coder_tokens.md b/docs/coder_tokens.md new file mode 100644 index 00000000..9f347277 --- /dev/null +++ b/docs/coder_tokens.md @@ -0,0 +1,29 @@ +## coder tokens + +manage Coder API tokens for the active user + +### Synopsis + +Create and manage API Tokens for authenticating the CLI. +Statically authenticate using the token value with the `CODER_TOKEN` and `CODER_URL` environment variables. + +### Options + +``` + -h, --help help for tokens +``` + +### Options inherited from parent commands + +``` + -v, --verbose show verbose output +``` + +### SEE ALSO + +* [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation +* [coder tokens create](coder_tokens_create.md) - create generates a new API token and prints it to stdout +* [coder tokens ls](coder_tokens_ls.md) - show the user's active API tokens +* [coder tokens regen](coder_tokens_regen.md) - regenerate an API token by its unique ID and print the new token to stdout +* [coder tokens rm](coder_tokens_rm.md) - remove an API token by its unique ID + diff --git a/docs/coder_tokens_create.md b/docs/coder_tokens_create.md new file mode 100644 index 00000000..a7a89f54 --- /dev/null +++ b/docs/coder_tokens_create.md @@ -0,0 +1,24 @@ +## coder tokens create + +create generates a new API token and prints it to stdout + +``` +coder tokens create [token_name] [flags] +``` + +### Options + +``` + -h, --help help for create +``` + +### Options inherited from parent commands + +``` + -v, --verbose show verbose output +``` + +### SEE ALSO + +* [coder tokens](coder_tokens.md) - manage Coder API tokens for the active user + diff --git a/docs/coder_tokens_ls.md b/docs/coder_tokens_ls.md new file mode 100644 index 00000000..6790700d --- /dev/null +++ b/docs/coder_tokens_ls.md @@ -0,0 +1,25 @@ +## coder tokens ls + +show the user's active API tokens + +``` +coder tokens ls [flags] +``` + +### Options + +``` + -h, --help help for ls + -o, --output string human | json (default "human") +``` + +### Options inherited from parent commands + +``` + -v, --verbose show verbose output +``` + +### SEE ALSO + +* [coder tokens](coder_tokens.md) - manage Coder API tokens for the active user + diff --git a/docs/coder_tokens_regen.md b/docs/coder_tokens_regen.md new file mode 100644 index 00000000..26832102 --- /dev/null +++ b/docs/coder_tokens_regen.md @@ -0,0 +1,24 @@ +## coder tokens regen + +regenerate an API token by its unique ID and print the new token to stdout + +``` +coder tokens regen [token_id] [flags] +``` + +### Options + +``` + -h, --help help for regen +``` + +### Options inherited from parent commands + +``` + -v, --verbose show verbose output +``` + +### SEE ALSO + +* [coder tokens](coder_tokens.md) - manage Coder API tokens for the active user + diff --git a/docs/coder_tokens_rm.md b/docs/coder_tokens_rm.md new file mode 100644 index 00000000..ca95ee0e --- /dev/null +++ b/docs/coder_tokens_rm.md @@ -0,0 +1,24 @@ +## coder tokens rm + +remove an API token by its unique ID + +``` +coder tokens rm [token_id] [flags] +``` + +### Options + +``` + -h, --help help for rm +``` + +### Options inherited from parent commands + +``` + -v, --verbose show verbose output +``` + +### SEE ALSO + +* [coder tokens](coder_tokens.md) - manage Coder API tokens for the active user + diff --git a/internal/cmd/tokens.go b/internal/cmd/tokens.go index b5f0c5d7..66d11230 100644 --- a/internal/cmd/tokens.go +++ b/internal/cmd/tokens.go @@ -1,9 +1,12 @@ package cmd import ( + "encoding/json" "fmt" + "os" "github.com/spf13/cobra" + "golang.org/x/xerrors" "cdr.dev/coder-cli/coder-sdk" "cdr.dev/coder-cli/internal/x/xcobra" @@ -12,9 +15,8 @@ import ( func tokensCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "tokens", - Hidden: true, - Short: "manage Coder API tokens for the active user", + Use: "tokens", + Short: "manage Coder API tokens for the active user", Long: "Create and manage API Tokens for authenticating the CLI.\n" + "Statically authenticate using the token value with the " + "`" + "CODER_TOKEN" + "`" + " and " + "`" + "CODER_URL" + "`" + " environment variables.", } @@ -28,7 +30,9 @@ func tokensCmd() *cobra.Command { } func lsTokensCmd() *cobra.Command { - return &cobra.Command{ + var outputFmt string + + cmd := &cobra.Command{ Use: "ls", Short: "show the user's active API tokens", RunE: func(cmd *cobra.Command, args []string) error { @@ -43,14 +47,30 @@ func lsTokensCmd() *cobra.Command { return err } - err = tablewriter.WriteTable(len(tokens), func(i int) interface{} { return tokens[i] }) - if err != nil { - return err + switch outputFmt { + case humanOutput: + err := tablewriter.WriteTable(len(tokens), func(i int) interface{} { + return tokens[i] + }) + if err != nil { + return xerrors.Errorf("write table: %w", err) + } + case jsonOutput: + err := json.NewEncoder(os.Stdout).Encode(tokens) + if err != nil { + return xerrors.Errorf("write tokens as JSON: %w", err) + } + default: + return xerrors.Errorf("unknown --output value %q", outputFmt) } return nil }, } + + cmd.Flags().StringVarP(&outputFmt, "output", "o", humanOutput, "human | json") + + return cmd } func createTokensCmd() *cobra.Command {