func TokenSource()

in src/go/gcsrunner/serviceaccount.go [40:105]


func TokenSource(ctx context.Context, sa string) (oauth2.TokenSource, error) {
	url := fmt.Sprintf("https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:generateAccessToken", sa)
	bodyBytes, err := json.Marshal(map[string][]string{
		"scope": []string{storage.ScopeReadOnly},
	})
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(bodyBytes))
	if err != nil {
		return nil, err
	}

	start := time.Now()
	c, err := google.FindDefaultCredentials(ctx)
	if err != nil {
		glog.Errorf("error finding default credentials: %v", err)
		return nil, err
	}
	glog.Infof("found default credentials in %s", time.Since(start))

	start = time.Now()
	token, err := c.TokenSource.Token()
	if err != nil {
		glog.Errorf("error getting token: %v", err)
		return nil, err
	}
	glog.Infof("obtained token in %s", time.Since(start))
	token.SetAuthHeader(req)

	client := http.Client{
		Timeout: time.Second * 5,
	}
	start = time.Now()
	resp, err := client.Do(req)
	if err != nil {
		glog.Errorf("error completing iamcredentials request: %v", err)
		return nil, err
	}
	glog.Infof("iamcredentials request completed in %s", time.Since(start))

	if resp.StatusCode != http.StatusOK {
		respBody, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return nil, fmt.Errorf("failed iamcredentials request (could not read body): %v", resp.Status)
		}
		return nil, fmt.Errorf("failed iamcredentials request: %v\n%v", resp.Status, string(respBody))
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var iamCredsResp iamcredentialsResponse
	if err := json.Unmarshal(respBody, &iamCredsResp); err != nil {
		return nil, err
	}
	expiry, err := time.Parse(time.RFC3339, iamCredsResp.ExpireTime)
	if err != nil {
		return nil, fmt.Errorf("could not parse expiry: %v", err)
	}
	return &staticTokenSource{
		accessToken: iamCredsResp.AccessToken,
		expiry:      expiry,
	}, nil
}