github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/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.v0/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 httpClient := httpbakery.NewHTTPClient() 39 httpClient.Jar = jar 40 credentials, err := registerMetrics(registrationURL, environmentUUID, charmURL, serviceName, httpClient, openWebBrowser) 41 if err != nil { 42 logger.Infof("failed to register metrics: %v", err) 43 return err 44 } 45 46 api, cerr := getMetricCredentialsAPI(state) 47 if cerr != nil { 48 logger.Infof("failed to get the metrics credentials setter: %v", cerr) 49 } 50 err = api.SetMetricCredentials(serviceName, credentials) 51 if err != nil { 52 logger.Infof("failed to set metric credentials: %v", err) 53 return err 54 } 55 api.Close() 56 } 57 return nil 58 } 59 60 func registerMetrics(registrationURL, environmentUUID, charmURL, serviceName string, client *http.Client, visitWebPage func(*url.URL) error) ([]byte, error) { 61 if registrationURL == "" { 62 return nil, errors.Errorf("no metric registration url is specified") 63 } 64 registerURL, err := url.Parse(registrationURL) 65 if err != nil { 66 return nil, errors.Trace(err) 67 } 68 69 registrationPost := metricRegistrationPost{ 70 EnvironmentUUID: environmentUUID, 71 CharmURL: charmURL, 72 ServiceName: serviceName, 73 } 74 75 buff := &bytes.Buffer{} 76 encoder := json.NewEncoder(buff) 77 err = encoder.Encode(registrationPost) 78 if err != nil { 79 return nil, errors.Trace(err) 80 } 81 82 req, err := http.NewRequest("POST", registerURL.String(), nil) 83 if err != nil { 84 return nil, errors.Trace(err) 85 } 86 req.Header.Set("Content-Type", "application/json") 87 88 bodyGetter := httpbakery.SeekerBody(bytes.NewReader(buff.Bytes())) 89 90 response, err := httpbakery.DoWithBody(client, req, bodyGetter, visitWebPage) 91 if err != nil { 92 return nil, errors.Trace(err) 93 } 94 defer response.Body.Close() 95 96 if response.StatusCode != http.StatusOK { 97 return nil, errors.Errorf("failed to register metrics: http response is %d", response.StatusCode) 98 } 99 100 b, err := ioutil.ReadAll(response.Body) 101 if err != nil { 102 return nil, errors.Annotatef(err, "failed to read the response") 103 } 104 return b, nil 105 }