diff --git a/go.mod b/go.mod index bb198d1f..8358c908 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.141.0 + github.com/planetscale/planetscale-go v0.142.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.1 diff --git a/go.sum b/go.sum index 05c7c43c..4194c172 100644 --- a/go.sum +++ b/go.sum @@ -175,8 +175,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.141.0 h1:KatZiVFM6xTfLZFrpee9FMRhumDyGZQAKRnn31HG4ds= -github.com/planetscale/planetscale-go v0.141.0/go.mod h1:/n7PU99UvYaajJlTbMWMOOlHmkEuN7SFjvLNDSgMQOk= +github.com/planetscale/planetscale-go v0.142.0 h1:luApvfbD2xcg8gS9TmUC7nFINl4t3T9qzX7Ed8rYlwQ= +github.com/planetscale/planetscale-go v0.142.0/go.mod h1:PheYDHAwF14wfCBak1M0J64AdPW8NUeyvgPgWqe7zpI= 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/database/create.go b/internal/cmd/database/create.go index 019c9def..0357fbd4 100644 --- a/internal/cmd/database/create.go +++ b/internal/cmd/database/create.go @@ -22,6 +22,7 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { clusterSize string engine string wait bool + replicas *int } cmd := &cobra.Command{ @@ -41,6 +42,10 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { createReq.Kind = engine + if cmd.Flags().Changed("replicas") { + createReq.Replicas = flags.replicas + } + client, err := ch.Client() if err != nil { return err @@ -85,6 +90,9 @@ func CreateCmd(ch *cmdutil.Helper) *cobra.Command { cmd.Flags().StringVar(&createReq.Region, "region", "", "region for the database") cmd.Flags().StringVar(&createReq.ClusterSize, "cluster-size", "", "cluster size for Scaler Pro databases. Use `pscale size cluster list` to see the valid sizes.") + + flags.replicas = cmd.Flags().Int("replicas", 0, "number of replicas for postgresql database. 0 for single node, 2+ for HA.") + cmd.Flags().StringVar(&flags.engine, "engine", string(ps.DatabaseEngineMySQL), "The database engine for the database. Supported values: mysql, postgresql. Defaults to mysql.") cmd.RegisterFlagCompletionFunc("engine", func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) { return []cobra.Completion{ diff --git a/internal/cmd/database/create_test.go b/internal/cmd/database/create_test.go index 48d222b6..6f0d72f4 100644 --- a/internal/cmd/database/create_test.go +++ b/internal/cmd/database/create_test.go @@ -32,6 +32,7 @@ func TestDatabase_CreateCmd(t *testing.T) { c.Assert(req.Organization, qt.Equals, org) c.Assert(req.Name, qt.Equals, db) c.Assert(req.Region, qt.Equals, "us-east") + c.Assert(req.Replicas, qt.IsNil) // Should be nil when not set return res, nil }, @@ -66,6 +67,60 @@ func TestDatabase_CreateCmd(t *testing.T) { c.Assert(buf.String(), qt.JSONEquals, res) } +func TestDatabase_CreateCmdWithReplicasZero(t *testing.T) { + c := qt.New(t) + + var buf bytes.Buffer + format := printer.JSON + p := printer.NewPrinter(&format) + p.SetResourceOutput(&buf) + + org := "planetscale" + db := "planetscale" + + res := &ps.Database{Name: "foo"} + + svc := &mock.DatabaseService{ + CreateFn: func(ctx context.Context, req *ps.CreateDatabaseRequest) (*ps.Database, error) { + c.Assert(req.Organization, qt.Equals, org) + c.Assert(req.Name, qt.Equals, db) + c.Assert(req.Region, qt.Equals, "us-east") + c.Assert(req.Replicas, qt.IsNotNil) // Should be set when explicitly passed + c.Assert(*req.Replicas, qt.Equals, 0) // Should be 0 + + return res, nil + }, + } + + ch := &cmdutil.Helper{ + Printer: p, + Config: &config.Config{ + Organization: org, + }, + Client: func() (*ps.Client, error) { + return &ps.Client{ + Databases: svc, + Organizations: &mock.OrganizationsService{ + GetFn: func(ctx context.Context, request *ps.GetOrganizationRequest) (*ps.Organization, error) { + return &ps.Organization{ + RemainingFreeDatabases: 1, + Name: request.Organization, + }, nil + }, + }, + }, nil + }, + } + + cmd := CreateCmd(ch) + cmd.SetArgs([]string{db, "--region", "us-east", "--replicas", "0"}) + err := cmd.Execute() + + c.Assert(err, qt.IsNil) + c.Assert(svc.CreateFnInvoked, qt.IsTrue) + c.Assert(buf.String(), qt.JSONEquals, res) +} + func TestDatabase_CreateCmdPostgres(t *testing.T) { c := qt.New(t) @@ -118,3 +173,57 @@ func TestDatabase_CreateCmdPostgres(t *testing.T) { c.Assert(svc.CreateFnInvoked, qt.IsTrue) c.Assert(buf.String(), qt.JSONEquals, res) } + +func TestDatabase_CreateCmdWithReplicas(t *testing.T) { + c := qt.New(t) + + var buf bytes.Buffer + format := printer.JSON + p := printer.NewPrinter(&format) + p.SetResourceOutput(&buf) + + org := "planetscale" + db := "planetscale" + + res := &ps.Database{Name: "foo"} + + svc := &mock.DatabaseService{ + CreateFn: func(ctx context.Context, req *ps.CreateDatabaseRequest) (*ps.Database, error) { + c.Assert(req.Organization, qt.Equals, org) + c.Assert(req.Name, qt.Equals, db) + c.Assert(req.Region, qt.Equals, "us-east") + c.Assert(req.Replicas, qt.IsNotNil) + c.Assert(*req.Replicas, qt.Equals, 3) + + return res, nil + }, + } + + ch := &cmdutil.Helper{ + Printer: p, + Config: &config.Config{ + Organization: org, + }, + Client: func() (*ps.Client, error) { + return &ps.Client{ + Databases: svc, + Organizations: &mock.OrganizationsService{ + GetFn: func(ctx context.Context, request *ps.GetOrganizationRequest) (*ps.Organization, error) { + return &ps.Organization{ + RemainingFreeDatabases: 1, + Name: request.Organization, + }, nil + }, + }, + }, nil + }, + } + + cmd := CreateCmd(ch) + cmd.SetArgs([]string{db, "--region", "us-east", "--replicas", "3"}) + err := cmd.Execute() + + c.Assert(err, qt.IsNil) + c.Assert(svc.CreateFnInvoked, qt.IsTrue) + c.Assert(buf.String(), qt.JSONEquals, res) +}