func (r *RegisterMeteredCharm) registerMetrics(modelUUID, charmURL, serviceName, budget, limit string, client *httpbakery.Client) ([]byte, error) { if r.RegisterURL == "" { return nil, errors.Errorf("no metric registration url is specified") } registerURL, err := url.Parse(r.RegisterURL) if err != nil { return nil, errors.Trace(err) } registrationPost := metricRegistrationPost{ ModelUUID: modelUUID, CharmURL: charmURL, ApplicationName: serviceName, PlanURL: r.Plan, Budget: budget, Limit: limit, } buff := &bytes.Buffer{} encoder := json.NewEncoder(buff) err = encoder.Encode(registrationPost) if err != nil { return nil, errors.Trace(err) } req, err := http.NewRequest("POST", registerURL.String(), nil) if err != nil { return nil, errors.Trace(err) } req.Header.Set("Content-Type", "application/json") response, err := client.DoWithBody(req, bytes.NewReader(buff.Bytes())) if err != nil { return nil, errors.Trace(err) } defer response.Body.Close() if response.StatusCode == http.StatusOK { b, err := ioutil.ReadAll(response.Body) if err != nil { return nil, errors.Annotatef(err, "failed to read the response") } return b, nil } var respError struct { Error string `json:"error"` } err = json.NewDecoder(response.Body).Decode(&respError) if err != nil { return nil, errors.Errorf("authorization failed: http response is %d", response.StatusCode) } return nil, errors.Errorf("authorization failed: %s", respError.Error) }
func (ctxt *context) doRequest(client *httpbakery.Client, stdin io.Reader) (*http.Response, error) { req := &http.Request{ URL: ctxt.url, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Method: ctxt.method, Header: ctxt.header, } if len(ctxt.urlValues) > 0 { if req.URL.RawQuery != "" { req.URL.RawQuery += "&" } req.URL.RawQuery += ctxt.urlValues.Encode() } var body []byte switch { case len(ctxt.form) > 0: req.Header.Set("Content-Type", "application/x-www-form-urlencoded") body = []byte(ctxt.form.Encode()) case len(ctxt.jsonObj) > 0: data, err := json.Marshal(ctxt.jsonObj) if err != nil { return nil, fmt.Errorf("cannot marshal JSON: %v", err) } body = data case req.Method != "GET" && req.Method != "HEAD" && stdin != nil: // No fields specified and it looks like we need a body. // TODO check if it's seekable or make a temp file. data, err := ioutil.ReadAll(stdin) if err != nil { return nil, fmt.Errorf("error reading stdin: %v", err) } // TODO if we're expecting JSON, accept rjson too. body = data } req.ContentLength = int64(len(body)) resp, err := client.DoWithBody(req, bytes.NewReader(body)) if err != nil { return nil, fmt.Errorf("cannot do HTTP request: %v", err) } return resp, nil }
func (r *RegisterMeteredCharm) registerMetrics(environmentUUID, charmURL, serviceName string, client *httpbakery.Client) ([]byte, error) { if r.RegisterURL == "" { return nil, errors.Errorf("no metric registration url is specified") } registerURL, err := url.Parse(r.RegisterURL) if err != nil { return nil, errors.Trace(err) } registrationPost := metricRegistrationPost{ ModelUUID: environmentUUID, CharmURL: charmURL, ServiceName: serviceName, PlanURL: r.Plan, } buff := &bytes.Buffer{} encoder := json.NewEncoder(buff) err = encoder.Encode(registrationPost) if err != nil { return nil, errors.Trace(err) } req, err := http.NewRequest("POST", registerURL.String(), nil) if err != nil { return nil, errors.Trace(err) } req.Header.Set("Content-Type", "application/json") response, err := client.DoWithBody(req, bytes.NewReader(buff.Bytes())) if err != nil { return nil, errors.Trace(err) } defer response.Body.Close() if response.StatusCode != http.StatusOK { return nil, errors.Errorf("failed to register metrics: http response is %d", response.StatusCode) } b, err := ioutil.ReadAll(response.Body) if err != nil { return nil, errors.Annotatef(err, "failed to read the response") } return b, nil }