Skip to content

Commit bcc5af0

Browse files
improve CLI help text for all datumctl commands
- Replace kubectl-centric Short/Long/Example text on all wrapped commands - Add Long and Example to all auth, mcp, and docs subcommands - Override activity command (external package) in root.go - Scope kubectl integration commands (whoami, can-i, get-token, update-kubeconfig) as advanced/kubectl-only - Hide irrelevant kubectl flags on create command - Fix templates.LongDesc vs templates.Examples in generate-cli-docs - Add cli-help-improvement-plan.md design doc Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2b5586c commit bcc5af0

File tree

14 files changed

+1915
-59
lines changed

14 files changed

+1915
-59
lines changed

docs/cli-help-improvement-plan.md

Lines changed: 1259 additions & 0 deletions
Large diffs are not rendered by default.

internal/cmd/auth/auth.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,19 @@ import (
99
func Command() *cobra.Command {
1010
cmd := &cobra.Command{
1111
Use: "auth",
12-
Short: "Authenticate with Datum Cloud",
12+
Short: "Manage Datum Cloud authentication credentials",
13+
Long: `The auth group provides commands to log in to Datum Cloud, manage multiple
14+
user sessions, and retrieve tokens for scripting.
15+
16+
Typical workflow:
17+
1. Log in: datumctl auth login
18+
2. Verify sessions: datumctl auth list
19+
3. Switch accounts: datumctl auth switch <email>
20+
4. Log out: datumctl auth logout <email>
21+
22+
Advanced — kubectl integration:
23+
If you use kubectl and want to point it at a Datum Cloud control plane,
24+
see 'datumctl auth update-kubeconfig --help'.`,
1325
}
1426

1527
cmd.AddCommand(

internal/cmd/auth/get_token.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,33 @@ const (
2222
// getTokenCmd retrieves tokens based on the --output flag.
2323
var getTokenCmd = &cobra.Command{
2424
Use: "get-token",
25-
Short: "Retrieve access token for active user (raw or K8s format)",
26-
Long: `Retrieves credentials for the currently active datumctl user.
25+
Short: "Print the active user's access token (advanced / kubectl integration)",
26+
Long: `Print the current access token for the active Datum Cloud user.
2727
28-
Default behavior (--output=token) prints the raw access token to stdout.
29-
With --output=client.authentication.k8s.io/v1, prints a K8s ExecCredential JSON object
30-
suitable for use as a kubectl credential plugin.`, // Updated description
28+
Most datumctl users do not need this command — datumctl handles
29+
authentication automatically for all its own commands.
30+
31+
This command exists for two advanced use cases:
32+
33+
1. kubectl credential plugin: invoked automatically by kubectl after you
34+
run 'datumctl auth update-kubeconfig'. You do not need to call it
35+
directly in that case.
36+
37+
2. Scripting or direct API calls: use --output=token to get a raw bearer
38+
token to pass to curl or other HTTP clients.
39+
40+
If the stored token is expired, datumctl automatically uses the stored
41+
refresh token to obtain a new one before printing.
42+
43+
Output formats (--output / -o):
44+
token Print the raw access token (default).
45+
client.authentication.k8s.io/v1 Print a Kubernetes ExecCredential JSON
46+
object for kubectl credential plugin use.`,
47+
Example: ` # Get a raw token for use in a script or direct API call
48+
datumctl auth get-token
49+
50+
# Get a Kubernetes ExecCredential JSON object (used by kubectl automatically)
51+
datumctl auth get-token --output=client.authentication.k8s.io/v1`,
3152
Args: cobra.NoArgs,
3253
RunE: runGetToken, // Use single function
3354
}

internal/cmd/auth/list.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ var listCmd = &cobra.Command{
1616
Use: "list",
1717
Short: "List locally authenticated users",
1818
Aliases: []string{"ls"},
19+
Long: `Display a table of all Datum Cloud users whose credentials are stored
20+
locally in the system keyring, along with their status.
21+
22+
Columns:
23+
Name The display name from the user's Datum Cloud account.
24+
Email The email address used to log in. Pass this to 'datumctl auth switch'
25+
or 'datumctl auth logout' to act on a specific account.
26+
Status "Active" marks the account whose credentials are used by default
27+
for all subsequent datumctl commands.`,
28+
Example: ` # Show all logged-in users
29+
datumctl auth list
30+
31+
# Alias
32+
datumctl auth ls`,
1933
RunE: func(cmd *cobra.Command, args []string) error {
2034
return runList()
2135
},

internal/cmd/auth/login.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,35 @@ var (
4040

4141
var LoginCmd = &cobra.Command{
4242
Use: "login",
43-
Short: "Authenticate with Datum Cloud via OAuth2 PKCE flow",
43+
Short: "Log in to Datum Cloud",
44+
Long: `Authenticate with Datum Cloud using a secure browser-based login flow.
45+
46+
Running this command will:
47+
1. Open your default web browser to the Datum Cloud authentication page.
48+
If the browser cannot open automatically, a URL is printed for manual use.
49+
2. Complete authentication in the browser (username/password or SSO).
50+
3. Return to datumctl, which stores your credentials (including a refresh
51+
token) securely in the system keyring.
52+
53+
After login, credentials are associated with your email address and
54+
automatically refreshed when they expire. Use 'datumctl auth list' to see
55+
all stored sessions.
56+
57+
By default, logs into auth.datum.net (the production Datum Cloud environment).
58+
Use --hostname to target a different environment (e.g., staging).
59+
Use --api-hostname to explicitly specify the API server hostname when it
60+
cannot be derived from the auth hostname (e.g., in self-hosted environments).`,
61+
Example: ` # Log in to Datum Cloud (opens browser)
62+
datumctl auth login
63+
64+
# Log in to a staging environment
65+
datumctl auth login --hostname auth.staging.env.datum.net
66+
67+
# Log in to a self-hosted environment with an explicit client ID
68+
datumctl auth login --hostname auth.example.com --client-id 123456789
69+
70+
# Log in to a self-hosted environment with explicit API hostname
71+
datumctl auth login --hostname auth.example.com --api-hostname api.example.com --client-id 123456789`,
4472
RunE: func(cmd *cobra.Command, args []string) error {
4573
var actualClientID string
4674
if clientIDFlag != "" {

internal/cmd/auth/logout.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,30 @@ var logoutAll bool // Flag variable for --all
1414

1515
// logoutCmd removes local authentication credentials for a specified user or all users.
1616
var logoutCmd = &cobra.Command{
17-
Use: "logout [user]",
18-
Short: "Remove local authentication credentials for a specified user or all users",
19-
Long: `Remove local authentication credentials.
20-
21-
Specify a user in the format 'email@hostname' to log out only that user.
22-
Use 'datumctl auth list' to see available users.
23-
Use the --all flag to log out all known users.`, // Updated Long description
17+
Use: "logout <email>",
18+
Short: "Remove stored credentials for a user or all users",
19+
Long: `Remove locally stored Datum Cloud credentials from the system keyring.
20+
21+
Provide the email address of the user to log out (as shown by
22+
'datumctl auth list'). Use --all to remove credentials for every
23+
logged-in user at once.
24+
25+
If you log out the currently active user, the active session is cleared.
26+
You will need to run 'datumctl auth login' again before running commands
27+
that require authentication.`,
28+
Example: ` # Log out a specific user
29+
datumctl auth logout user@example.com
30+
31+
# Log out all authenticated users
32+
datumctl auth logout --all`,
2433
Args: func(cmd *cobra.Command, args []string) error {
2534
// Custom args validation
2635
all, _ := cmd.Flags().GetBool("all")
2736
if all && len(args) > 0 {
2837
return errors.New("cannot specify a user argument when using the --all flag")
2938
}
3039
if !all && len(args) != 1 {
31-
return errors.New("must specify exactly one user (email@hostname) or use the --all flag")
40+
return errors.New("must specify exactly one user email or use the --all flag")
3241
}
3342
return nil
3443
},

internal/cmd/auth/switch.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,19 @@ import (
1212

1313
var switchCmd = &cobra.Command{
1414
Use: "switch <user-email>",
15-
Short: "Set the active authenticated user session",
16-
Long: `Switches the active user context to the specified user email.
15+
Short: "Switch the active Datum Cloud user session",
16+
Long: `Change which locally stored user account is treated as active.
1717
18-
The user email must correspond to an existing set of credentials previously
19-
established via 'datumctl auth login'. Use 'datumctl auth list' to see available users.`,
18+
The active user's credentials are used for all datumctl commands that
19+
require authentication.
20+
21+
The email address must match an account shown by 'datumctl auth list'.
22+
To add a new account, run 'datumctl auth login' first.`,
23+
Example: ` # See which accounts are available
24+
datumctl auth list
25+
26+
# Switch to a different account
27+
datumctl auth switch user@example.com`,
2028
Args: cobra.ExactArgs(1), // Requires exactly one argument: the user email
2129
RunE: func(cmd *cobra.Command, args []string) error {
2230
targetUserKey := args[0]

internal/cmd/auth/update-kubeconfig.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,37 @@ func updateKubeconfigCmd() *cobra.Command {
1717

1818
cmd := &cobra.Command{
1919
Use: "update-kubeconfig",
20-
Short: "Update the kubeconfig file",
20+
Short: "Configure kubectl to access a Datum Cloud control plane (kubectl users only)",
21+
Long: `For kubectl users only. datumctl users do not need this command —
22+
manage your resources directly with 'datumctl get', 'datumctl apply', etc.
23+
24+
This command adds or updates a cluster, user, and context entry in your
25+
kubeconfig file so that kubectl can authenticate to a Datum Cloud control
26+
plane using your active datumctl session.
27+
28+
After running this command, kubectl will automatically call
29+
'datumctl auth get-token' to obtain a fresh credential on each request.
30+
31+
You must specify exactly one of --organization or --project:
32+
33+
--organization <id> Configure kubectl access to an organization's
34+
control plane.
35+
--project <id> Configure kubectl access to a specific project's
36+
control plane.
37+
38+
The kubeconfig is updated at $HOME/.kube/config by default, or the path
39+
set by the KUBECONFIG environment variable. Use --kubeconfig to override.
40+
41+
Use --hostname to override the API server hostname (useful for self-hosted
42+
environments where the hostname cannot be derived from stored credentials).`,
43+
Example: ` # Configure kubectl for an organization's control plane
44+
datumctl auth update-kubeconfig --organization my-org-id
45+
46+
# Configure kubectl for a specific project's control plane
47+
datumctl auth update-kubeconfig --project my-project-id
48+
49+
# Write to a custom kubeconfig file
50+
datumctl auth update-kubeconfig --organization my-org-id --kubeconfig ~/.kube/datum-config`,
2151
RunE: func(cmd *cobra.Command, args []string) error {
2252
// Determine kubeconfig path
2353
var kubeconfigPath string

internal/cmd/create/create.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,23 @@ func NewCmdCreate(f util.Factory, ioStreams genericiooptions.IOStreams) *cobra.C
1414
for _, subCmd := range cmd.Commands() {
1515
cmd.RemoveCommand(subCmd)
1616
}
17+
cmd.Short = "Create a Datum Cloud resource from a file or stdin"
18+
cmd.Long = `Create a new Datum Cloud resource by providing a manifest in YAML or JSON
19+
format, either from a file or piped through stdin.
20+
21+
datumctl create accepts Datum Cloud resource manifests — not Kubernetes
22+
built-in resources. Use 'datumctl apply' for idempotent creation or updates.
23+
24+
Resource manifests must specify the correct apiVersion and kind for the
25+
Datum Cloud resource type. Use 'datumctl explain <type>' to see the schema
26+
for a resource type and 'datumctl api-resources' to list available types.`
27+
cmd.Example = ` # Create a project from a manifest file
28+
datumctl create -f ./project.yaml --organization <org-id>
29+
30+
# Create a resource from stdin
31+
cat dnszone.yaml | datumctl create -f - --project <project-id>
32+
33+
# Validate the resource without creating it
34+
datumctl create -f ./project.yaml --organization <org-id> --dry-run=server`
1735
return cmd
1836
}

internal/cmd/docs/docs.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@ import "github.com/spf13/cobra"
66
func Command(root *cobra.Command) *cobra.Command {
77
cmd := &cobra.Command{
88
Use: "docs",
9-
Short: "Documentation and API exploration commands",
10-
Long: `Commands for exploring and browsing API documentation.`,
9+
Short: "Explore API documentation and generate CLI reference docs",
10+
Long: `The docs group provides tools for discovering and exploring the Datum Cloud
11+
API, as well as generating offline documentation for datumctl itself.
12+
13+
Subcommands:
14+
openapi Launch a local Swagger UI to browse OpenAPI specs
15+
for any API group available in the current context.
16+
generate-cli-docs Generate markdown documentation files for all
17+
datumctl commands (used to build the published
18+
CLI reference at datum.net/docs).`,
1119
}
1220
cmd.AddCommand(OpenAPICmd())
1321

0 commit comments

Comments
 (0)