diff --git a/cmd/tailscale/cli/routecheck.go b/cmd/tailscale/cli/routecheck.go index 679c174be..ade301c70 100644 --- a/cmd/tailscale/cli/routecheck.go +++ b/cmd/tailscale/cli/routecheck.go @@ -13,12 +13,13 @@ "slices" "strings" "text/tabwriter" - "time" jsonv2 "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" "github.com/peterbourgon/ff/v3/ffcli" + "tailscale.com/cmd/tailscale/cli/jsonoutput" + "tailscale.com/cmd/tailscale/tsroutecheckjsonv0" "tailscale.com/net/routecheck" "tailscale.com/tstime" ) @@ -41,13 +42,14 @@ func init() { var routecheckFlagSet = func() *flag.FlagSet { fs := newFlagSet("routecheck") fs.BoolVar(&routecheckArgs.probe, "probe", false, "probe now to generate a new reachability report") - fs.StringVar(&routecheckArgs.format, "format", "", `output format: empty (for human-readable), "json" or "json-line"`) + fs.Var(&routecheckArgs.format, "format", `output format: empty (for human-readable), "json" or "json-line"`) + fs.Var(routecheckArgs.format.JSONBool(), "json", "output in JSON format") return fs }() var routecheckArgs struct { probe bool - format string + format jsonoutput.Format } func runRoutecheck(ctx context.Context, args []string) error { @@ -67,7 +69,7 @@ func runRoutecheck(ctx context.Context, args []string) error { func printRouteCheckReport(rp *routecheck.Report) error { var enc *jsontext.Encoder - switch routecheckArgs.format { + switch routecheckArgs.format.String() { case "": case "json": enc = jsontext.NewEncoder(Stdout, jsontext.WithIndent("\t")) @@ -90,10 +92,7 @@ func printRouteCheckReport(rp *routecheck.Report) error { } if enc != nil { - out := struct { - Done time.Time `json:"done"` - Routes routecheck.RoutablePrefixes `json:"routes"` - }{ + out := tsroutecheckjsonv0.ReportResponse{ Done: rp.Done, Routes: routes, } diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index 0a61b4564..58760a804 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -184,6 +184,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/cmd/tailscale/cli/ffcomplete from tailscale.com/cmd/tailscale/cli tailscale.com/cmd/tailscale/cli/ffcomplete/internal from tailscale.com/cmd/tailscale/cli/ffcomplete tailscale.com/cmd/tailscale/cli/jsonoutput from tailscale.com/cmd/tailscale/cli + tailscale.com/cmd/tailscale/tsroutecheckjsonv0 from tailscale.com/cmd/tailscale/cli tailscale.com/control/controlbase from tailscale.com/control/controlhttp+ tailscale.com/control/controlhttp from tailscale.com/control/ts2021 tailscale.com/control/controlhttp/controlhttpcommon from tailscale.com/control/controlhttp diff --git a/cmd/tailscale/tsroutecheckjsonv0/tsroutecheck.go b/cmd/tailscale/tsroutecheckjsonv0/tsroutecheck.go new file mode 100644 index 000000000..f9dd89348 --- /dev/null +++ b/cmd/tailscale/tsroutecheckjsonv0/tsroutecheck.go @@ -0,0 +1,28 @@ +// Copyright (c) Tailscale Inc & contributors +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_routecheck + +// Package tsroutecheckjsonv0 provides types for unmarshalling the JSON output of the +// "tailscale routecheck --json" command: +// +// - [ReportResponse] will unmarshal the output of "tailscale routecheck --json" +// +// # WARNING: unstable +// +// Format is "v0" and is subject to change. +// There is no guarantee of backwards or forwards compatibility. +package tsroutecheckjsonv0 + +import ( + "time" + + "tailscale.com/net/routecheck" +) + +// ReportResponse is the JSON form of [routecheck.Report]. +// Experimental: This output is not yet stable: tailscale/tailscale#17366. +type ReportResponse struct { + Done time.Time `json:"done"` + Routes routecheck.RoutablePrefixes `json:"routes"` +}