func registerMeteredCharm(registrationURL string, state *api.State, jar *cookiejar.Jar, charmURL string, serviceName, environmentUUID string) error { charmsClient := charms.NewClient(state) defer charmsClient.Close() metered, err := charmsClient.IsMetered(charmURL) if err != nil { return err } if metered { httpClient := httpbakery.NewHTTPClient() httpClient.Jar = jar credentials, err := registerMetrics(registrationURL, environmentUUID, charmURL, serviceName, httpClient, openWebBrowser) if err != nil { logger.Infof("failed to register metrics: %v", err) return err } api, cerr := getMetricCredentialsAPI(state) if cerr != nil { logger.Infof("failed to get the metrics credentials setter: %v", cerr) } err = api.SetMetricCredentials(serviceName, credentials) if err != nil { logger.Infof("failed to set metric credentials: %v", err) return err } api.Close() } return nil }
func newHTTPClient() (*cookiejar.Jar, *http.Client, error) { cookieFile := path.Join(utils.Home(), ".go-cookies") jar, err := cookiejar.New(&cookiejar.Options{ PublicSuffixList: publicsuffix.List, }) if err != nil { panic(err) } if err := jar.Load(cookieFile); err != nil { return nil, nil, err } client := httpbakery.NewHTTPClient() client.Jar = jar return jar, client, nil }
// AddCharmWithAuthorization adds the given charm URL (which must include revision) to // the environment, if it does not exist yet. Local charms are not // supported, only charm store URLs. See also AddLocalCharm(). // // The authorization macaroon, args.CharmStoreMacaroon, may be // omitted, in which case this call is equivalent to AddCharm. func AddCharmWithAuthorization(st *state.State, args params.AddCharmWithAuthorization) error { charmURL, err := charm.ParseURL(args.URL) if err != nil { return err } if charmURL.Schema != "cs" { return fmt.Errorf("only charm store charm URLs are supported, with cs: schema") } if charmURL.Revision < 0 { return fmt.Errorf("charm URL must include revision") } // First, check if a pending or a real charm exists in state. stateCharm, err := st.PrepareStoreCharmUpload(charmURL) if err != nil { return err } if stateCharm.IsUploaded() { // Charm already in state (it was uploaded already). return nil } // Get the charm and its information from the store. envConfig, err := st.EnvironConfig() if err != nil { return err } csURL, err := url.Parse(csclient.ServerURL) if err != nil { return err } csParams := charmrepo.NewCharmStoreParams{ URL: csURL.String(), HTTPClient: httpbakery.NewHTTPClient(), } if args.CharmStoreMacaroon != nil { // Set the provided charmstore authorizing macaroon // as a cookie in the HTTP client. // TODO discharge any third party caveats in the macaroon. ms := []*macaroon.Macaroon{args.CharmStoreMacaroon} httpbakery.SetCookie(csParams.HTTPClient.Jar, csURL, ms) } repo := config.SpecializeCharmRepo( NewCharmStore(csParams), envConfig, ) downloadedCharm, err := repo.Get(charmURL) if err != nil { cause := errors.Cause(err) if httpbakery.IsDischargeError(cause) || httpbakery.IsInteractionError(cause) { return errors.NewUnauthorized(err, "") } return errors.Trace(err) } // Open it and calculate the SHA256 hash. downloadedBundle, ok := downloadedCharm.(*charm.CharmArchive) if !ok { return errors.Errorf("expected a charm archive, got %T", downloadedCharm) } archive, err := os.Open(downloadedBundle.Path) if err != nil { return errors.Annotate(err, "cannot read downloaded charm") } defer archive.Close() bundleSHA256, size, err := utils.ReadSHA256(archive) if err != nil { return errors.Annotate(err, "cannot calculate SHA256 hash of charm") } if _, err := archive.Seek(0, 0); err != nil { return errors.Annotate(err, "cannot rewind charm archive") } // Store the charm archive in environment storage. return StoreCharmArchive( st, charmURL, downloadedCharm, archive, size, bundleSHA256, ) }
type metricRegistrationPost struct { EnvironmentUUID string `json:"env-uuid"` CharmURL string `json:"charm-url"` ServiceName string `json:"service-name"` } var registerMeteredCharm = func(registrationURL string, state api.Connection, jar *cookiejar.Jar, charmURL string, serviceName, environmentUUID string) error { charmsClient := charms.NewClient(state) defer charmsClient.Close() metered, err := charmsClient.IsMetered(charmURL) if err != nil { return err } if metered { httpClient := httpbakery.NewHTTPClient() httpClient.Jar = jar credentials, err := registerMetrics(registrationURL, environmentUUID, charmURL, serviceName, httpClient, openWebBrowser) if err != nil { logger.Infof("failed to register metrics: %v", err) return err } api, cerr := getMetricCredentialsAPI(state) if cerr != nil { logger.Infof("failed to get the metrics credentials setter: %v", cerr) } err = api.SetMetricCredentials(serviceName, credentials) if err != nil { logger.Infof("failed to set metric credentials: %v", err) return err