From ec5eb0e92719f4be9536b3c7b09dab20a0d8c8aa Mon Sep 17 00:00:00 2001 From: Nick Van Wiggeren Date: Tue, 9 Jun 2026 08:28:09 -0700 Subject: [PATCH] Add filter flags to `branch list-tablets` `pscale branch list-tablets` returned every tablet on a branch, so finding a specific tablet alias (e.g. for a throttler config change) on large, multi-keyspace branches meant parsing the full output by hand. Add the filters that vtctldclient GetTablets supports, now that the API and SDK pass them through (planetscale/issues#1955): - --keyspace, --shard (requires --keyspace), --tablet-type - --tablet-alias (comma-separated/repeatable; overrides the other filters) Bumps planetscale-go to v0.168.0 for the new ListBranchTabletsRequest filter fields. --- go.mod | 2 +- go.sum | 4 +- internal/cmd/branch/vtctld/list_tablets.go | 23 +++- .../cmd/branch/vtctld/list_tablets_test.go | 106 ++++++++++++++++++ 4 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 internal/cmd/branch/vtctld/list_tablets_test.go diff --git a/go.mod b/go.mod index 27181892..5db98a4b 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/mattn/go-shellwords v1.0.12 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c - github.com/planetscale/planetscale-go v0.167.0 + github.com/planetscale/planetscale-go v0.168.0 github.com/planetscale/psdb v0.0.0-20250717190954-65c6661ab6e4 github.com/planetscale/psdbproxy v0.0.0-20250728082226-3f4ea3a74ec7 github.com/spf13/cobra v1.10.2 diff --git a/go.sum b/go.sum index 2891aa4f..f657fe9c 100644 --- a/go.sum +++ b/go.sum @@ -176,8 +176,8 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjL github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e h1:MZ8D+Z3m2vvqGZLvoQfpaGg/j1fNDr4j03s3PRz4rVY= github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e/go.mod h1:hwAsSPQdvPa3WcfKfzTXxtEq/HlqwLjQasfO6QbGo4Q= -github.com/planetscale/planetscale-go v0.167.0 h1:TqXYCu7Pgcc3wAVD7cNBqZ1zH5+rXrxr6UGYNSV5V44= -github.com/planetscale/planetscale-go v0.167.0/go.mod h1:paQCI5SgquuoewvMQM7R+r1XJO868bdP6/ihGidYRM0= +github.com/planetscale/planetscale-go v0.168.0 h1:MZfhTUbZ4DNv2q7WSMF0VqYovGpdkvY40JstZTCPTW4= +github.com/planetscale/planetscale-go v0.168.0/go.mod h1:paQCI5SgquuoewvMQM7R+r1XJO868bdP6/ihGidYRM0= github.com/planetscale/psdb v0.0.0-20250717190954-65c6661ab6e4 h1:Xv5pj20Rhfty1Tv0OVcidg4ez4PvGrpKvb6rvUwQgDs= github.com/planetscale/psdb v0.0.0-20250717190954-65c6661ab6e4/go.mod h1:M52h5IWxAcbdQ1hSZrLAGQC4ZXslxEsK/Wh9nu3wdWs= github.com/planetscale/psdbproxy v0.0.0-20250728082226-3f4ea3a74ec7 h1:aRd6vdE1fyuSI4RVj7oCr8lFmgqXvpnPUmN85VbZCp8= diff --git a/internal/cmd/branch/vtctld/list_tablets.go b/internal/cmd/branch/vtctld/list_tablets.go index f76a4701..61276afd 100644 --- a/internal/cmd/branch/vtctld/list_tablets.go +++ b/internal/cmd/branch/vtctld/list_tablets.go @@ -9,6 +9,13 @@ import ( ) func ListTabletsCmd(ch *cmdutil.Helper) *cobra.Command { + var flags struct { + keyspace string + shard string + tabletType string + tabletAliases []string + } + cmd := &cobra.Command{ Use: "list-tablets ", Short: "List tablets for a branch, grouped by keyspace and shard", @@ -28,9 +35,13 @@ func ListTabletsCmd(ch *cmdutil.Helper) *cobra.Command { defer end() groups, err := client.Vtctld.ListTablets(ctx, &ps.ListBranchTabletsRequest{ - Organization: ch.Config.Organization, - Database: database, - Branch: branch, + Organization: ch.Config.Organization, + Database: database, + Branch: branch, + Keyspace: flags.keyspace, + Shard: flags.shard, + TabletType: flags.tabletType, + TabletAliases: flags.tabletAliases, }) if err != nil { return cmdutil.HandleError(err) @@ -41,5 +52,11 @@ func ListTabletsCmd(ch *cmdutil.Helper) *cobra.Command { }, } + cmd.Flags().StringVar(&flags.keyspace, "keyspace", "", "Only list tablets in this keyspace") + cmd.Flags().StringVar(&flags.shard, "shard", "", "Only list tablets in this shard (requires --keyspace)") + cmd.Flags().StringVar(&flags.tabletType, "tablet-type", "", "Only list tablets of this type (e.g. primary, replica, rdonly)") + cmd.Flags().StringSliceVar(&flags.tabletAliases, "tablet-alias", nil, + "Only list the tablet(s) with these aliases, e.g. zone1-0000000100 (comma-separated; overrides the other filters)") + return cmd } diff --git a/internal/cmd/branch/vtctld/list_tablets_test.go b/internal/cmd/branch/vtctld/list_tablets_test.go new file mode 100644 index 00000000..fdabb59e --- /dev/null +++ b/internal/cmd/branch/vtctld/list_tablets_test.go @@ -0,0 +1,106 @@ +package vtctld + +import ( + "bytes" + "context" + "testing" + + qt "github.com/frankban/quicktest" + + "github.com/planetscale/cli/internal/cmdutil" + "github.com/planetscale/cli/internal/config" + "github.com/planetscale/cli/internal/mock" + "github.com/planetscale/cli/internal/printer" + ps "github.com/planetscale/planetscale-go/planetscale" +) + +func TestListTablets(t *testing.T) { + c := qt.New(t) + + org := "my-org" + db := "my-db" + branch := "my-branch" + + svc := &mock.VtctldService{ + ListTabletsFn: func(ctx context.Context, req *ps.ListBranchTabletsRequest) ([]*ps.TabletGroup, error) { + c.Assert(req.Organization, qt.Equals, org) + c.Assert(req.Database, qt.Equals, db) + c.Assert(req.Branch, qt.Equals, branch) + + // No filter flags set. + c.Assert(req.Keyspace, qt.Equals, "") + c.Assert(req.Shard, qt.Equals, "") + c.Assert(req.TabletType, qt.Equals, "") + c.Assert(req.TabletAliases, qt.HasLen, 0) + + return []*ps.TabletGroup{}, nil + }, + } + + var buf bytes.Buffer + format := printer.JSON + p := printer.NewPrinter(&format) + p.SetResourceOutput(&buf) + + ch := &cmdutil.Helper{ + Printer: p, + Config: &config.Config{Organization: org}, + Client: func() (*ps.Client, error) { + return &ps.Client{ + Vtctld: svc, + }, nil + }, + } + + cmd := ListTabletsCmd(ch) + cmd.SetArgs([]string{db, branch}) + err := cmd.Execute() + c.Assert(err, qt.IsNil) + c.Assert(svc.ListTabletsFnInvoked, qt.IsTrue) +} + +func TestListTablets_Filters(t *testing.T) { + c := qt.New(t) + + org := "my-org" + db := "my-db" + branch := "my-branch" + + svc := &mock.VtctldService{ + ListTabletsFn: func(ctx context.Context, req *ps.ListBranchTabletsRequest) ([]*ps.TabletGroup, error) { + c.Assert(req.Keyspace, qt.Equals, "commerce") + c.Assert(req.Shard, qt.Equals, "-80") + c.Assert(req.TabletType, qt.Equals, "replica") + c.Assert(req.TabletAliases, qt.DeepEquals, []string{"zone1-0000000100", "zone1-0000000101"}) + + return []*ps.TabletGroup{}, nil + }, + } + + var buf bytes.Buffer + format := printer.JSON + p := printer.NewPrinter(&format) + p.SetResourceOutput(&buf) + + ch := &cmdutil.Helper{ + Printer: p, + Config: &config.Config{Organization: org}, + Client: func() (*ps.Client, error) { + return &ps.Client{ + Vtctld: svc, + }, nil + }, + } + + cmd := ListTabletsCmd(ch) + cmd.SetArgs([]string{ + db, branch, + "--keyspace", "commerce", + "--shard=-80", + "--tablet-type", "replica", + "--tablet-alias", "zone1-0000000100,zone1-0000000101", + }) + err := cmd.Execute() + c.Assert(err, qt.IsNil) + c.Assert(svc.ListTabletsFnInvoked, qt.IsTrue) +}