diff --git a/internal/command/extensions/extensions.go b/internal/command/extensions/extensions.go index 54a59da225..c9e384c52d 100644 --- a/internal/command/extensions/extensions.go +++ b/internal/command/extensions/extensions.go @@ -8,7 +8,6 @@ import ( "github.com/superfly/flyctl/internal/command/extensions/arcjet" "github.com/superfly/flyctl/internal/command/extensions/kubernetes" sentry_ext "github.com/superfly/flyctl/internal/command/extensions/sentry" - "github.com/superfly/flyctl/internal/command/extensions/supabase" "github.com/superfly/flyctl/internal/command/extensions/tigris" "github.com/superfly/flyctl/internal/command/extensions/vector" "github.com/superfly/flyctl/internal/command/extensions/wafris" @@ -26,7 +25,6 @@ func New() (cmd *cobra.Command) { cmd.AddCommand( sentry_ext.New(), - supabase.New(), tigris.New(), kubernetes.New(), vector.New(), diff --git a/internal/command/extensions/supabase/dashboard.go b/internal/command/extensions/supabase/dashboard.go deleted file mode 100644 index 2b330bb7e9..0000000000 --- a/internal/command/extensions/supabase/dashboard.go +++ /dev/null @@ -1,48 +0,0 @@ -package supabase - -import ( - "context" - - "github.com/spf13/cobra" - - "github.com/superfly/flyctl/gql" - "github.com/superfly/flyctl/internal/command" - extensions_core "github.com/superfly/flyctl/internal/command/extensions/core" - "github.com/superfly/flyctl/internal/flag" -) - -func dashboard() (cmd *cobra.Command) { - const ( - long = `Visit the Supabase database dashboard` - - short = long - usage = "dashboard [database_name]" - ) - - cmd = command.New(usage, short, long, runDashboard, command.RequireSession, command.LoadAppNameIfPresent) - - flag.Add(cmd, - flag.App(), - flag.AppConfig(), - flag.Org(), - extensions_core.SharedFlags, - ) - cmd.Args = cobra.MaximumNArgs(1) - - return cmd -} - -func runDashboard(ctx context.Context) error { - org := flag.GetOrg(ctx) - - if org != "" { - return extensions_core.OpenOrgDashboard(ctx, org, "supabase") - } - - extension, _, err := extensions_core.Discover(ctx, gql.AddOnTypeSupabase) - if err != nil { - return err - } - - return extensions_core.OpenDashboard(ctx, extension.Name, gql.AddOnTypeSupabase) -} diff --git a/internal/command/extensions/supabase/destroy.go b/internal/command/extensions/supabase/destroy.go deleted file mode 100644 index 98ca08714b..0000000000 --- a/internal/command/extensions/supabase/destroy.go +++ /dev/null @@ -1,79 +0,0 @@ -package supabase - -import ( - "context" - "fmt" - - "github.com/spf13/cobra" - - "github.com/superfly/flyctl/gql" - "github.com/superfly/flyctl/iostreams" - - "github.com/superfly/flyctl/internal/command" - extensions_core "github.com/superfly/flyctl/internal/command/extensions/core" - "github.com/superfly/flyctl/internal/flag" - "github.com/superfly/flyctl/internal/flyutil" - "github.com/superfly/flyctl/internal/prompt" -) - -func destroy() (cmd *cobra.Command) { - const ( - long = `Permanently destroy a Supabase database` - - short = long - usage = "destroy [name]" - ) - - cmd = command.New(usage, short, long, runDestroy, command.RequireSession, command.LoadAppNameIfPresent) - - cmd.Args = cobra.MaximumNArgs(1) - - flag.Add(cmd, - flag.App(), - flag.AppConfig(), - extensions_core.SharedFlags, - ) - - return cmd -} - -func runDestroy(ctx context.Context) (err error) { - io := iostreams.FromContext(ctx) - colorize := io.ColorScheme() - - extension, _, err := extensions_core.Discover(ctx, gql.AddOnTypeSupabase) - if err != nil { - return err - } - - if !flag.GetYes(ctx) { - const msg = "Destroying a Supabase database is not reversible." - fmt.Fprintln(io.ErrOut, colorize.Red(msg)) - - switch confirmed, err := prompt.Confirmf(ctx, "Destroy Supabase database %s?", extension.Name); { - case err == nil: - if !confirmed { - return nil - } - case prompt.IsNonInteractive(err): - return prompt.NonInteractiveError("yes flag must be specified when not running interactively") - default: - return err - } - } - - var ( - out = iostreams.FromContext(ctx).Out - client = flyutil.ClientFromContext(ctx).GenqClient() - ) - - _, err = gql.DeleteAddOn(ctx, client, extension.Name, string(gql.AddOnTypeSupabase)) - - if err != nil { - return - } - - fmt.Fprintf(out, "Your Supabase database %s was destroyed\n", extension.Name) - - return -} diff --git a/internal/command/extensions/supabase/list.go b/internal/command/extensions/supabase/list.go deleted file mode 100644 index 2f0b58a099..0000000000 --- a/internal/command/extensions/supabase/list.go +++ /dev/null @@ -1,74 +0,0 @@ -package supabase - -import ( - "context" - - "github.com/spf13/cobra" - - "github.com/superfly/flyctl/gql" - "github.com/superfly/flyctl/iostreams" - - "github.com/superfly/flyctl/internal/command" - extensions_core "github.com/superfly/flyctl/internal/command/extensions/core" - "github.com/superfly/flyctl/internal/flag" - "github.com/superfly/flyctl/internal/flyutil" - "github.com/superfly/flyctl/internal/render" -) - -func list() (cmd *cobra.Command) { - const ( - long = `List your Supabase databases` - short = long - usage = "list" - ) - - cmd = command.New(usage, short, long, runList, command.RequireSession) - - cmd.Aliases = []string{"ls"} - - flag.Add(cmd, - flag.Org(), - extensions_core.SharedFlags, - ) - - return cmd -} - -func runList(ctx context.Context) (err error) { - var ( - out = iostreams.FromContext(ctx).Out - apiClient = flyutil.ClientFromContext(ctx) - client = apiClient.GenqClient() - orgSlug = flag.GetOrg(ctx) - ) - - var rows [][]string - - if orgSlug != "" { - if _, err := apiClient.GetOrganizationBySlug(ctx, orgSlug); err != nil { - return err - } - - response, err := gql.ListOrganizationAddOns(ctx, client, orgSlug, "supabase") - if err != nil { - return err - } - - for _, addon := range response.Organization.AddOns.Nodes { - rows = append(rows, []string{addon.Name, orgSlug, addon.PrimaryRegion}) - } - } else { - response, err := gql.ListAddOns(ctx, client, "supabase") - if err != nil { - return err - } - - for _, addon := range response.AddOns.Nodes { - rows = append(rows, []string{addon.Name, addon.Organization.Slug, addon.PrimaryRegion}) - } - } - - _ = render.Table(out, "", rows, "Name", "Org", "Primary Region") - - return -} diff --git a/internal/command/extensions/supabase/status.go b/internal/command/extensions/supabase/status.go deleted file mode 100644 index f57890ae81..0000000000 --- a/internal/command/extensions/supabase/status.go +++ /dev/null @@ -1,38 +0,0 @@ -package supabase - -import ( - "context" - - "github.com/spf13/cobra" - "github.com/superfly/flyctl/gql" - "github.com/superfly/flyctl/internal/command" - extensions_core "github.com/superfly/flyctl/internal/command/extensions/core" - "github.com/superfly/flyctl/internal/flag" -) - -func status() *cobra.Command { - const ( - short = "Show details about a Supabase Postgres database" - long = short + "\n" - - usage = "status [name]" - ) - - cmd := command.New(usage, short, long, runStatus, - command.RequireSession, command.LoadAppNameIfPresent, - ) - - cmd.Args = cobra.MaximumNArgs(1) - - flag.Add(cmd, - flag.App(), - flag.AppConfig(), - extensions_core.SharedFlags, - ) - - return cmd -} - -func runStatus(ctx context.Context) (err error) { - return extensions_core.Status(ctx, gql.AddOnTypeSupabase) -} diff --git a/internal/command/extensions/supabase/supabase.go b/internal/command/extensions/supabase/supabase.go deleted file mode 100644 index 440fb7ea0a..0000000000 --- a/internal/command/extensions/supabase/supabase.go +++ /dev/null @@ -1,19 +0,0 @@ -package supabase - -import ( - "github.com/spf13/cobra" - "github.com/superfly/flyctl/internal/command" -) - -func New() (cmd *cobra.Command) { - - const ( - short = "Provision and manage Supabase Postgres databases" - long = short + "\n" - ) - - cmd = command.New("supabase", short, long, nil) - cmd.AddCommand(destroy(), dashboard(), list(), status()) - - return cmd -} diff --git a/internal/command/launch/cmd.go b/internal/command/launch/cmd.go index e9df05598b..a1f6b043ff 100644 --- a/internal/command/launch/cmd.go +++ b/internal/command/launch/cmd.go @@ -466,7 +466,7 @@ func run(ctx context.Context) (err error) { status.VM.ProcessN = len(vm.Processes) } - status.HasPostgres = launchManifest.Plan.Postgres.FlyPostgres != nil || launchManifest.Plan.Postgres.SupabasePostgres != nil || launchManifest.Plan.Postgres.ManagedPostgres != nil + status.HasPostgres = launchManifest.Plan.Postgres.FlyPostgres != nil || launchManifest.Plan.Postgres.ManagedPostgres != nil status.HasRedis = launchManifest.Plan.Redis.UpstashRedis != nil status.HasSentry = launchManifest.Plan.Sentry diff --git a/internal/command/launch/describe_plan.go b/internal/command/launch/describe_plan.go index fc9bdaaf5f..38478270b5 100644 --- a/internal/command/launch/describe_plan.go +++ b/internal/command/launch/describe_plan.go @@ -20,8 +20,6 @@ func describePostgresPlan(launchPlan *plan.LaunchPlan) (string, error) { switch provider := launchPlan.Postgres.Provider().(type) { case *plan.FlyPostgresPlan: return describeFlyPostgresPlan(provider) - case *plan.SupabasePostgresPlan: - return describeSupabasePostgresPlan(provider, launchPlan) case *plan.ManagedPostgresPlan: return describeManagedPostgresPlan(provider, launchPlan) } @@ -49,11 +47,6 @@ func describeFlyPostgresPlan(p *plan.FlyPostgresPlan) (string, error) { return strings.Join(info, ", "), nil } -func describeSupabasePostgresPlan(p *plan.SupabasePostgresPlan, launchPlan *plan.LaunchPlan) (string, error) { - - return fmt.Sprintf("(Supabase) %s in %s", p.GetDbName(launchPlan), p.GetRegion(launchPlan)), nil -} - func describeRedisPlan(ctx context.Context, p plan.RedisPlan) (string, error) { switch provider := p.Provider().(type) { diff --git a/internal/command/launch/launch_databases.go b/internal/command/launch/launch_databases.go index b489cc40bc..cc8bb31762 100644 --- a/internal/command/launch/launch_databases.go +++ b/internal/command/launch/launch_databases.go @@ -44,10 +44,6 @@ func (state *launchState) createDatabases(ctx context.Context) error { } } - if state.Plan.Postgres.SupabasePostgres != nil && (planStep == "" || planStep == "postgres") { - fmt.Fprintf(iostreams.FromContext(ctx).ErrOut, "Supabase Postgres is no longer supported.\n") - } - if state.Plan.Redis.UpstashRedis != nil && (planStep == "" || planStep == "redis") { err := state.createUpstashRedis(ctx) if err != nil { diff --git a/internal/command/launch/plan/postgres.go b/internal/command/launch/plan/postgres.go index 3fc6cc9a06..338873388c 100644 --- a/internal/command/launch/plan/postgres.go +++ b/internal/command/launch/plan/postgres.go @@ -13,9 +13,8 @@ import ( ) type PostgresPlan struct { - FlyPostgres *FlyPostgresPlan `json:"fly_postgres"` - SupabasePostgres *SupabasePostgresPlan `json:"supabase_postgres"` - ManagedPostgres *ManagedPostgresPlan `json:"managed_postgres"` + FlyPostgres *FlyPostgresPlan `json:"fly_postgres"` + ManagedPostgres *ManagedPostgresPlan `json:"managed_postgres"` } func (p *PostgresPlan) Provider() any { @@ -25,9 +24,6 @@ func (p *PostgresPlan) Provider() any { if p.FlyPostgres != nil { return p.FlyPostgres } - if p.SupabasePostgres != nil { - return p.SupabasePostgres - } if p.ManagedPostgres != nil { return p.ManagedPostgres } @@ -249,27 +245,6 @@ func (p *FlyPostgresPlan) Guest() *fly.MachineGuest { return &guest } -type SupabasePostgresPlan struct { - DbName string `json:"db_name"` - Region string `json:"region"` -} - -func (p *SupabasePostgresPlan) GetDbName(plan *LaunchPlan) string { - if p.DbName == "" { - return plan.AppName + "-db" - } - - return p.DbName -} - -func (p *SupabasePostgresPlan) GetRegion(plan *LaunchPlan) string { - if p.Region == "" { - return plan.RegionCode - } - - return p.Region -} - type ManagedPostgresPlan struct { DbName string `json:"db_name"` Region string `json:"region"` diff --git a/internal/command/launch/state.go b/internal/command/launch/state.go index fb43029abf..aefeaf152e 100644 --- a/internal/command/launch/state.go +++ b/internal/command/launch/state.go @@ -2,7 +2,6 @@ package launch import ( "context" - "errors" "fmt" "strconv" "strings" @@ -11,11 +10,8 @@ import ( fly "github.com/superfly/fly-go" "github.com/superfly/flyctl/gql" "github.com/superfly/flyctl/internal/appconfig" - extensions_core "github.com/superfly/flyctl/internal/command/extensions/core" "github.com/superfly/flyctl/internal/command/launch/plan" - "github.com/superfly/flyctl/internal/flag" "github.com/superfly/flyctl/internal/flyutil" - "github.com/superfly/flyctl/internal/prompt" "github.com/superfly/flyctl/iostreams" ) @@ -217,69 +213,5 @@ func (state *launchState) validateExtensions(ctx context.Context) error { // This is written a little awkwardly with the expectation // that we'll probably need more validation in the future. // When that happens we can just errors.Join(a(), b(), c()...) - - io := iostreams.FromContext(ctx) - noConfirm := !io.IsInteractive() || flag.GetBool(ctx, "now") - - org, err := state.orgCompact(ctx) - if err != nil { - return err - } - - validateSupabase := func() error { - supabase := state.Plan.Postgres.SupabasePostgres - if supabase == nil { - return nil - } - - // We're using Supabase. Ensure that we're within plan limits for the target org. - client := flyutil.ClientFromContext(ctx).GenqClient() - - response, err := gql.ListOrganizationAddOns(ctx, client, org.Slug, "supabase") - if err != nil { - return fmt.Errorf("failed to list Supabase databases for org %q: %w", org.Slug, err) - } - - // TODO: We'd like to be able to query the user's plan to see if they're on a paid plan. - // For now, we'll just nag when they create their second database, every time. - - if len(response.Organization.AddOns.Nodes) != 1 { - // If we're at zero databases, we're within the free plan. - // If we're at >=2 databases, we know we're on a paid plan. - // It's only 1 existing database where we need to validate the plan. - return nil - } - - if noConfirm { - // We can't validate this any further until we can query the plan info. - // Assume it's okay, and let the launch fail if it's not. - - // TODO: Once we can query whether or not the user is on a paid plan, - // we'll be able to early-exit in non-interactive mode and prevent a failed launch. - return nil - } - - fmt.Fprintf(io.Out, "You're about to create a second Supabase database. This requires a paid plan.\n") - fmt.Fprintf(io.Out, "Please check to ensure that your plan supports this, otherwise your launch may fail.\n") - openDashboard, err := prompt.Confirm(ctx, "Open the dashboard to check your plan?") - if err != nil { - return err - } - if openDashboard { - if err = extensions_core.OpenOrgDashboard(ctx, org.Slug, "supabase"); err != nil { - return err - } - } - confirm, err := prompt.Confirm(ctx, fmt.Sprintf("Continue launching %s?", state.Plan.AppName)) - if err != nil { - return err - } - if !confirm { - return errors.New("aborted by user") - } - - return nil - } - - return validateSupabase() + return nil }