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  }