auth: add span to FetchToken helpers

Before this, during a call to the docker resolver, we would generate
span wrappers for each HTTPRequest correctly, however, as the docker
resolver reaches out to the docker authorizer, it could create HTTP
requests (for fetching tokens) that would not be wrapped in any span.

This can result in rather confusing traces, e.g. something like:

	remotes.docker.resolver.HTTPRequest
		HTTP HEAD (fetch index, fails with 401)
	HTTP GET (fetch token)
	remotes.docker.resolver.HTTPRequest
		HTTP HEAD (fetch index)
	remotes.docker.resolver.HTTPRequest
		HTTP GET (fetch manifest)

By adding a span into the FetchToken, this trace becomes a little easier
to consume:

	remotes.docker.resolver.HTTPRequest
		HTTP HEAD (fetch index, fails with 401)
	remotes.docker.resolver.FetchToken
		HTTP GET (fetch token)
	remotes.docker.resolver.HTTPRequest
		HTTP HEAD (fetch index)
	remotes.docker.resolver.HTTPRequest
		HTTP GET (fetch manifest)

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell 2024-05-15 15:42:57 +01:00
parent 536608ef22
commit 9831a62d72

View File

@ -27,6 +27,7 @@ import (
"time" "time"
remoteserrors "github.com/containerd/containerd/v2/core/remotes/errors" remoteserrors "github.com/containerd/containerd/v2/core/remotes/errors"
"github.com/containerd/containerd/v2/pkg/tracing"
"github.com/containerd/containerd/v2/version" "github.com/containerd/containerd/v2/version"
"github.com/containerd/log" "github.com/containerd/log"
) )
@ -95,6 +96,10 @@ type OAuthTokenResponse struct {
// FetchTokenWithOAuth fetches a token using a POST request // FetchTokenWithOAuth fetches a token using a POST request
func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http.Header, clientID string, to TokenOptions) (*OAuthTokenResponse, error) { func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http.Header, clientID string, to TokenOptions) (*OAuthTokenResponse, error) {
c := *client
client = &c
tracing.UpdateHTTPClient(client, tracing.Name("remotes.docker.resolver", "FetchTokenWithOAuth"))
form := url.Values{} form := url.Values{}
if len(to.Scopes) > 0 { if len(to.Scopes) > 0 {
form.Set("scope", strings.Join(to.Scopes, " ")) form.Set("scope", strings.Join(to.Scopes, " "))
@ -161,6 +166,10 @@ type FetchTokenResponse struct {
// FetchToken fetches a token using a GET request // FetchToken fetches a token using a GET request
func FetchToken(ctx context.Context, client *http.Client, headers http.Header, to TokenOptions) (*FetchTokenResponse, error) { func FetchToken(ctx context.Context, client *http.Client, headers http.Header, to TokenOptions) (*FetchTokenResponse, error) {
c := *client
client = &c
tracing.UpdateHTTPClient(client, tracing.Name("remotes.docker.resolver", "FetchToken"))
req, err := http.NewRequestWithContext(ctx, http.MethodGet, to.Realm, nil) req, err := http.NewRequestWithContext(ctx, http.MethodGet, to.Realm, nil)
if err != nil { if err != nil {
return nil, err return nil, err