Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enveloop CLI commands #3526

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gql/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions gql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ type AddOnProvider {
}

enum AddOnType {
"""
An Enveloop team
"""
enveloop

"""
A Kubernetes cluster
"""
Expand Down
68 changes: 68 additions & 0 deletions internal/command/extensions/enveloop/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package enveloop

import (
"context"

"github.com/spf13/cobra"
"github.com/superfly/flyctl/gql"
"github.com/superfly/flyctl/internal/appconfig"
"github.com/superfly/flyctl/internal/command"
extensions_core "github.com/superfly/flyctl/internal/command/extensions/core"
"github.com/superfly/flyctl/internal/command/orgs"
"github.com/superfly/flyctl/internal/command/secrets"
"github.com/superfly/flyctl/internal/flag"
)

func create() (cmd *cobra.Command) {
const (
short = "Provision an Enveloop team"
long = short + "\n"
)

cmd = command.New("create", short, long, runCreate, command.RequireSession, command.LoadAppNameIfPresent)
flag.Add(cmd,
flag.App(),
flag.AppConfig(),
flag.Org(),
extensions_core.SharedFlags,
SharedFlags,
flag.String{
Name: "name",
Shorthand: "n",
Description: "The name of your AddOn",
},
)
return cmd
}

func runCreate(ctx context.Context) (err error) {
appName := appconfig.NameFromContext(ctx)
params := extensions_core.ExtensionParams{}

if appName != "" {
params.AppName = appName
} else {
org, err := orgs.OrgFromFlagOrSelect(ctx)
if err != nil {
return err
}

params.Organization = org
}

var options gql.AddOnOptions

params.Options = options
params.PlanID = "starter" // starter is the only plan for now
params.Provider = "enveloop"
extension, err := extensions_core.ProvisionExtension(ctx, params)
if err != nil {
return err
}

if extension.SetsSecrets {
err = secrets.DeploySecrets(ctx, gql.ToAppCompact(*extension.App), false, false)
}

return err
}
46 changes: 46 additions & 0 deletions internal/command/extensions/enveloop/dashboard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package enveloop

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 Enveloop 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.NoArgs
cmd.Args = cobra.MaximumNArgs(1)
return cmd
}

func runDashboard(ctx context.Context) (err error) {
org := flag.GetOrg(ctx)

if org != "" {
return extensions_core.OpenOrgDashboard(ctx, org, "enveloop")
}

extension, _, err := extensions_core.Discover(ctx, gql.AddOnTypeEnveloop)
if err != nil {
return err
}
return extensions_core.OpenDashboard(ctx, extension.Name)
}
72 changes: 72 additions & 0 deletions internal/command/extensions/enveloop/destroy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package enveloop

import (
"context"
"fmt"

"github.com/spf13/cobra"
fly "github.com/superfly/fly-go"
"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"
"github.com/superfly/flyctl/internal/prompt"
"github.com/superfly/flyctl/iostreams"
)

func destroy() (cmd *cobra.Command) {
const (
long = `Permanently destroy an Enveloop cluster`

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.AddOnTypeEnveloop)
if err != nil {
return err
}

if !flag.GetYes(ctx) {
const msg = "Destroying an Enveloop cluster is not reversible."
fmt.Fprintln(io.ErrOut, colorize.Red(msg))

switch confirmed, err := prompt.Confirmf(ctx, "Do you want to destroy the cluster named %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
}
}

client := fly.ClientFromContext(ctx).GenqClient
if _, err := gql.DeleteAddOn(ctx, client, extension.Name); err != nil {
return err
}

out := iostreams.FromContext(ctx).Out
fmt.Fprintf(out, "Your Enveloop cluster %s was destroyed\n", extension.Name)

return nil
}
21 changes: 21 additions & 0 deletions internal/command/extensions/enveloop/enveloop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package enveloop

import (
"github.com/spf13/cobra"
"github.com/superfly/flyctl/internal/command"
"github.com/superfly/flyctl/internal/flag"
)

func New() (cmd *cobra.Command) {
const (
short = "Provision and manage Enveloop teams"
long = short + "\n"
)

cmd = command.New("enveloop", short, long, nil)
cmd.AddCommand(create(), list(), plans(), dashboard(), destroy())

return cmd
}

var SharedFlags = flag.Set{}
53 changes: 53 additions & 0 deletions internal/command/extensions/enveloop/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package enveloop

import (
"context"

"github.com/spf13/cobra"
fly "github.com/superfly/fly-go"
"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"
"github.com/superfly/flyctl/internal/render"
"github.com/superfly/flyctl/iostreams"
)

func list() (cmd *cobra.Command) {
const (
long = `List your Enveloop clusters`
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) {
client := fly.ClientFromContext(ctx).GenqClient
response, err := gql.ListAddOns(ctx, client, "enveloop")
if err != nil {
return err
}

var rows [][]string
for _, extension := range response.AddOns.Nodes {
rows = append(rows, []string{
extension.Name,
extension.Organization.Slug,
// extension.addOnPlan.displayName,
})
}

out := iostreams.FromContext(ctx).Out
_ = render.Table(out, "", rows, "Name", "Team", "AddOn Name")

return nil
}
57 changes: 57 additions & 0 deletions internal/command/extensions/enveloop/plans.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package enveloop

import (
"context"
"fmt"

"github.com/spf13/cobra"
fly "github.com/superfly/fly-go"
"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"
"github.com/superfly/flyctl/internal/render"
"github.com/superfly/flyctl/iostreams"
)

func plans() (cmd *cobra.Command) {
const (
long = `List all Enveloop plans`
short = long
usage = "plans"
)

cmd = command.New(usage, short, long, runListPlans, command.RequireSession)
cmd.Aliases = []string{"ls"}

flag.Add(cmd,
flag.Org(),
extensions_core.SharedFlags,
)
return cmd
}

func runListPlans(ctx context.Context) (err error) {
client := fly.ClientFromContext(ctx).GenqClient
response, err := gql.ListAddOnPlans(ctx, client)
if err != nil {
return err
}

fmt.Printf("%+v\n", response)

var rows [][]string
for _, extension := range response.AddOnPlans.Nodes {
rows = append(rows, []string{
extension.Id,
extension.DisplayName,
extension.Description,
fmt.Sprintf("$%d / mo", extension.PricePerMonth),
})
}

out := iostreams.FromContext(ctx).Out
_ = render.Table(out, "", rows, "Id", "Name", "Description", "Price")

return nil
}
2 changes: 2 additions & 0 deletions internal/command/extensions/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/spf13/cobra"

"github.com/superfly/flyctl/internal/command"
"github.com/superfly/flyctl/internal/command/extensions/enveloop"
"github.com/superfly/flyctl/internal/command/extensions/kafka"
"github.com/superfly/flyctl/internal/command/extensions/kubernetes"
"github.com/superfly/flyctl/internal/command/extensions/planetscale"
Expand All @@ -30,6 +31,7 @@ func New() (cmd *cobra.Command) {
tigris.New(),
kubernetes.New(),
kafka.New(),
enveloop.New(),
)
return
}