From 1ce348b559dde704bd3be98ffd0cceea3d363785 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sat, 6 Jun 2026 16:17:59 -0400 Subject: [PATCH 1/3] Add vtctld get-routing-rules command Co-authored-by: Cursor Signed-off-by: Max Englander --- go.mod | 2 +- go.sum | 2 + internal/cmd/branch/vtctld/routing_rules.go | 49 +++++++++++++++++ .../cmd/branch/vtctld/routing_rules_test.go | 54 +++++++++++++++++++ internal/cmd/branch/vtctld/vtctld.go | 1 + internal/mock/vtctld_general.go | 8 +++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 internal/cmd/branch/vtctld/routing_rules.go create mode 100644 internal/cmd/branch/vtctld/routing_rules_test.go diff --git a/go.mod b/go.mod index 27181892..9e7bf4de 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.167.1-0.20260606201648-938306efbc47 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..9f0ae432 100644 --- a/go.sum +++ b/go.sum @@ -178,6 +178,8 @@ github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e h1:MZ8D+Z3m2v 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.167.1-0.20260606201648-938306efbc47 h1:gU4tPFSjq8bPGAJ7n9jswgslbEgMMpuZNYzDUyQ4DoA= +github.com/planetscale/planetscale-go v0.167.1-0.20260606201648-938306efbc47/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/routing_rules.go b/internal/cmd/branch/vtctld/routing_rules.go new file mode 100644 index 00000000..8aea1172 --- /dev/null +++ b/internal/cmd/branch/vtctld/routing_rules.go @@ -0,0 +1,49 @@ +package vtctld + +import ( + "fmt" + + "github.com/planetscale/cli/internal/cmdutil" + ps "github.com/planetscale/planetscale-go/planetscale" + "github.com/spf13/cobra" +) + +// GetRoutingRulesCmd reads live routing rules from the cluster via vtctld. +func GetRoutingRulesCmd(ch *cmdutil.Helper) *cobra.Command { + cmd := &cobra.Command{ + Use: "get-routing-rules ", + Short: "Get live routing rules for a branch", + Long: "Get live routing rules from the cluster via vtctld. " + + "This reads the current cluster state, unlike `pscale branch routing-rules get`, " + + "which reads from the schema snapshot.", + Args: cmdutil.RequiredArgs("database", "branch"), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + database, branch := args[0], args[1] + + client, err := ch.Client() + if err != nil { + return err + } + + end := ch.Printer.PrintProgress( + fmt.Sprintf("Fetching routing rules for %s\u2026", + progressTarget(ch.Config.Organization, database, branch))) + defer end() + + data, err := client.Vtctld.GetRoutingRules(ctx, &ps.VtctldGetRoutingRulesRequest{ + Organization: ch.Config.Organization, + Database: database, + Branch: branch, + }) + if err != nil { + return cmdutil.HandleError(err) + } + + end() + return ch.Printer.PrettyPrintJSON(data) + }, + } + + return cmd +} diff --git a/internal/cmd/branch/vtctld/routing_rules_test.go b/internal/cmd/branch/vtctld/routing_rules_test.go new file mode 100644 index 00000000..40dd9ea2 --- /dev/null +++ b/internal/cmd/branch/vtctld/routing_rules_test.go @@ -0,0 +1,54 @@ +package vtctld + +import ( + "bytes" + "context" + "encoding/json" + "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 TestGetRoutingRules(t *testing.T) { + c := qt.New(t) + + org := "my-org" + db := "my-db" + branch := "my-branch" + + svc := &mock.VtctldService{ + GetRoutingRulesFn: func(ctx context.Context, req *ps.VtctldGetRoutingRulesRequest) (json.RawMessage, error) { + c.Assert(req.Organization, qt.Equals, org) + c.Assert(req.Database, qt.Equals, db) + c.Assert(req.Branch, qt.Equals, branch) + return json.RawMessage(`{"rules":{"rules":[]}}`), 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 := GetRoutingRulesCmd(ch) + cmd.SetArgs([]string{db, branch}) + err := cmd.Execute() + c.Assert(err, qt.IsNil) + c.Assert(svc.GetRoutingRulesFnInvoked, qt.IsTrue) +} diff --git a/internal/cmd/branch/vtctld/vtctld.go b/internal/cmd/branch/vtctld/vtctld.go index bff983fa..eb7c2f98 100644 --- a/internal/cmd/branch/vtctld/vtctld.go +++ b/internal/cmd/branch/vtctld/vtctld.go @@ -20,6 +20,7 @@ func VtctldCmd(ch *cmdutil.Helper) *cobra.Command { cmd.AddCommand(PlannedReparentShardCmd(ch)) cmd.AddCommand(ListWorkflowsCmd(ch)) cmd.AddCommand(ListKeyspacesCmd(ch)) + cmd.AddCommand(GetRoutingRulesCmd(ch)) cmd.AddCommand(ListTabletsCmd(ch)) cmd.AddCommand(StartWorkflowCmd(ch)) cmd.AddCommand(StopWorkflowCmd(ch)) diff --git a/internal/mock/vtctld_general.go b/internal/mock/vtctld_general.go index 8b985259..2180dbbf 100644 --- a/internal/mock/vtctld_general.go +++ b/internal/mock/vtctld_general.go @@ -14,6 +14,9 @@ type VtctldService struct { ListKeyspacesFn func(context.Context, *ps.VtctldListKeyspacesRequest) (json.RawMessage, error) ListKeyspacesFnInvoked bool + GetRoutingRulesFn func(context.Context, *ps.VtctldGetRoutingRulesRequest) (json.RawMessage, error) + GetRoutingRulesFnInvoked bool + ListTabletsFn func(context.Context, *ps.ListBranchTabletsRequest) ([]*ps.TabletGroup, error) ListTabletsFnInvoked bool @@ -46,6 +49,11 @@ func (s *VtctldService) ListKeyspaces(ctx context.Context, req *ps.VtctldListKey return s.ListKeyspacesFn(ctx, req) } +func (s *VtctldService) GetRoutingRules(ctx context.Context, req *ps.VtctldGetRoutingRulesRequest) (json.RawMessage, error) { + s.GetRoutingRulesFnInvoked = true + return s.GetRoutingRulesFn(ctx, req) +} + func (s *VtctldService) ListTablets(ctx context.Context, req *ps.ListBranchTabletsRequest) ([]*ps.TabletGroup, error) { s.ListTabletsFnInvoked = true return s.ListTabletsFn(ctx, req) From a49d8f20b2cccdbb8d6e0c206d28f5401336a59e Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sat, 6 Jun 2026 18:01:21 -0400 Subject: [PATCH 2/3] Update get-routing-rules test for flattened API response Co-authored-by: Cursor Signed-off-by: Max Englander --- internal/cmd/branch/vtctld/routing_rules_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/branch/vtctld/routing_rules_test.go b/internal/cmd/branch/vtctld/routing_rules_test.go index 40dd9ea2..5a802a8e 100644 --- a/internal/cmd/branch/vtctld/routing_rules_test.go +++ b/internal/cmd/branch/vtctld/routing_rules_test.go @@ -27,7 +27,7 @@ func TestGetRoutingRules(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Database, qt.Equals, db) c.Assert(req.Branch, qt.Equals, branch) - return json.RawMessage(`{"rules":{"rules":[]}}`), nil + return json.RawMessage(`{"rules":[]}`), nil }, } From 0a532b8be2c5b822dfcfe062fc291d5a466cc38e Mon Sep 17 00:00:00 2001 From: Max Englander Date: Wed, 10 Jun 2026 18:52:08 -0400 Subject: [PATCH 3/3] Bump planetscale-go for get-routing-rules --- go.mod | 2 +- go.sum | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index dc552275..37d54b2b 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.168.1-0.20260609224250-8001bcf5eba5 + github.com/planetscale/planetscale-go v0.168.1 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 69ab203f..16128997 100644 --- a/go.sum +++ b/go.sum @@ -178,6 +178,10 @@ github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e h1:MZ8D+Z3m2v github.com/planetscale/noglog v0.2.1-0.20210421230640-bea75fcd2e8e/go.mod h1:hwAsSPQdvPa3WcfKfzTXxtEq/HlqwLjQasfO6QbGo4Q= github.com/planetscale/planetscale-go v0.168.1-0.20260609224250-8001bcf5eba5 h1:z+ao9YVEVP9GHpyB1Gmw48dt2+RQsS+BAOTE1QUigrw= github.com/planetscale/planetscale-go v0.168.1-0.20260609224250-8001bcf5eba5/go.mod h1:paQCI5SgquuoewvMQM7R+r1XJO868bdP6/ihGidYRM0= +github.com/planetscale/planetscale-go v0.168.1-0.20260610223405-068c67a15c9b h1:VJwfNPEI1sYyo52bhN/f8xxeHoh/BhE/0XWaNy5jYOk= +github.com/planetscale/planetscale-go v0.168.1-0.20260610223405-068c67a15c9b/go.mod h1:paQCI5SgquuoewvMQM7R+r1XJO868bdP6/ihGidYRM0= +github.com/planetscale/planetscale-go v0.168.1 h1:ikGvRC5YlQQiNf7vF9vxi6WBXNs2NokNie0sazMTTcA= +github.com/planetscale/planetscale-go v0.168.1/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=