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  }