github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/commands/register.go (about) 1 // Copyright 2015 Canonical Ltd. All rights reserved. 2 3 package commands 4 5 import ( 6 "bytes" 7 "encoding/json" 8 "io/ioutil" 9 "net/http" 10 "net/url" 11 12 "github.com/juju/errors" 13 "github.com/juju/persistent-cookiejar" 14 "gopkg.in/macaroon-bakery.v1/httpbakery" 15 16 "github.com/juju/juju/api" 17 "github.com/juju/juju/api/charms" 18 ) 19 20 var ( 21 openWebBrowser = func(_ *url.URL) error { return nil } 22 ) 23 24 type metricRegistrationPost struct { 25 EnvironmentUUID string `json:"env-uuid"` 26 CharmURL string `json:"charm-url"` 27 ServiceName string `json:"service-name"` 28 } 29 30 var registerMeteredCharm = func(registrationURL string, state api.Connection, jar *cookiejar.Jar, charmURL string, serviceName, environmentUUID string) error { 31 charmsClient := charms.NewClient(state) 32 defer charmsClient.Close() 33 metered, err := charmsClient.IsMetered(charmURL) 34 if err != nil { 35 return err 36 } 37 if metered { 38 client := httpbakery.NewClient() 39 client.Client.Jar = jar 40 client.VisitWebPage = openWebBrowser 41 credentials, err := registerMetrics(registrationURL, environmentUUID, charmURL, serviceName, client) 42 if err != nil { 43 logger.Infof("failed to register metrics: %v", err) 44 return err 45 } 46 47 api, cerr := getMetricCredentialsAPI(state) 48 if cerr != nil { 49 logger.Infof("failed to get the metrics credentials setter: %v", cerr) 50 } 51 err = api.SetMetricCredentials(serviceName, credentials) 52 if err != nil { 53 logger.Infof("failed to set metric credentials: %v", err) 54 return err 55 } 56 api.Close() 57 } 58 return nil 59 } 60 61 func registerMetrics(registrationURL, environmentUUID, charmURL, serviceName string, client *httpbakery.Client) ([]byte, error) { 62 if registrationURL == "" { 63 return nil, errors.Errorf("no metric registration url is specified") 64 } 65 registerURL, err := url.Parse(registrationURL) 66 if err != nil { 67 return nil, errors.Trace(err) 68 } 69 70 registrationPost := metricRegistrationPost{ 71 EnvironmentUUID: environmentUUID, 72 CharmURL: charmURL, 73 ServiceName: serviceName, 74 } 75 76 buff := &bytes.Buffer{} 77 encoder := json.NewEncoder(buff) 78 err = encoder.Encode(registrationPost) 79 if err != nil { 80 return nil, errors.Trace(err) 81 } 82 83 req, err := http.NewRequest("POST", registerURL.String(), nil) 84 if err != nil { 85 return nil, errors.Trace(err) 86 } 87 req.Header.Set("Content-Type", "application/json") 88 89 response, err := client.DoWithBody(req, bytes.NewReader(buff.Bytes())) 90 if err != nil { 91 return nil, errors.Trace(err) 92 } 93 defer response.Body.Close() 94 95 if response.StatusCode != http.StatusOK { 96 return nil, errors.Errorf("failed to register metrics: http response is %d", response.StatusCode) 97 } 98 99 b, err := ioutil.ReadAll(response.Body) 100 if err != nil { 101 return nil, errors.Annotatef(err, "failed to read the response") 102 } 103 return b, nil 104 }