Add support for registry token in containerd pull logic

When registry token is provided, the authorization header can be
directly applied to the registry request. No other type of
authorization will be attempted when the registry token is provided.

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan 2023-09-13 16:14:24 -07:00
parent 982e5afd1c
commit 62e55fd58a
No known key found for this signature in database
GPG key ID: F58C5D0A4405ACDB

View file

@ -6,6 +6,7 @@ import (
"errors"
"net/http"
cerrdefs "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
@ -33,7 +34,7 @@ func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig
func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts {
var authorizer docker.Authorizer
if optAuthConfig != nil {
authorizer = docker.NewDockerAuthorizer(authorizationCredsFromAuthConfig(*optAuthConfig))
authorizer = authorizerFromAuthConfig(*optAuthConfig)
}
return func(n string) ([]docker.RegistryHost, error) {
@ -55,13 +56,20 @@ func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.Aut
}
}
func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docker.AuthorizerOpt {
func authorizerFromAuthConfig(authConfig registrytypes.AuthConfig) docker.Authorizer {
cfgHost := registry.ConvertToHostname(authConfig.ServerAddress)
if cfgHost == "" || cfgHost == registry.IndexHostname {
cfgHost = registry.DefaultRegistryHost
}
return docker.WithAuthCreds(func(host string) (string, string, error) {
if authConfig.RegistryToken != "" {
return &bearerAuthorizer{
host: cfgHost,
bearer: authConfig.RegistryToken,
}
}
return docker.NewDockerAuthorizer(docker.WithAuthCreds(func(host string) (string, string, error) {
if cfgHost != host {
log.G(context.TODO()).WithFields(log.Fields{
"host": host,
@ -73,7 +81,31 @@ func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docke
return "", authConfig.IdentityToken, nil
}
return authConfig.Username, authConfig.Password, nil
})
}))
}
type bearerAuthorizer struct {
host string
bearer string
}
func (a *bearerAuthorizer) Authorize(ctx context.Context, req *http.Request) error {
if req.Host != a.host {
log.G(ctx).WithFields(log.Fields{
"host": req.Host,
"cfgHost": a.host,
}).Warn("Host doesn't match for bearer token")
return nil
}
req.Header.Set("Authorization", "Bearer "+a.bearer)
return nil
}
func (a *bearerAuthorizer) AddResponses(context.Context, []*http.Response) error {
// Return not implemented to prevent retry of the request when bearer did not succeed
return cerrdefs.ErrNotImplemented
}
type httpFallback struct {