Пример #1
0
func (s *S) TestNodeContainerCreateInvalid(c *check.C) {
	reader := strings.NewReader("")
	request, err := http.NewRequest("POST", "/1.2/nodecontainers", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusBadRequest)
	c.Assert(recorder.Body.String(), check.Matches, "node container config name cannot be empty\n")
	values, err := form.EncodeToValues(nodecontainer.NodeContainerConfig{Name: ""})
	c.Assert(err, check.IsNil)
	reader = strings.NewReader(values.Encode())
	request, err = http.NewRequest("POST", "/1.2/nodecontainers", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder = httptest.NewRecorder()
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusBadRequest)
	c.Assert(recorder.Body.String(), check.Matches, "node container config name cannot be empty\n")
	values, err = form.EncodeToValues(nodecontainer.NodeContainerConfig{Name: "x1"})
	c.Assert(err, check.IsNil)
	reader = strings.NewReader(values.Encode())
	request, err = http.NewRequest("POST", "/1.2/nodecontainers", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder = httptest.NewRecorder()
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusBadRequest)
	c.Assert(recorder.Body.String(), check.Matches, "node container config image cannot be empty\n")
}
Пример #2
0
func (s *S) TestUpdateNodeEnableAndDisableCantBeDone(c *check.C) {
	err := s.provisioner.AddNode(provision.AddNodeOptions{
		Address: "localhost:1999",
	})
	c.Assert(err, check.IsNil)
	opts := provision.AddPoolOptions{Name: "pool1"}
	err = provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	defer provision.RemovePool("pool1")
	params := provision.UpdateNodeOptions{
		Address: "localhost:1999",
		Enable:  true,
		Disable: true,
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/node", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusBadRequest)
	c.Assert(recorder.Body.String(), check.Equals, "A node can't be enabled and disabled simultaneously.\n")
}
Пример #3
0
func (s *HandlersSuite) TestAutoScaleSetRuleInvalidRule(c *check.C) {
	rule := autoScaleRule{MetadataFilter: "pool1", Enabled: true, ScaleDownRatio: 0.9, MaxMemoryRatio: 2.0}
	v, err := form.EncodeToValues(&rule)
	c.Assert(err, check.IsNil)
	body := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("POST", "/docker/autoscale/rules", body)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := api.RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusInternalServerError)
	c.Assert(recorder.Body.String(), check.Matches, "(?s).*invalid rule, scale down ratio needs to be greater than 1.0, got 0.9.*")
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypePool, Value: "pool1"},
		Owner:  s.token.GetUserName(),
		Kind:   "node.autoscale.update",
		StartCustomData: []map[string]interface{}{
			{"name": "MetadataFilter", "value": "pool1"},
			{"name": "Enabled", "value": "true"},
			{"name": "ScaleDownRatio", "value": "0.9"},
			{"name": "MaxMemoryRatio", "value": "2"},
		},
		ErrorMatches: `.*invalid rule, scale down ratio needs to be greater than 1.0, got 0.9.*`,
	}, eventtest.HasEvent)
}
Пример #4
0
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)
}
Пример #5
0
func (s *S) TestUpdateNodeEnableNodeHandler(c *check.C) {
	err := s.provisioner.AddNode(provision.AddNodeOptions{
		Address: "localhost:1999",
	})
	c.Assert(err, check.IsNil)
	opts := provision.AddPoolOptions{Name: "pool1"}
	err = provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	defer provision.RemovePool("pool1")
	params := provision.UpdateNodeOptions{
		Address: "localhost:1999",
		Enable:  true,
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/node", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	nodes, err := s.provisioner.ListNodes(nil)
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 1)
	c.Assert(nodes[0].Status(), check.Equals, "enabled")
}
Пример #6
0
// WithForm sets Content-Type header to "application/x-www-form-urlencoded"
// or (if WithMultipart() was called) "multipart/form-data", converts given
// object to url.Values using github.com/ajg/form, and adds it to request body.
//
// Various object types are supported, including maps and structs. Structs may
// contain "form" struct tag, similar to "json" struct tag for json.Marshal().
// See https://github.com/ajg/form for details.
//
// Multiple WithForm(), WithFormField(), and WithFile() calls may be combined.
// If WithMultipart() is called, it should be called first.
//
// Example:
//  type MyForm struct {
//      Foo int `form:"foo"`
//  }
//
//  req := NewRequest(config, "PUT", "http://example.com/path")
//  req.WithForm(MyForm{Foo: 123})
//
//  req := NewRequest(config, "PUT", "http://example.com/path")
//  req.WithForm(map[string]interface{}{"foo": 123})
func (r *Request) WithForm(object interface{}) *Request {
	f, err := form.EncodeToValues(object)
	if err != nil {
		r.chain.fail(err.Error())
		return r
	}

	if r.multipart != nil {
		r.setType("WithForm", "multipart/form-data", false)

		var keys []string
		for k := range f {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		for _, k := range keys {
			if err := r.multipart.WriteField(k, f[k][0]); err != nil {
				r.chain.fail(err.Error())
				return r
			}
		}
	} else {
		r.setType("WithForm", "application/x-www-form-urlencoded", false)

		if r.form == nil {
			r.form = make(url.Values)
		}
		for k, v := range f {
			r.form[k] = append(r.form[k], v...)
		}
	}

	return r
}
Пример #7
0
func (s *S) TestNodeContainerUpdateLimited(c *check.C) {
	err := nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{Name: "c1", Config: docker.Config{Image: "img1"}})
	c.Assert(err, check.IsNil)
	t := userWithPermission(c, permission.Permission{
		Scheme:  permission.PermNodecontainerUpdate,
		Context: permission.Context(permission.CtxPool, "p1"),
	})
	values, err := form.EncodeToValues(nodecontainer.NodeContainerConfig{Name: "c1"})
	c.Assert(err, check.IsNil)
	reader := strings.NewReader(values.Encode())
	request, err := http.NewRequest("POST", "/1.2/nodecontainers/c1", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+t.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusForbidden)
	values.Set("pool", "p1")
	reader = strings.NewReader(values.Encode())
	request, err = http.NewRequest("POST", "/1.2/nodecontainers/c1", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+t.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder = httptest.NewRecorder()
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
}
Пример #8
0
// WithQueryObject adds multiple query parameters to request URL.
//
// object is converted to query string using github.com/google/go-querystring
// if it's a struct or pointer to struct, or github.com/ajg/form otherwise.
//
// Various object types are supported. Structs may contain "url" struct tag,
// similar to "json" struct tag for json.Marshal().
//
// Example:
//  type MyURL struct {
//      A int    `url:"a"`
//      B string `url:"b"`
//  }
//
//  req := NewRequest(config, "PUT", "http://example.com/path")
//  req.WithQueryObject(MyURL{A: 123, B: "foo"})
//  // URL is now http://example.com/path?a=123&b=foo
//
//  req := NewRequest(config, "PUT", "http://example.com/path")
//  req.WithQueryObject(map[string]interface{}{"a": 123, "b": "foo"})
//  // URL is now http://example.com/path?a=123&b=foo
func (r *Request) WithQueryObject(object interface{}) *Request {
	if object == nil {
		return r
	}
	var (
		q   url.Values
		err error
	)
	if reflect.Indirect(reflect.ValueOf(object)).Kind() == reflect.Struct {
		q, err = query.Values(object)
		if err != nil {
			r.chain.fail(err.Error())
			return r
		}
	} else {
		q, err = form.EncodeToValues(object)
		if err != nil {
			r.chain.fail(err.Error())
			return r
		}
	}
	if r.query == nil {
		r.query = make(url.Values)
	}
	for k, v := range q {
		r.query[k] = append(r.query[k], v...)
	}
	return r
}
Пример #9
0
Файл: cmd.go Проект: tsuru/tsuru
func (c *autoScaleSetRuleCmd) Run(context *cmd.Context, client *cmd.Client) error {
	if (c.enable && c.disable) || (!c.enable && !c.disable) {
		return errors.New("either --disable or --enable must be set")
	}
	rule := autoScaleRule{
		MetadataFilter:    c.filterValue,
		MaxContainerCount: c.maxContainerCount,
		MaxMemoryRatio:    float32(c.maxMemoryRatio),
		ScaleDownRatio:    float32(c.scaleDownRatio),
		PreventRebalance:  c.noRebalanceOnScale,
		Enabled:           c.enable,
	}
	val, err := form.EncodeToValues(rule)
	if err != nil {
		return err
	}
	body := strings.NewReader(val.Encode())
	u, err := cmd.GetURL("/docker/autoscale/rules")
	if err != nil {
		return err
	}
	req, err := http.NewRequest("POST", u, body)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	_, err = client.Do(req)
	if err != nil {
		return err
	}
	fmt.Fprintln(context.Stdout, "Rule successfully defined.")
	return nil
}
Пример #10
0
func (s *S) TestAddNodeHandlerExisting(c *check.C) {
	opts := provision.AddPoolOptions{Name: "pool1"}
	err := provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	defer provision.RemovePool("pool1")
	serverAddr := "http://mysrv1"
	params := provision.AddNodeOptions{
		Register: true,
		Metadata: map[string]string{
			"address": serverAddr,
			"pool":    "pool1",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	req, err := http.NewRequest("POST", "/1.2/node", strings.NewReader(v.Encode()))
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec := httptest.NewRecorder()
	m := RunServer(true)
	m.ServeHTTP(rec, req)
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
	req, err = http.NewRequest("POST", "/1.2/node", strings.NewReader(v.Encode()))
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec = httptest.NewRecorder()
	m.ServeHTTP(rec, req)
	var result map[string]string
	err = json.NewDecoder(rec.Body).Decode(&result)
	c.Assert(err, check.IsNil)
	c.Assert(result["Error"], check.Equals, "node with address \"http://mysrv1\" already exists in provisioner \"fake\"")
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
}
Пример #11
0
// RequestForm makes an HTTP request with the given interface being encoded as
// form data.
func (c *Client) RequestForm(verb, p string, i interface{}, ro *RequestOptions) (*http.Response, error) {
	values, err := form.EncodeToValues(i)
	if err != nil {
		return nil, err
	}

	if ro == nil {
		ro = new(RequestOptions)
	}

	if ro.Headers == nil {
		ro.Headers = make(map[string]string)
	}
	ro.Headers["Content-Type"] = "application/x-www-form-urlencoded"

	// There is a super-jank implementation in the form library where fields with
	// a "dot" are replaced with "/.". That is then URL encoded and Fastly just
	// dies. We fix that here.
	body := strings.Replace(values.Encode(), "%5C.", ".", -1)

	ro.Body = strings.NewReader(body)
	ro.BodyLength = int64(len(body))

	return c.Request(verb, p, ro)
}
Пример #12
0
func (s *S) TestAddNodeHandlerWithInvalidURLAddress(c *check.C) {
	opts := provision.AddPoolOptions{Name: "pool1"}
	err := provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	params := provision.AddNodeOptions{
		Register: true,
		Metadata: map[string]string{
			"address": "/invalid",
			"pool":    "pool1",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	req, err := http.NewRequest("POST", "/node", b)
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec := httptest.NewRecorder()
	m := RunServer(true)
	m.ServeHTTP(rec, req)
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
	var result map[string]string
	err = json.NewDecoder(rec.Body).Decode(&result)
	c.Assert(err, check.IsNil)
	c.Assert(result["Error"], check.Equals, "Invalid address url: host cannot be empty")
	params = provision.AddNodeOptions{
		Register: true,
		Metadata: map[string]string{
			"address": "xxx://abc/invalid",
			"pool":    "pool1",
		},
	}
	v, err = form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b = strings.NewReader(v.Encode())
	req, err = http.NewRequest("POST", "/node", b)
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec = httptest.NewRecorder()
	m.ServeHTTP(rec, req)
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
	err = json.NewDecoder(rec.Body).Decode(&result)
	c.Assert(err, check.IsNil)
	c.Assert(result["Error"], check.Equals, "Invalid address url: scheme must be http[s]")
}
Пример #13
0
func (o *HTTP) encodeToForm(record intf.Record) string {
	values, err := form.EncodeToValues(record)
	if err != nil {
		Error("Form Error %s", err)
	}

	return values.Encode()
}
Пример #14
0
func (s *S) TestRebalanceContainersDryBodyHandler(c *check.C) {
	p, err := s.startMultipleServersCluster()
	c.Assert(err, check.IsNil)
	mainDockerProvisioner = p
	err = s.newFakeImage(p, "tsuru/app-myapp", nil)
	c.Assert(err, check.IsNil)
	appInstance := provisiontest.NewFakeApp("myapp", "python", 0)
	defer p.Destroy(appInstance)
	p.Provision(appInstance)
	coll := p.Collection()
	defer coll.Close()
	coll.Insert(container.Container{ID: "container-id", AppName: appInstance.GetName(), Version: "container-version", Image: "tsuru/python", ProcessName: "web"})
	defer coll.RemoveAll(bson.M{"appname": appInstance.GetName()})
	imageId, err := image.AppCurrentImageName(appInstance.GetName())
	c.Assert(err, check.IsNil)
	units, err := addContainersWithHost(&changeUnitsPipelineArgs{
		toHost:      "localhost",
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 5}},
		app:         appInstance,
		imageId:     imageId,
		provisioner: p,
	})
	c.Assert(err, check.IsNil)
	appStruct := &app.App{
		Name:     appInstance.GetName(),
		Platform: appInstance.GetPlatform(),
		Pool:     "test-default",
	}
	err = s.storage.Apps().Insert(appStruct)
	c.Assert(err, check.IsNil)
	err = s.storage.Apps().Update(
		bson.M{"name": appStruct.Name},
		bson.M{"$set": bson.M{"units": units}},
	)
	c.Assert(err, check.IsNil)
	recorder := httptest.NewRecorder()
	opts := rebalanceOptions{Dry: true}
	v, err := form.EncodeToValues(&opts)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	request, err := http.NewRequest("POST", "/docker/containers/rebalance", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	server := api.RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	body, err := ioutil.ReadAll(recorder.Body)
	c.Assert(err, check.IsNil)
	validJson := fmt.Sprintf("[%s]", strings.Replace(strings.Trim(string(body), "\n "), "\n", ",", -1))
	var result []tsuruIo.SimpleJsonMessage
	err = json.Unmarshal([]byte(validJson), &result)
	c.Assert(err, check.IsNil)
	c.Assert(result, check.HasLen, 8)
	c.Assert(result[0].Message, check.Equals, "Rebalancing 6 units...\n")
	c.Assert(result[1].Message, check.Matches, "(?s)Would move unit .*")
	c.Assert(result[7].Message, check.Equals, "Containers successfully rebalanced!\n")
}
Пример #15
0
// FormData ecodes from data from an interface{} and converts to an `io.Reader`.
func FormData(data interface{}) (io.Reader, error) {
	values, err := form.EncodeToValues(data)
	if err != nil {
		return nil, err
	}

	body := bytes.NewBufferString(values.Encode())
	return body, nil
}
Пример #16
0
func toReader(body interface{}) io.Reader {
	modelType := reflect.TypeOf((*encodable)(nil)).Elem()
	s := reflect.ValueOf(body)
	t := s.Type()
	if !t.Implements(modelType) {
		body, _ = form.EncodeToValues(body)
	}
	return strings.NewReader(body.(encodable).Encode())
}
Пример #17
0
func (s *S) TestTemplateUpdate(c *check.C) {
	iaas.RegisterIaasProvider("my-iaas", newTestIaaS)
	tpl1 := iaas.Template{
		Name:     "my-tpl",
		IaaSName: "my-iaas",
		Data: iaas.TemplateDataList([]iaas.TemplateData{
			{Name: "x", Value: "y"},
			{Name: "a", Value: "b"},
		}),
	}
	err := tpl1.Save()
	c.Assert(err, check.IsNil)
	tplParam := iaas.Template{
		Data: iaas.TemplateDataList([]iaas.TemplateData{
			{Name: "x", Value: ""},
			{Name: "y", Value: "8"},
			{Name: "z", Value: "9"},
		}),
	}
	v, err := form.EncodeToValues(&tplParam)
	c.Assert(err, check.IsNil)
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/iaas/templates/my-tpl", strings.NewReader(v.Encode()))
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	m := RunServer(true)
	m.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	templates, err := iaas.ListTemplates()
	c.Assert(err, check.IsNil)
	c.Assert(templates, check.HasLen, 1)
	c.Assert(templates[0].Name, check.Equals, "my-tpl")
	c.Assert(templates[0].IaaSName, check.Equals, "my-iaas")
	sort.Sort(templates[0].Data)
	c.Assert(templates[0].Data, check.DeepEquals, iaas.TemplateDataList([]iaas.TemplateData{
		{Name: "a", Value: "b"},
		{Name: "y", Value: "8"},
		{Name: "z", Value: "9"},
	}))
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeIaas, Value: "my-iaas"},
		Owner:  s.token.GetUserName(),
		Kind:   "machine.template.update",
		StartCustomData: []map[string]interface{}{
			{"name": ":template_name", "value": "my-tpl"},
			{"name": "Data.0.Name", "value": "x"},
			{"name": "Data.0.Value", "value": ""},
			{"name": "Data.1.Name", "value": "y"},
			{"name": "Data.1.Value", "value": "8"},
			{"name": "Data.2.Name", "value": "z"},
			{"name": "Data.2.Value", "value": "9"},
		},
	}, eventtest.HasEvent)
}
Пример #18
0
func (s *S) TestUpdateNodeHandlerNoAddress(c *check.C) {
	params := provision.UpdateNodeOptions{}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/node", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusBadRequest)
}
Пример #19
0
func (s *S) TestNodeContainerUpdateInvalid(c *check.C) {
	cont := nodecontainer.NodeContainerConfig{Name: "c1", Config: docker.Config{Image: "img1"}}
	val, err := form.EncodeToValues(cont)
	c.Assert(err, check.IsNil)
	reader := strings.NewReader(val.Encode())
	request, err := http.NewRequest("POST", "/1.2/nodecontainers/c1", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusNotFound)
	c.Assert(recorder.Body.String(), check.Matches, "node container not found\n")
}
Пример #20
0
func (s *S) TestAddNodeHandlerCreatingAnIaasMachine(c *check.C) {
	iaas.RegisterIaasProvider("test-iaas", newTestIaaS)
	opts := provision.AddPoolOptions{Name: "pool1"}
	err := provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	defer provision.RemovePool("pool1")
	params := provision.AddNodeOptions{
		Register: false,
		Metadata: map[string]string{
			"id":   "test1",
			"pool": "pool1",
			"iaas": "test-iaas",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	req, err := http.NewRequest("POST", "/node", b)
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec := httptest.NewRecorder()
	m := RunServer(true)
	m.ServeHTTP(rec, req)
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
	c.Assert(rec.Body.String(), check.Equals, "")
	nodes, err := s.provisioner.ListNodes(nil)
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 1)
	c.Assert(nodes[0].Address(), check.Equals, "http://test1.somewhere.com:2375")
	c.Assert(nodes[0].Metadata(), check.DeepEquals, map[string]string{
		"id":      "test1",
		"pool":    "pool1",
		"iaas":    "test-iaas",
		"iaas-id": "test1",
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNode, Value: "http://test1.somewhere.com:2375"},
		Owner:  s.token.GetUserName(),
		Kind:   "node.create",
		StartCustomData: []map[string]interface{}{
			{"name": "Metadata.id", "value": "test1"},
			{"name": "Metadata.pool", "value": "pool1"},
			{"name": "Register", "value": ""},
		},
	}, eventtest.HasEvent)
}
Пример #21
0
func (s *S) TestUpdateNodeHandler(c *check.C) {
	err := s.provisioner.AddNode(provision.AddNodeOptions{
		Address: "localhost:1999",
	})
	c.Assert(err, check.IsNil)
	opts := provision.AddPoolOptions{Name: "pool1"}
	err = provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	params := provision.UpdateNodeOptions{
		Address: "localhost:1999",
		Metadata: map[string]string{
			"m1": "",
			"m2": "v9",
			"m3": "v8",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/1.2/node", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	nodes, err := s.provisioner.ListNodes(nil)
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 1)
	c.Assert(nodes[0].Metadata(), check.DeepEquals, map[string]string{
		"m1": "",
		"m2": "v9",
		"m3": "v8",
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNode, Value: "localhost:1999"},
		Owner:  s.token.GetUserName(),
		Kind:   "node.update",
		StartCustomData: []map[string]interface{}{
			{"name": "Metadata.m1", "value": ""},
			{"name": "Metadata.m2", "value": "v9"},
			{"name": "Metadata.m3", "value": "v8"},
		},
	}, eventtest.HasEvent)
}
Пример #22
0
func (s *S) TestAddNodeHandler(c *check.C) {
	opts := provision.AddPoolOptions{Name: "pool1"}
	err := provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	defer provision.RemovePool("pool1")
	serverAddr := "http://mysrv1"
	params := provision.AddNodeOptions{
		Register: true,
		Metadata: map[string]string{
			"address": serverAddr,
			"pool":    "pool1",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	req, err := http.NewRequest("POST", "/1.2/node", strings.NewReader(v.Encode()))
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec := httptest.NewRecorder()
	m := RunServer(true)
	m.ServeHTTP(rec, req)
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
	c.Assert(rec.Header().Get("Content-Type"), check.Equals, "application/x-json-stream")
	nodes, err := s.provisioner.ListNodes(nil)
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 1)
	c.Assert(nodes[0].Address(), check.Equals, serverAddr)
	c.Assert(nodes[0].Metadata(), check.DeepEquals, map[string]string{
		"pool": "pool1",
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNode, Value: serverAddr},
		Owner:  s.token.GetUserName(),
		Kind:   "node.create",
		StartCustomData: []map[string]interface{}{
			{"name": "Metadata.address", "value": serverAddr},
			{"name": "Metadata.pool", "value": "pool1"},
			{"name": "Register", "value": "true"},
		},
	}, eventtest.HasEvent)
}
Пример #23
0
func (s *HandlersSuite) TestAutoScaleSetRuleExisting(c *check.C) {
	rule := autoScaleRule{MetadataFilter: "", Enabled: true, ScaleDownRatio: 1.1, MaxContainerCount: 5}
	err := rule.update()
	c.Assert(err, check.IsNil)
	rule.MaxContainerCount = 9
	v, err := form.EncodeToValues(&rule)
	c.Assert(err, check.IsNil)
	body := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("POST", "/docker/autoscale/rules", body)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := api.RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	rules, err := listAutoScaleRules()
	c.Assert(err, check.IsNil)
	c.Assert(rules, check.DeepEquals, []autoScaleRule{rule})
}
Пример #24
0
func (s *S) TestUpdateNodeHandlerNodeDoesNotExist(c *check.C) {
	err := s.provisioner.AddNode(provision.AddNodeOptions{
		Address: "localhost1:1999",
		Metadata: map[string]string{
			"m1": "v1",
			"m2": "v2",
		},
	})
	c.Assert(err, check.IsNil)
	opts := provision.AddPoolOptions{Name: "pool1"}
	err = provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	defer provision.RemovePool("pool1")
	params := provision.UpdateNodeOptions{
		Address: "localhost2:1999",
		Metadata: map[string]string{
			"m1": "",
			"m2": "v9",
			"m3": "v8",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/node", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusNotFound)
	c.Assert(recorder.Body.String(), check.Equals, provision.ErrNodeNotFound.Error()+"\n")
	nodes, err := s.provisioner.ListNodes(nil)
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 1)
	c.Assert(nodes[0].Metadata(), check.DeepEquals, map[string]string{
		"m1": "v1",
		"m2": "v2",
	})
}
Пример #25
0
func (s *S) TestTemplateUpdateNotFound(c *check.C) {
	iaas.RegisterIaasProvider("my-iaas", newTestIaaS)
	tplParam := iaas.Template{
		Data: iaas.TemplateDataList([]iaas.TemplateData{
			{Name: "x", Value: ""},
			{Name: "y", Value: "8"},
			{Name: "z", Value: "9"},
		}),
	}
	v, err := form.EncodeToValues(&tplParam)
	c.Assert(err, check.IsNil)
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("PUT", "/iaas/templates/my-tpl", strings.NewReader(v.Encode()))
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	m := RunServer(true)
	m.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusNotFound)
	c.Assert(recorder.Body.String(), check.Equals, "template not found\n")
}
Пример #26
0
Файл: cmd.go Проект: tsuru/tsuru
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)
}
Пример #27
0
Файл: cmd.go Проект: tsuru/tsuru
func (c *dockerCmd) toValues() (url.Values, error) {
	ports, portBindings, err := nat.ParsePortSpecs(c.ports)
	if err != nil {
		return nil, err
	}
	c.config.Config.ExposedPorts = map[docker.Port]struct{}{}
	for k, v := range ports {
		c.config.Config.ExposedPorts[docker.Port(k)] = v
	}
	c.config.HostConfig.PortBindings = map[docker.Port][]docker.PortBinding{}
	for k, v := range portBindings {
		var val []docker.PortBinding
		for _, b := range v {
			val = append(val, docker.PortBinding{HostIP: b.HostIP, HostPort: b.HostPort})
		}
		c.config.HostConfig.PortBindings[docker.Port(k)] = val
	}
	val, err := form.EncodeToValues(c.config)
	if err != nil {
		return nil, err
	}
	for k := range val {
		lower := strings.ToLower(k)
		if lower == k {
			continue
		}
		val[lower] = val[k]
		delete(val, k)
	}
	for k, v := range c.raw {
		k = strings.ToLower(k)
		matches := reKeyWithIndex.FindStringSubmatch(k)
		if len(matches) >= 1 {
			val.Del(matches[1])
		}
		val.Set(k, v)
	}
	return val, nil
}
Пример #28
0
func (s *HandlersSuite) TestAutoScaleSetRule(c *check.C) {
	config.Set("docker:scheduler:total-memory-metadata", "maxmemory")
	defer config.Unset("docker:scheduler:total-memory-metadata")
	rule := autoScaleRule{
		MetadataFilter: "pool1",
		Enabled:        true,
		ScaleDownRatio: 1.1,
		MaxMemoryRatio: 2.0,
	}
	v, err := form.EncodeToValues(&rule)
	c.Assert(err, check.IsNil)
	body := strings.NewReader(v.Encode())
	request, err := http.NewRequest("POST", "/docker/autoscale/rules", body)
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder := httptest.NewRecorder()
	server := api.RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	rules, err := listAutoScaleRules()
	c.Assert(err, check.IsNil)
	c.Assert(rules, check.DeepEquals, []autoScaleRule{
		{Enabled: true, ScaleDownRatio: 1.333, Error: "invalid rule, either memory information or max container count must be set"},
		rule,
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypePool, Value: "pool1"},
		Owner:  s.token.GetUserName(),
		Kind:   "node.autoscale.update",
		StartCustomData: []map[string]interface{}{
			{"name": "MetadataFilter", "value": "pool1"},
			{"name": "Enabled", "value": "true"},
			{"name": "ScaleDownRatio", "value": "1.1"},
			{"name": "MaxMemoryRatio", "value": "2"},
		},
	}, eventtest.HasEvent)
}
Пример #29
0
func (s *S) TestAddNodeHandlerWithoutAddress(c *check.C) {
	opts := provision.AddPoolOptions{Name: "pool1"}
	err := provision.AddPool(opts)
	c.Assert(err, check.IsNil)
	params := provision.AddNodeOptions{
		Register: true,
		Metadata: map[string]string{
			"pool": "pool1",
		},
	}
	v, err := form.EncodeToValues(&params)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	req, err := http.NewRequest("POST", "/node", b)
	c.Assert(err, check.IsNil)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", s.token.GetValue())
	rec := httptest.NewRecorder()
	m := RunServer(true)
	m.ServeHTTP(rec, req)
	c.Assert(rec.Code, check.Equals, http.StatusCreated)
	var result map[string]string
	err = json.NewDecoder(rec.Body).Decode(&result)
	c.Assert(err, check.IsNil)
	c.Assert(result["Error"], check.Equals, "address=url parameter is required")
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNode},
		Owner:  s.token.GetUserName(),
		Kind:   "node.create",
		StartCustomData: []map[string]interface{}{
			{"name": "Metadata.pool", "value": "pool1"},
			{"name": "Register", "value": "true"},
		},
		ErrorMatches: `address=url parameter is required`,
	}, eventtest.HasEvent)
}
Пример #30
0
func (s *S) TestRebalanceContainersFilters(c *check.C) {
	p, err := s.startMultipleServersClusterSeggregated()
	c.Assert(err, check.IsNil)
	mainDockerProvisioner = p
	err = s.newFakeImage(p, "tsuru/app-myapp", nil)
	c.Assert(err, check.IsNil)
	appInstance := provisiontest.NewFakeApp("myapp", "python", 0)
	defer p.Destroy(appInstance)
	p.Provision(appInstance)
	coll := p.Collection()
	defer coll.Close()
	defer coll.RemoveAll(bson.M{"appname": appInstance.GetName()})
	imageId, err := image.AppCurrentImageName(appInstance.GetName())
	c.Assert(err, check.IsNil)
	units, err := addContainersWithHost(&changeUnitsPipelineArgs{
		toHost:      "localhost",
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 5}},
		app:         appInstance,
		imageId:     imageId,
		provisioner: p,
	})
	c.Assert(err, check.IsNil)
	appStruct := &app.App{
		Name:     appInstance.GetName(),
		Platform: appInstance.GetPlatform(),
	}
	err = s.storage.Apps().Insert(appStruct)
	c.Assert(err, check.IsNil)
	err = s.storage.Apps().Update(
		bson.M{"name": appStruct.Name},
		bson.M{"$set": bson.M{"units": units}},
	)
	c.Assert(err, check.IsNil)
	opts := rebalanceOptions{
		MetadataFilter: map[string]string{"pool": "pool1"},
	}
	v, err := form.EncodeToValues(&opts)
	c.Assert(err, check.IsNil)
	b := strings.NewReader(v.Encode())
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("POST", "/docker/containers/rebalance", b)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	server := api.RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	body, err := ioutil.ReadAll(recorder.Body)
	c.Assert(err, check.IsNil)
	validJson := fmt.Sprintf("[%s]", strings.Replace(strings.Trim(string(body), "\n "), "\n", ",", -1))
	var result []tsuruIo.SimpleJsonMessage
	err = json.Unmarshal([]byte(validJson), &result)
	c.Assert(err, check.IsNil)
	c.Assert(result, check.HasLen, 2)
	c.Assert(result[0].Message, check.Equals, "No containers found to rebalance\n")
	c.Assert(result[1].Message, check.Equals, "Containers successfully rebalanced!\n")
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypePool, Value: "pool1"},
		Owner:  s.token.GetUserName(),
		Kind:   "node.update.rebalance",
		StartCustomData: []map[string]interface{}{
			{"name": "MetadataFilter.pool", "value": "pool1"},
		},
	}, eventtest.HasEvent)
}