diff --git a/api/casting.go b/api/casting.go index 582f95e594..44080d1b0f 100644 --- a/api/casting.go +++ b/api/casting.go @@ -1,13 +1,16 @@ package api +// IntPointer - Returns a pointer to an int func IntPointer(val int) *int { return &val } +// BoolPointer - Returns a pointer to a bool func BoolPointer(val bool) *bool { return &val } +// StringPointer - Returns a pointer to a string func StringPointer(val string) *string { return &val } diff --git a/api/resource_apps.go b/api/resource_apps.go index d53e248d09..9e869c4a83 100644 --- a/api/resource_apps.go +++ b/api/resource_apps.go @@ -1,6 +1,6 @@ package api -func (c *Client) GetApps() ([]App, error) { +func (client *Client) GetApps() ([]App, error) { query := ` query { apps(type: "container", first: 200) { @@ -21,9 +21,9 @@ func (c *Client) GetApps() ([]App, error) { } ` - req := c.NewRequest(query) + req := client.NewRequest(query) - data, err := c.Run(req) + data, err := client.Run(req) if err != nil { return nil, err } @@ -31,7 +31,7 @@ func (c *Client) GetApps() ([]App, error) { return data.Apps.Nodes, nil } -func (c *Client) GetAppID(appName string) (string, error) { +func (client *Client) GetAppID(appName string) (string, error) { query := ` query ($appName: String!) { app(name: $appName) { @@ -40,10 +40,10 @@ func (c *Client) GetAppID(appName string) (string, error) { } ` - req := c.NewRequest(query) + req := client.NewRequest(query) req.Var("appName", appName) - data, err := c.Run(req) + data, err := client.Run(req) if err != nil { return "", err } @@ -51,7 +51,7 @@ func (c *Client) GetAppID(appName string) (string, error) { return data.App.ID, nil } -func (c *Client) GetApp(appName string) (*App, error) { +func (client *Client) GetApp(appName string) (*App, error) { query := ` query ($appName: String!) { app(name: $appName) { @@ -86,10 +86,10 @@ func (c *Client) GetApp(appName string) (*App, error) { } ` - req := c.NewRequest(query) + req := client.NewRequest(query) req.Var("appName", appName) - data, err := c.Run(req) + data, err := client.Run(req) if err != nil { return nil, err } @@ -97,7 +97,7 @@ func (c *Client) GetApp(appName string) (*App, error) { return &data.App, nil } -func (c *Client) CreateApp(name string, orgId string) (*App, error) { +func (client *Client) CreateApp(name string, orgId string) (*App, error) { query := ` mutation($input: CreateAppInput!) { createApp(input: $input) { @@ -115,7 +115,7 @@ func (c *Client) CreateApp(name string, orgId string) (*App, error) { } ` - req := c.NewRequest(query) + req := client.NewRequest(query) req.Var("input", CreateAppInput{ Name: name, @@ -123,7 +123,7 @@ func (c *Client) CreateApp(name string, orgId string) (*App, error) { OrganizationID: orgId, }) - data, err := c.Run(req) + data, err := client.Run(req) if err != nil { return nil, err } @@ -171,3 +171,55 @@ func (client *Client) MoveApp(appName string, orgID string) (*App, error) { data, err := client.Run(req) return &data.App, err } + +// PauseApp - Send GQL mutation to pause app +func (client *Client) PauseApp(appName string) (*App, error) { + query := ` + mutation ($input: SuspendAppInput!) { + suspendApp(input: $input) { + app{ + id + name + status + version + hostname + } + } + } + ` + + req := client.NewRequest(query) + + req.Var("input", map[string]string{ + "appId": appName, + }) + + data, err := client.Run(req) + return &data.SuspendApp.App, err +} + +// ResumeApp - Send GQL mutation to pause app +func (client *Client) ResumeApp(appName string) (*App, error) { + query := ` + mutation ($input: ResumeAppInput!) { + resumeApp(input: $input) { + app{ + id + name + status + version + hostname + } + } + } + ` + + req := client.NewRequest(query) + + req.Var("input", map[string]string{ + "appId": appName, + }) + + data, err := client.Run(req) + return &data.ResumeApp.App, err +} diff --git a/api/types.go b/api/types.go index 8f983f3e4f..cb49269db6 100644 --- a/api/types.go +++ b/api/types.go @@ -78,6 +78,14 @@ type Query struct { App App Regions []Region } + + ResumeApp struct { + App App + } + + SuspendApp struct { + App App + } } type Definition map[string]interface{} diff --git a/cmd/apps.go b/cmd/apps.go index 0ffafc1485..f4b7e9ce2f 100644 --- a/cmd/apps.go +++ b/cmd/apps.go @@ -74,6 +74,12 @@ func newAppListCommand() *Command { Description: `The organization to move the app to`, }) + appsPauseStrings := docstrings.Get("apps.pause") + BuildCommand(cmd, runAppsPause, appsPauseStrings.Usage, appsPauseStrings.Short, appsPauseStrings.Long, os.Stdout, requireSession, requireAppName) + + appsResumeStrings := docstrings.Get("apps.resume") + BuildCommand(cmd, runAppsResume, appsResumeStrings.Usage, appsResumeStrings.Short, appsResumeStrings.Long, os.Stdout, requireSession, requireAppName) + return cmd } @@ -86,6 +92,26 @@ func runAppsList(ctx *CmdContext) error { return ctx.Render(&presenters.Apps{Apps: apps}) } +func runAppsPause(ctx *CmdContext) error { + app, err := ctx.Client.API().PauseApp(ctx.AppName) + if err != nil { + return err + } + fmt.Println(app) + + fmt.Println(aurora.Bold("App")) + return ctx.RenderEx(&presenters.AppInfo{App: *app}, presenters.Options{HideHeader: true, Vertical: true}) +} + +func runAppsResume(ctx *CmdContext) error { + app, err := ctx.Client.API().ResumeApp(ctx.AppName) + if err != nil { + return err + } + fmt.Println(aurora.Bold("App")) + return ctx.RenderEx(&presenters.AppInfo{App: *app}, presenters.Options{HideHeader: true, Vertical: true}) +} + func runDestroyApp(ctx *CmdContext) error { appName := ctx.Args[0] diff --git a/cmd/logs.go b/cmd/logs.go index 87d715b6d4..8093018e3b 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -73,7 +73,7 @@ func runLogs(ctx *CmdContext) error { } } - return nil + // This should not be reached } var maxBackoff float64 = 5000 diff --git a/cmd/root.go b/cmd/root.go index 6b7c3f2232..a0ec2853f1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,6 +14,7 @@ import ( "github.com/superfly/flyctl/internal/client" ) +// ErrAbort - Error generated when application aborts var ErrAbort = errors.New("abort") var flyctlClient *client.Client diff --git a/helpgen/flyctlhelp.toml b/helpgen/flyctlhelp.toml index ed770a9f9d..7e44ac9cd8 100644 --- a/helpgen/flyctlhelp.toml +++ b/helpgen/flyctlhelp.toml @@ -61,8 +61,22 @@ shortHelp="Move an App to another organization" longHelp="""The APPS MOVE command will move an application to another organization the current user belongs to. """ - - +[apps.pause] +usage="pause [APPNAME]" +shortHelp="Pause an application" +longHelp="""The APPS PAUSE command will pause an application. +All allocations will be deallocated leaving the application running nowhere. +It will continue to consume networking resources (IP address). See APPS RESUME +for details on restarting it. +""" +[apps.resume] +usage="resume [APPNAME]" +shortHelp="Resume an application" +longHelp="""The APPS Resume command will restart a previously paused application. +The application will resume with its original region pool and a min count of one +meaning there will be one running instance once restarted. Use SCALE SET MIN= to raise +the number of configured instances. +""" [auth] usage="auth"