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") }
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(¶ms) 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") }
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) }
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 (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(¶ms) 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") }
// 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 }
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) }
// 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 }
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 }
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(¶ms) 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) }
// 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) }
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(¶ms) 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(¶ms) 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]") }
func (o *HTTP) encodeToForm(record intf.Record) string { values, err := form.EncodeToValues(record) if err != nil { Error("Form Error %s", err) } return values.Encode() }
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") }
// 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 }
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()) }
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) }
func (s *S) TestUpdateNodeHandlerNoAddress(c *check.C) { params := provision.UpdateNodeOptions{} v, err := form.EncodeToValues(¶ms) 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) }
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") }
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(¶ms) 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) }
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(¶ms) 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) }
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(¶ms) 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) }
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}) }
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(¶ms) 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", }) }
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") }
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 *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 }
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) }
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(¶ms) 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) }
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) }