func (c *moveContainerCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() url, err := cmd.GetURL(fmt.Sprintf("/docker/container/%s/move", context.Args[0])) if err != nil { return err } params := map[string]string{ "to": context.Args[1], } b, err := json.Marshal(params) if err != nil { return err } buffer := bytes.NewBuffer(b) request, err := http.NewRequest("POST", url, buffer) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { return err } w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *rebalanceContainersCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() if !c.dry && !c.Confirm(context, "Are you sure you want to rebalance containers?") { return nil } u, err := cmd.GetURL("/docker/containers/rebalance") if err != nil { return err } opts := rebalanceOptions{ Dry: c.dry, } if len(c.metadataFilter) > 0 { opts.MetadataFilter = c.metadataFilter } if len(c.appFilter) > 0 { opts.AppFilter = c.appFilter } v, err := form.EncodeToValues(&opts) if err != nil { return err } request, err := http.NewRequest("POST", u, bytes.NewBufferString(v.Encode())) if err != nil { return err } request.Header.Set("Content-Type", "application/x-www-form-urlencoded") response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *appRestart) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/restart?process=%s", appName, c.process)) if err != nil { return err } request, err := http.NewRequest("POST", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *appRun) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/run?once=%t", appName, c.once)) if err != nil { return err } b := strings.NewReader(strings.Join(context.Args, " ")) request, err := http.NewRequest("POST", url, b) if err != nil { return err } r, err := client.Do(request) if err != nil { return err } defer r.Body.Close() w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, r.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *appStart) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/start?process=%s", appName, c.process)) if err != nil { return err } request, err := http.NewRequest("POST", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() _, err = io.Copy(context.Stdout, response.Body) if err != nil { return err } return nil }
func (c *appPlanChange) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } plan := tsuruapp.Plan{Name: context.Args[0]} question := fmt.Sprintf("Are you sure you want to change the plan of the application %q to %q?", appName, plan.Name) if !c.Confirm(context, question) { return nil } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/plan", appName)) if err != nil { return err } b, err := json.Marshal(plan) if err != nil { return err } request, err := http.NewRequest("POST", url, bytes.NewReader(b)) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *unitRemove) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } val := url.Values{} val.Add("units", context.Args[0]) val.Add("process", c.process) url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/units?%s", appName, val.Encode())) if err != nil { return err } request, err := http.NewRequest("DELETE", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *rebalanceContainersCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() if !c.dry && !c.Confirm(context, "Are you sure you want to rebalance containers?") { return nil } url, err := cmd.GetURL("/docker/containers/rebalance") if err != nil { return err } params := map[string]interface{}{ "dry": fmt.Sprintf("%t", c.dry), } if len(c.metadataFilter) > 0 { params["metadataFilter"] = c.metadataFilter } if len(c.appFilter) > 0 { params["appFilter"] = c.appFilter } b, err := json.Marshal(params) if err != nil { return err } buffer := bytes.NewBuffer(b) request, err := http.NewRequest("POST", url, buffer) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *unitAdd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } u, err := cmd.GetURL(fmt.Sprintf("/apps/%s/units", appName)) if err != nil { return err } val := url.Values{} val.Add("units", context.Args[0]) val.Add("process", c.process) request, err := http.NewRequest("PUT", u, bytes.NewBufferString(val.Encode())) if err != nil { return err } request.Header.Add("Content-Type", "application/x-www-form-urlencoded") response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *moveContainerCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() url, err := cmd.GetURL(fmt.Sprintf("/docker/container/%s/move", context.Args[0])) if err != nil { return err } params := map[string]string{ "to": context.Args[1], } b, err := json.Marshal(params) if err != nil { return err } buffer := bytes.NewBuffer(b) request, err := http.NewRequest("POST", url, buffer) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *autoScaleRunCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() if !c.Confirm(context, "Are you sure you want to run auto scaling checks?") { return nil } u, err := cmd.GetURL("/docker/autoscale/run") if err != nil { return err } request, err := http.NewRequest("POST", u, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return errors.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *unitAdd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } u, err := cmd.GetURL(fmt.Sprintf("/apps/%s/units", appName)) if err != nil { return err } val := url.Values{} val.Add("units", context.Args[0]) val.Add("process", c.process) request, err := http.NewRequest("PUT", u, bytes.NewBufferString(val.Encode())) if err != nil { return err } request.Header.Add("Content-Type", "application/x-www-form-urlencoded") response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *envUnset) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/env", appName)) if err != nil { return err } var buf bytes.Buffer json.NewEncoder(&buf).Encode(context.Args) request, err := http.NewRequest("DELETE", url, &buf) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (su *serviceUnbind) Run(ctx *cmd.Context, client *cmd.Client) error { ctx.RawOutput() appName, err := su.Guess() if err != nil { return err } instanceName := ctx.Args[0] url, err := cmd.GetURL("/services/instances/" + instanceName + "/" + appName) if err != nil { return err } request, err := http.NewRequest("DELETE", url, nil) if err != nil { return err } resp, err := client.Do(request) if err != nil { return err } defer resp.Body.Close() w := tsuruIo.NewStreamWriter(ctx.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, resp.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (p *platformUpdate) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() name := context.Args[0] if p.disable && p.enable { return errors.New("Conflicting options: --enable and --disable\n") } if !p.disable && !p.enable && p.dockerfile == "" { return errors.New("Flag is required") } disable := "" if p.enable { disable = "false" } if p.disable { disable = "true" } body := fmt.Sprintf("a=1&dockerfile=%s", p.dockerfile) url, err := cmd.GetURL(fmt.Sprintf("/platforms/%s?disabled=%s", name, disable)) request, err := http.NewRequest("PUT", url, strings.NewReader(body)) if err != nil { return err } request.Header.Add("Content-Type", "application/x-www-form-urlencoded") response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *plugin) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() pluginName := context.Args[0] pluginPath := cmd.JoinWithUserDir(".tsuru", "plugins", pluginName) target, err := cmd.GetURL("/") if err != nil { return err } token, err := cmd.ReadToken() if err != nil { return err } envs := os.Environ() tsuruEnvs := []string{ "TSURU_TARGET=" + target, "TSURU_TOKEN=" + token, "TSURU_PLUGIN_NAME=" + pluginName, } envs = append(envs, tsuruEnvs...) opts := exec.ExecuteOptions{ Cmd: pluginPath, Args: context.Args[1:], Stdout: context.Stdout, Stderr: context.Stderr, Stdin: context.Stdin, Envs: envs, } return executor().Execute(opts) }
func (c *dockerLogUpdate) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() if c.restart { extra := "" if c.pool != "" { extra = fmt.Sprintf(" running on pool %s", c.pool) } msg := fmt.Sprintf("Are you sure you want to restart all apps%s?", extra) if !c.Confirm(context, msg) { return nil } } url, err := cmd.GetURL("/docker/logs") if err != nil { return err } envList := []provision.Entry{ {Name: "log-driver", Value: c.logDriver}, } for name, value := range c.logOpts { envList = append(envList, provision.Entry{Name: name, Value: value}) } conf := provision.ScopedConfig{} if c.pool == "" { conf.Envs = envList } else { conf.Pools = []provision.PoolEntry{{ Name: c.pool, Envs: envList, }} } b, err := json.Marshal(logsSetData{ Restart: c.restart, Config: conf, }) if err != nil { return err } buffer := bytes.NewBuffer(b) request, err := http.NewRequest("POST", url, buffer) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() return cmd.StreamJSONResponse(context.Stdout, response) }
func (createRootUserCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() scheme, err := config.GetString("auth:scheme") if err != nil { scheme = "native" } app.AuthScheme, err = auth.GetScheme(scheme) if err != nil { return err } email := context.Args[0] user, err := auth.GetUserByEmail(email) if err == nil { err = addSuperRole(user) if err != nil { return err } fmt.Fprintln(context.Stdout, "Root user successfully updated.") } var confirm, password string if scheme == "native" { fmt.Fprint(context.Stdout, "Password: "******"\nConfirm: ") confirm, err = cmd.PasswordFromReader(context.Stdin) if err != nil { return err } fmt.Fprintln(context.Stdout) if password != confirm { return errors.New("Passwords didn't match.") } } user, err = app.AuthScheme.Create(&auth.User{ Email: email, Password: password, }) if err != nil { return err } err = addSuperRole(user) if err != nil { return err } fmt.Fprintln(context.Stdout, "Root user successfully created.") return nil }
func (c *envSet) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } raw := strings.Join(context.Args, "\n") regex := regexp.MustCompile(`(\w+=[^\n]+)(\n|$)`) decls := regex.FindAllStringSubmatch(raw, -1) if len(decls) < 1 || len(decls) != len(context.Args) { return errors.New(envSetValidationMessage) } variables := make(map[string]string, len(decls)) for _, v := range decls { parts := strings.SplitN(v[1], "=", 2) variables[parts[0]] = parts[1] } var buf bytes.Buffer json.NewEncoder(&buf).Encode(variables) url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/env", appName)) if err != nil { return err } if c.private { url += "?private=1" } request, err := http.NewRequest("POST", url, &buf) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *UpgradeCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() url, err := cmd.GetURL("/docker/bs/upgrade") if err != nil { return err } request, err := http.NewRequest("POST", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *rebalanceContainersCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() if !c.dry && !c.Confirm(context, "Are you sure you want to rebalance containers?") { return nil } url, err := cmd.GetURL("/docker/containers/rebalance") if err != nil { return err } params := map[string]interface{}{ "dry": fmt.Sprintf("%t", c.dry), } if len(c.metadataFilter) > 0 { params["metadataFilter"] = c.metadataFilter } if len(c.appFilter) > 0 { params["appFilter"] = c.appFilter } b, err := json.Marshal(params) if err != nil { return err } buffer := bytes.NewBuffer(b) request, err := http.NewRequest("POST", url, buffer) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { return err } w := tsuruIo.NewStreamWriter(context.Stdout, nil) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } if err != nil { return err } unparsed := w.Remaining() if len(unparsed) > 0 { return fmt.Errorf("unparsed message error: %s", string(unparsed)) } return nil }
func (c *appUpdate) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName := context.Args[0] var param app if c.plan != "" { plan := tsuruapp.Plan{Name: c.plan} question := fmt.Sprintf("Are you sure you want to change the plan of the application %q to %q?", appName, plan.Name) if !c.Confirm(context, question) { return nil } param.Plan = plan } param.Description = c.description param.Pool = c.pool param.TeamOwner = c.teamOwner b, err := json.Marshal(param) if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s", appName)) if err != nil { return err } request, err := http.NewRequest("POST", url, bytes.NewBuffer(b)) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { e := err.(*tsuruerr.HTTP) if e.Code == http.StatusBadRequest { return errors.New("You must set a flag. Use the 'app-update --help' command for more information.") } return err } err = cmd.StreamJSONResponse(context.Stdout, response) if err != nil { return err } fmt.Fprintf(context.Stdout, "App %q has been updated!\n", appName) fmt.Fprintln(context.Stdout, "Use app-info to check the status of the app and its units.") return nil }
func (c *moveContainerCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() u, err := cmd.GetURL(fmt.Sprintf("/docker/container/%s/move", context.Args[0])) if err != nil { return err } v := url.Values{} v.Set("to", context.Args[1]) request, err := http.NewRequest("POST", u, bytes.NewBufferString(v.Encode())) if err != nil { return err } request.Header.Set("Content-Type", "application/x-www-form-urlencoded") response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *appLog) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/log?lines=%d", appName, c.lines)) if err != nil { return err } if c.source != "" { url = fmt.Sprintf("%s&source=%s", url, c.source) } if c.unit != "" { url = fmt.Sprintf("%s&unit=%s", url, c.unit) } if c.follow { url += "&follow=1" } request, err := http.NewRequest("GET", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } if response.StatusCode == http.StatusNoContent { return nil } defer response.Body.Close() w := tsuruIo.NewStreamWriter(context.Stdout, logFormatter{ noDate: c.noDate, noSource: c.noSource, }) for n := int64(1); n > 0 && err == nil; n, err = io.Copy(w, response.Body) { } unparsed := w.Remaining() if len(unparsed) > 0 { fmt.Fprintf(context.Stdout, "Error: %s", string(unparsed)) } return nil }
func (c *EnvSetCmd) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() url, err := cmd.GetURL("/docker/bs/env") if err != nil { return err } var envList []provision.Entry for _, arg := range context.Args { parts := strings.SplitN(arg, "=", 2) if len(parts) < 2 { return fmt.Errorf("invalid variable values") } if parts[0] == "" { return fmt.Errorf("invalid variable values") } envList = append(envList, provision.Entry{Name: parts[0], Value: parts[1]}) } conf := provision.ScopedConfig{} if c.pool == "" { conf.Envs = envList } else { conf.Pools = []provision.PoolEntry{{ Name: c.pool, Envs: envList, }} } b, err := json.Marshal(conf) if err != nil { return err } buffer := bytes.NewBuffer(b) request, err := http.NewRequest("POST", url, buffer) if err != nil { return err } request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *appRestart) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s/restart?process=%s", appName, c.process)) if err != nil { return err } request, err := http.NewRequest("POST", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *userCreate) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() url, err := cmd.GetURL("/users") if err != nil { return err } email := context.Args[0] fmt.Fprint(context.Stdout, "Password: "******"\nConfirm: ") confirm, err := cmd.PasswordFromReader(context.Stdin) if err != nil { return err } fmt.Fprintln(context.Stdout) if password != confirm { return errors.New("Passwords didn't match.") } b := bytes.NewBufferString(`{"email":"` + email + `", "password":"******"}`) request, err := http.NewRequest("POST", url, b) if err != nil { return err } resp, err := client.Do(request) if resp != nil { if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusMethodNotAllowed { return errors.New("User creation is disabled.") } } if err != nil { return err } fmt.Fprintf(context.Stdout, `User "%s" successfully created!`+"\n", email) return nil }
func (c *dockerLogUpdate) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() if c.restart { extra := "" if c.pool != "" { extra = fmt.Sprintf(" running on pool %s", c.pool) } msg := fmt.Sprintf("Are you sure you want to restart all apps%s?", extra) if !c.Confirm(context, msg) { return nil } } u, err := cmd.GetURL("/docker/logs") if err != nil { return err } conf := container.DockerLogConfig{ Driver: c.logDriver, LogOpts: map[string]string(c.logOpts), } values, err := form.EncodeToValues(conf) if err != nil { return err } values.Set("pool", c.pool) values.Set("restart", strconv.FormatBool(c.restart)) reader := strings.NewReader(values.Encode()) request, err := http.NewRequest("POST", u, reader) if err != nil { return err } request.Header.Set("Content-Type", "application/x-www-form-urlencoded") response, err := client.Do(request) if err != nil { return err } defer response.Body.Close() return cmd.StreamJSONResponse(context.Stdout, response) }
func (c *NodeContainerDelete) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() msg := fmt.Sprintf("Are you sure you want to remove node container %q", context.Args[0]) if c.pool != "" { msg += fmt.Sprintf(" from pool %q", c.pool) } else { msg += " from ALL pools" } if c.kill { msg += " and KILL it" } msg += "?" if !c.Confirm(context, msg) { return nil } val := url.Values{} val.Set("pool", c.pool) val.Set("kill", strconv.FormatBool(c.kill)) u, err := cmd.GetURL(fmt.Sprintf("/docker/nodecontainers/%s?%s", context.Args[0], val.Encode())) if err != nil { return err } request, err := http.NewRequest("DELETE", u, nil) if err != nil { return err } rsp, err := client.Do(request) if err != nil { return err } defer rsp.Body.Close() err = cmd.StreamJSONResponse(context.Stdout, rsp) if err != nil { return err } fmt.Fprintln(context.Stdout, "Node container successfully deleted.") return nil }
func (c *appRemove) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() appName := c.Flags().Lookup("app").Value.String() if appName == "" { return errors.New("Please use the -a/--app flag to specify which app you want to remove.") } if !c.Confirm(context, fmt.Sprintf(`Are you sure you want to remove app "%s"?`, appName)) { return nil } url, err := cmd.GetURL(fmt.Sprintf("/apps/%s", appName)) if err != nil { return err } request, err := http.NewRequest("DELETE", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } return cmd.StreamJSONResponse(context.Stdout, response) }