mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-26 11:11:01 +00:00
cmd/tailscale: fix, test some recent doc inconsistencies
3dabea0fc2c added some docs with inconsistent usage docs. This fixes them, and adds a test. It also adds some other tests and fixes other verb tense inconsistencies. Updates tailscale/corp#25278 Change-Id: I94c2a8940791bddd7c35c1c3d5fb791a317370c2 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
f0db47338e
commit
61bea75092
@ -17,6 +17,7 @@ import (
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/health/healthmsg"
|
||||
"tailscale.com/ipn"
|
||||
@ -1525,3 +1526,45 @@ func TestHelpAlias(t *testing.T) {
|
||||
t.Fatalf("Run: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocs(t *testing.T) {
|
||||
root := newRootCmd()
|
||||
check := func(t *testing.T, c *ffcli.Command) {
|
||||
shortVerb, _, ok := strings.Cut(c.ShortHelp, " ")
|
||||
if !ok || shortVerb == "" {
|
||||
t.Errorf("couldn't find verb+space in ShortHelp")
|
||||
} else {
|
||||
if strings.HasSuffix(shortVerb, ".") {
|
||||
t.Errorf("ShortHelp shouldn't end in period; got %q", c.ShortHelp)
|
||||
}
|
||||
if b := shortVerb[0]; b >= 'a' && b <= 'z' {
|
||||
t.Errorf("ShortHelp should start with upper-case letter; got %q", c.ShortHelp)
|
||||
}
|
||||
if strings.HasSuffix(shortVerb, "s") && shortVerb != "Does" {
|
||||
t.Errorf("verb %q ending in 's' is unexpected, from %q", shortVerb, c.ShortHelp)
|
||||
}
|
||||
}
|
||||
|
||||
name := t.Name()
|
||||
wantPfx := strings.ReplaceAll(strings.TrimPrefix(name, "TestDocs/"), "/", " ")
|
||||
switch name {
|
||||
case "TestDocs/tailscale/completion/bash",
|
||||
"TestDocs/tailscale/completion/zsh":
|
||||
wantPfx = "" // special-case exceptions
|
||||
}
|
||||
if !strings.HasPrefix(c.ShortUsage, wantPfx) {
|
||||
t.Errorf("ShortUsage should start with %q; got %q", wantPfx, c.ShortUsage)
|
||||
}
|
||||
}
|
||||
|
||||
var walk func(t *testing.T, c *ffcli.Command)
|
||||
walk = func(t *testing.T, c *ffcli.Command) {
|
||||
t.Run(c.Name, func(t *testing.T) {
|
||||
check(t, c)
|
||||
for _, sub := range c.Subcommands {
|
||||
walk(t, sub)
|
||||
}
|
||||
})
|
||||
}
|
||||
walk(t, root)
|
||||
}
|
||||
|
@ -27,28 +27,28 @@ func sysExtCmd() *ffcli.Command {
|
||||
return &ffcli.Command{
|
||||
Name: "sysext",
|
||||
ShortUsage: "tailscale configure sysext [activate|deactivate|status]",
|
||||
ShortHelp: "Manages the system extension for macOS (Standalone variant)",
|
||||
ShortHelp: "Manage the system extension for macOS (Standalone variant)",
|
||||
LongHelp: "The sysext set of commands provides a way to activate, deactivate, or manage the state of the Tailscale system extension on macOS. " +
|
||||
"This is only relevant if you are running the Standalone variant of the Tailscale client for macOS. " +
|
||||
"To access more detailed information about system extensions installed on this Mac, run 'systemextensionsctl list'.",
|
||||
Subcommands: []*ffcli.Command{
|
||||
{
|
||||
Name: "activate",
|
||||
ShortUsage: "tailscale sysext activate",
|
||||
ShortUsage: "tailscale configure sysext activate",
|
||||
ShortHelp: "Register the Tailscale system extension with macOS.",
|
||||
LongHelp: "This command registers the Tailscale system extension with macOS. To run Tailscale, you'll also need to install the VPN configuration separately (run `tailscale configure vpn-config install`). After running this command, you need to approve the extension in System Settings > Login Items and Extensions > Network Extensions.",
|
||||
Exec: requiresStandalone,
|
||||
},
|
||||
{
|
||||
Name: "deactivate",
|
||||
ShortUsage: "tailscale sysext deactivate",
|
||||
ShortUsage: "tailscale configure sysext deactivate",
|
||||
ShortHelp: "Deactivate the Tailscale system extension on macOS",
|
||||
LongHelp: "This command deactivates the Tailscale system extension on macOS. To completely remove Tailscale, you'll also need to delete the VPN configuration separately (use `tailscale configure vpn-config uninstall`).",
|
||||
Exec: requiresStandalone,
|
||||
},
|
||||
{
|
||||
Name: "status",
|
||||
ShortUsage: "tailscale sysext status",
|
||||
ShortUsage: "tailscale configure sysext status",
|
||||
ShortHelp: "Print the enablement status of the Tailscale system extension",
|
||||
LongHelp: "This command prints the enablement status of the Tailscale system extension. If the extension is not enabled, run `tailscale sysext activate` to enable it.",
|
||||
Exec: requiresStandalone,
|
||||
@ -69,14 +69,14 @@ func vpnConfigCmd() *ffcli.Command {
|
||||
Subcommands: []*ffcli.Command{
|
||||
{
|
||||
Name: "install",
|
||||
ShortUsage: "tailscale mac-vpn install",
|
||||
ShortUsage: "tailscale configure mac-vpn install",
|
||||
ShortHelp: "Write the Tailscale VPN configuration to the macOS settings",
|
||||
LongHelp: "This command writes the Tailscale VPN configuration to the macOS settings. This is the entry that appears in System Settings > VPN. If you are running the Standalone variant of the client, you'll also need to install the system extension separately (run `tailscale configure sysext activate`).",
|
||||
Exec: requiresGUI,
|
||||
},
|
||||
{
|
||||
Name: "uninstall",
|
||||
ShortUsage: "tailscale mac-vpn uninstall",
|
||||
ShortUsage: "tailscale configure mac-vpn uninstall",
|
||||
ShortHelp: "Delete the Tailscale VPN configuration from the macOS settings",
|
||||
LongHelp: "This command removes the Tailscale VPN configuration from the macOS settings. This is the entry that appears in System Settings > VPN. If you are running the Standalone variant of the client, you'll also need to deactivate the system extension separately (run `tailscale configure sysext deactivate`).",
|
||||
Exec: requiresGUI,
|
||||
|
@ -289,7 +289,7 @@ var debugCmd = &ffcli.Command{
|
||||
Name: "capture",
|
||||
ShortUsage: "tailscale debug capture",
|
||||
Exec: runCapture,
|
||||
ShortHelp: "Streams pcaps for debugging",
|
||||
ShortHelp: "Stream pcaps for debugging",
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("capture")
|
||||
fs.StringVar(&captureArgs.outFile, "o", "", "path to stream the pcap (or - for stdout), leave empty to start wireshark")
|
||||
@ -315,13 +315,13 @@ var debugCmd = &ffcli.Command{
|
||||
Name: "peer-endpoint-changes",
|
||||
ShortUsage: "tailscale debug peer-endpoint-changes <hostname-or-IP>",
|
||||
Exec: runPeerEndpointChanges,
|
||||
ShortHelp: "Prints debug information about a peer's endpoint changes",
|
||||
ShortHelp: "Print debug information about a peer's endpoint changes",
|
||||
},
|
||||
{
|
||||
Name: "dial-types",
|
||||
ShortUsage: "tailscale debug dial-types <hostname-or-IP> <port>",
|
||||
Exec: runDebugDialTypes,
|
||||
ShortHelp: "Prints debug information about connecting to a given host or IP",
|
||||
ShortHelp: "Print debug information about connecting to a given host or IP",
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("dial-types")
|
||||
fs.StringVar(&debugDialTypesArgs.network, "network", "tcp", `network type to dial ("tcp", "udp", etc.)`)
|
||||
@ -342,7 +342,7 @@ var debugCmd = &ffcli.Command{
|
||||
{
|
||||
Name: "go-buildinfo",
|
||||
ShortUsage: "tailscale debug go-buildinfo",
|
||||
ShortHelp: "Prints Go's runtime/debug.BuildInfo",
|
||||
ShortHelp: "Print Go's runtime/debug.BuildInfo",
|
||||
Exec: runGoBuildInfo,
|
||||
},
|
||||
},
|
||||
|
@ -20,7 +20,7 @@ var dnsCmd = &ffcli.Command{
|
||||
Name: "status",
|
||||
ShortUsage: "tailscale dns status [--all]",
|
||||
Exec: runDNSStatus,
|
||||
ShortHelp: "Prints the current DNS status and configuration",
|
||||
ShortHelp: "Print the current DNS status and configuration",
|
||||
LongHelp: dnsStatusLongHelp(),
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("status")
|
||||
|
@ -41,7 +41,7 @@ func exitNodeCmd() *ffcli.Command {
|
||||
{
|
||||
Name: "suggest",
|
||||
ShortUsage: "tailscale exit-node suggest",
|
||||
ShortHelp: "Suggests the best available exit node",
|
||||
ShortHelp: "Suggest the best available exit node",
|
||||
Exec: runExitNodeSuggest,
|
||||
}},
|
||||
(func() []*ffcli.Command {
|
||||
|
@ -33,13 +33,13 @@ https://tailscale.com/s/client-metrics
|
||||
Name: "print",
|
||||
ShortUsage: "tailscale metrics print",
|
||||
Exec: runMetricsPrint,
|
||||
ShortHelp: "Prints current metric values in the Prometheus text exposition format",
|
||||
ShortHelp: "Print current metric values in Prometheus text format",
|
||||
},
|
||||
{
|
||||
Name: "write",
|
||||
ShortUsage: "tailscale metrics write <path>",
|
||||
Exec: runMetricsWrite,
|
||||
ShortHelp: "Writes metric values to a file",
|
||||
ShortHelp: "Write metric values to a file",
|
||||
LongHelp: strings.TrimSpace(`
|
||||
|
||||
The 'tailscale metrics write' command writes metric values to a text file provided as its
|
||||
|
@ -191,8 +191,7 @@ var nlStatusArgs struct {
|
||||
var nlStatusCmd = &ffcli.Command{
|
||||
Name: "status",
|
||||
ShortUsage: "tailscale lock status",
|
||||
ShortHelp: "Outputs the state of tailnet lock",
|
||||
LongHelp: "Outputs the state of tailnet lock",
|
||||
ShortHelp: "Output the state of tailnet lock",
|
||||
Exec: runNetworkLockStatus,
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("lock status")
|
||||
@ -293,8 +292,7 @@ func runNetworkLockStatus(ctx context.Context, args []string) error {
|
||||
var nlAddCmd = &ffcli.Command{
|
||||
Name: "add",
|
||||
ShortUsage: "tailscale lock add <public-key>...",
|
||||
ShortHelp: "Adds one or more trusted signing keys to tailnet lock",
|
||||
LongHelp: "Adds one or more trusted signing keys to tailnet lock",
|
||||
ShortHelp: "Add one or more trusted signing keys to tailnet lock",
|
||||
Exec: func(ctx context.Context, args []string) error {
|
||||
return runNetworkLockModify(ctx, args, nil)
|
||||
},
|
||||
@ -307,8 +305,7 @@ var nlRemoveArgs struct {
|
||||
var nlRemoveCmd = &ffcli.Command{
|
||||
Name: "remove",
|
||||
ShortUsage: "tailscale lock remove [--re-sign=false] <public-key>...",
|
||||
ShortHelp: "Removes one or more trusted signing keys from tailnet lock",
|
||||
LongHelp: "Removes one or more trusted signing keys from tailnet lock",
|
||||
ShortHelp: "Remove one or more trusted signing keys from tailnet lock",
|
||||
Exec: runNetworkLockRemove,
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("lock remove")
|
||||
@ -448,7 +445,7 @@ func runNetworkLockModify(ctx context.Context, addArgs, removeArgs []string) err
|
||||
var nlSignCmd = &ffcli.Command{
|
||||
Name: "sign",
|
||||
ShortUsage: "tailscale lock sign <node-key> [<rotation-key>]\ntailscale lock sign <auth-key>",
|
||||
ShortHelp: "Signs a node or pre-approved auth key",
|
||||
ShortHelp: "Sign a node or pre-approved auth key",
|
||||
LongHelp: `Either:
|
||||
- signs a node key and transmits the signature to the coordination
|
||||
server, or
|
||||
@ -510,7 +507,7 @@ func runNetworkLockSign(ctx context.Context, args []string) error {
|
||||
var nlDisableCmd = &ffcli.Command{
|
||||
Name: "disable",
|
||||
ShortUsage: "tailscale lock disable <disablement-secret>",
|
||||
ShortHelp: "Consumes a disablement secret to shut down tailnet lock for the tailnet",
|
||||
ShortHelp: "Consume a disablement secret to shut down tailnet lock for the tailnet",
|
||||
LongHelp: strings.TrimSpace(`
|
||||
|
||||
The 'tailscale lock disable' command uses the specified disablement
|
||||
@ -539,7 +536,7 @@ func runNetworkLockDisable(ctx context.Context, args []string) error {
|
||||
var nlLocalDisableCmd = &ffcli.Command{
|
||||
Name: "local-disable",
|
||||
ShortUsage: "tailscale lock local-disable",
|
||||
ShortHelp: "Disables tailnet lock for this node only",
|
||||
ShortHelp: "Disable tailnet lock for this node only",
|
||||
LongHelp: strings.TrimSpace(`
|
||||
|
||||
The 'tailscale lock local-disable' command disables tailnet lock for only
|
||||
@ -561,8 +558,8 @@ func runNetworkLockLocalDisable(ctx context.Context, args []string) error {
|
||||
var nlDisablementKDFCmd = &ffcli.Command{
|
||||
Name: "disablement-kdf",
|
||||
ShortUsage: "tailscale lock disablement-kdf <hex-encoded-disablement-secret>",
|
||||
ShortHelp: "Computes a disablement value from a disablement secret (advanced users only)",
|
||||
LongHelp: "Computes a disablement value from a disablement secret (advanced users only)",
|
||||
ShortHelp: "Compute a disablement value from a disablement secret (advanced users only)",
|
||||
LongHelp: "Compute a disablement value from a disablement secret (advanced users only)",
|
||||
Exec: runNetworkLockDisablementKDF,
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
var switchCmd = &ffcli.Command{
|
||||
Name: "switch",
|
||||
ShortUsage: "tailscale switch <id>",
|
||||
ShortHelp: "Switches to a different Tailscale account",
|
||||
ShortHelp: "Switch to a different Tailscale account",
|
||||
LongHelp: `"tailscale switch" switches between logged in accounts. You can
|
||||
use the ID that's returned from 'tailnet switch -list'
|
||||
to pick which profile you want to switch to. Alternatively, you
|
||||
|
@ -31,7 +31,7 @@ var syspolicyCmd = &ffcli.Command{
|
||||
Name: "list",
|
||||
ShortUsage: "tailscale syspolicy list",
|
||||
Exec: runSysPolicyList,
|
||||
ShortHelp: "Prints effective policy settings",
|
||||
ShortHelp: "Print effective policy settings",
|
||||
LongHelp: "The 'tailscale syspolicy list' subcommand displays the effective policy settings and their sources (e.g., MDM or environment variables).",
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("syspolicy list")
|
||||
@ -43,7 +43,7 @@ var syspolicyCmd = &ffcli.Command{
|
||||
Name: "reload",
|
||||
ShortUsage: "tailscale syspolicy reload",
|
||||
Exec: runSysPolicyReload,
|
||||
ShortHelp: "Forces a reload of policy settings, even if no changes are detected, and prints the result",
|
||||
ShortHelp: "Force a reload of policy settings, even if no changes are detected, and prints the result",
|
||||
LongHelp: "The 'tailscale syspolicy reload' subcommand forces a reload of policy settings, even if no changes are detected, and prints the result.",
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := newFlagSet("syspolicy reload")
|
||||
|
Loading…
x
Reference in New Issue
Block a user