Exemple #1
0
// Execute an API request and return its response/error
func (req *APIRequest) Do() (*http.Response, error) {
	err := req.FillDefaultValues()
	if err != nil {
		return nil, errgo.Mask(err, errgo.Any)
	}

	endpoint := req.URL + req.Endpoint

	// Execute the HTTP request according to the HTTP method
	switch req.Method {
	case "PATCH":
		fallthrough
	case "POST":
		fallthrough
	case "WITH_BODY":
		buffer, err := json.Marshal(req.Params)
		if err != nil {
			return nil, errgo.Mask(err, errgo.Any)
		}
		reader := bytes.NewReader(buffer)
		req.HTTPRequest, err = http.NewRequest(req.Method, endpoint, reader)
		if err != nil {
			return nil, errgo.Mask(err, errgo.Any)
		}
	case "GET", "DELETE":
		values, err := req.BuildQueryFromParams()
		if err != nil {
			return nil, errgo.Mask(err, errgo.Any)
		}
		endpoint = fmt.Sprintf("%s?%s", endpoint, values.Encode())
		req.HTTPRequest, err = http.NewRequest(req.Method, endpoint, nil)
		if err != nil {
			return nil, errgo.Mask(err, errgo.Any)
		}
	}

	debug.Printf("[API] %v %v\n", req.HTTPRequest.Method, req.HTTPRequest.URL)
	debug.Printf(io.Indent(fmt.Sprintf("Headers: %v", req.HTTPRequest.Header), 6))
	debug.Printf(io.Indent("Params : %v", 6), req.Params)

	req.HTTPRequest.SetBasicAuth("", req.Token)
	res, err := httpclient.Do(req.HTTPRequest)
	if err != nil {
		fmt.Printf("Fail to query %s: %v\n", req.HTTPRequest.Host, err)
		os.Exit(1)
	}

	if req.Expected.Contains(res.StatusCode) {
		return res, nil
	}

	return nil, NewRequestFailedError(res, req)
}
Exemple #2
0
func List() error {
	apps, err := scalingo.AppsList()
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	if len(apps) == 0 {
		fmt.Println(io.Indent("\nYou haven't created any app yet, create your first application using:\n→ scalingo create <app_name>\n", 2))
		return nil
	}

	t := tablewriter.NewWriter(os.Stdout)
	t.SetHeader([]string{"Name", "Role", "Owner"})

	for _, app := range apps {
		if app.Owner.Email == scalingo.CurrentUser.Email {
			t.Append([]string{app.Name, "owner", "-"})
		} else {
			t.Append([]string{app.Name, "collaborator", fmt.Sprintf("%s <%s>", app.Owner.Username, app.Owner.Email)})
		}
	}
	t.Render()

	return nil
}
Exemple #3
0
func Scale(app string, sync bool, types []string) error {
	var size string
	scaleParams := &scalingo.AppsScaleParams{}

	for _, t := range types {
		splitT := strings.Split(t, ":")
		if len(splitT) != 2 && len(splitT) != 3 {
			return errgo.Newf("%s is invalid, format is <type>:<amount>[:<size>]", t)
		}
		typeName, typeAmount := splitT[0], splitT[1]
		if len(splitT) == 3 {
			size = splitT[2]
		}

		amount, err := strconv.ParseInt(typeAmount, 10, 32)
		if err != nil {
			return errgo.Newf("%s in %s should be an integer", typeAmount, t)
		}
		scaleParams.Containers = append(scaleParams.Containers, scalingo.Container{Name: typeName, Amount: int(amount), Size: size})
	}

	res, err := scalingo.AppsScale(app, scaleParams)
	if err != nil {
		return errgo.Mask(err)
	}
	defer res.Body.Close()

	if res.StatusCode == 422 {
		var scaleUnprocessableEntity ScaleUnprocessableEntity
		err = scalingo.ParseJSON(res, &scaleUnprocessableEntity)
		if err != nil {
			return errgo.Mask(err)
		}
		return scaleUnprocessableEntity
	}

	var scaleRes ScaleRes
	err = scalingo.ParseJSON(res, &scaleRes)
	if err != nil {
		return errgo.Mask(err)
	}

	fmt.Printf("Your application is being scaled to:\n")
	for _, ct := range scaleRes.Containers {
		fmt.Println(io.Indent(fmt.Sprintf("%s: %d - %s", ct.Name, ct.Amount, ct.Size), 2))
	}

	if !sync {
		return nil
	}

	err = handleOperation(app, res)
	if err != nil {
		return errgo.Mask(err)
	}

	fmt.Println("Your application has been scaled.")
	return nil
}
Exemple #4
0
func errorQuit(err error) {
	if errgo.Cause(err) == api.LoginAbortedErr {
		fmt.Printf("... %v\n", err)
		os.Exit(1)
	}

	if api.IsRequestFailedError(errgo.Cause(err)) {
		code := errgo.Cause(err).(*api.RequestFailedError).Code
		if code == 401 {
			session.DestroyToken()
		}
	}

	newReportError(err).Report()
	rollbar.Wait()
	io.Error("An error occured:")
	fmt.Println(io.Indent(err.Error(), 7))
	os.Exit(1)
}
Exemple #5
0
func Scale(app string, sync bool, types []string) error {
	var (
		size        string
		containers  []scalingo.Container
		modificator byte
		err         error
	)

	scaleParams := &scalingo.AppsScaleParams{}

	for _, t := range types {
		splitT := strings.Split(t, ":")
		if len(splitT) != 2 && len(splitT) != 3 {
			return errgo.Newf("%s is invalid, format is <type>:<amount>[:<size>]", t)
		}
		typeName, typeAmount := splitT[0], splitT[1]
		if len(splitT) == 3 {
			size = splitT[2]
		}

		if typeAmount[0] == '-' || typeAmount[0] == '+' {
			modificator = typeAmount[0]
			typeAmount = typeAmount[1:]
			if size != "" {
				return errgo.Newf("%s is invalid, can't use relative modificator with size, change the size first", t)
			}
			if containers == nil {
				c := config.ScalingoClient()
				containers, err = c.AppsPs(app)
				if err != nil {
					return errgo.Notef(err, "fail to get list of running containers")
				}
				debug.Println("get container list", containers)
			}
		}

		amount, err := strconv.ParseInt(typeAmount, 10, 32)
		if err != nil {
			return errgo.Newf("%s in %s should be an integer", typeAmount, t)
		}

		newContainerConfig := scalingo.Container{Name: typeName, Size: size}
		if modificator != 0 {
			for _, container := range containers {
				if container.Name == typeName {
					if modificator == '-' {
						newContainerConfig.Amount = container.Amount - int(amount)
					} else if modificator == '+' {
						newContainerConfig.Amount = container.Amount + int(amount)
					}
					break
				}
			}
		} else {
			newContainerConfig.Amount = int(amount)
		}

		scaleParams.Containers = append(scaleParams.Containers, newContainerConfig)
	}

	c := config.ScalingoClient()
	res, err := c.AppsScale(app, scaleParams)
	if err != nil {
		return errgo.Mask(err)
	}
	defer res.Body.Close()

	var scaleRes ScaleRes
	err = scalingo.ParseJSON(res, &scaleRes)
	if err != nil {
		return errgo.Mask(err)
	}

	fmt.Printf("Your application is being scaled to:\n")
	for _, ct := range scaleRes.Containers {
		fmt.Println(io.Indent(fmt.Sprintf("%s: %d - %s", ct.Name, ct.Amount, ct.Size), 2))
	}

	if !sync {
		return nil
	}

	err = handleOperation(app, res)
	if err != nil {
		return errgo.Mask(err)
	}

	fmt.Println("Your application has been scaled.")
	return nil
}