feat: add auth support for downloading OCI artifacts (#3915)

This commit is contained in:
Teppei Fukuda
2023-03-30 05:53:24 +03:00
committed by GitHub
parent 1ee05189f0
commit f14bed4532
22 changed files with 286 additions and 221 deletions

View File

@@ -27,12 +27,15 @@ type Descriptor = remote.Descriptor
// Get is a wrapper of google/go-containerregistry/pkg/v1/remote.Get
// so that it can try multiple authentication methods.
func Get(ctx context.Context, ref name.Reference, option types.RemoteOptions) (*Descriptor, error) {
remoteOpts := []remote.Option{remote.WithTransport(transport(option.Insecure))}
transport := httpTransport(option.Insecure)
var errs error
// Try each authentication method until it succeeds
for _, authOpt := range authOptions(ctx, ref, option) {
// Try each authentication method until it succeeds
remoteOpts = append(remoteOpts, authOpt)
remoteOpts := []remote.Option{
remote.WithTransport(transport),
authOpt,
}
if option.Platform != "" {
s, err := parsePlatform(ref, option.Platform, remoteOpts)
@@ -58,13 +61,42 @@ func Get(ctx context.Context, ref name.Reference, option types.RemoteOptions) (*
return nil, errs
}
func Referrers(ctx context.Context, d name.Digest, option types.RemoteOptions) (*v1.IndexManifest, error) {
remoteOpts := []remote.Option{remote.WithTransport(transport(option.Insecure))}
// Image is a wrapper of google/go-containerregistry/pkg/v1/remote.Image
// so that it can try multiple authentication methods.
func Image(ctx context.Context, ref name.Reference, option types.RemoteOptions) (v1.Image, error) {
transport := httpTransport(option.Insecure)
var errs error
// Try each authentication method until it succeeds
for _, authOpt := range authOptions(ctx, ref, option) {
remoteOpts := []remote.Option{
remote.WithTransport(transport),
authOpt,
}
index, err := remote.Image(ref, remoteOpts...)
if err != nil {
errs = multierror.Append(errs, err)
continue
}
return index, nil
}
// No authentication succeeded
return nil, errs
}
// Referrers is a wrapper of google/go-containerregistry/pkg/v1/remote.Referrers
// so that it can try multiple authentication methods.
func Referrers(ctx context.Context, d name.Digest, option types.RemoteOptions) (*v1.IndexManifest, error) {
transport := httpTransport(option.Insecure)
var errs error
// Try each authentication method until it succeeds
for _, authOpt := range authOptions(ctx, d, option) {
// Try each authentication method until it succeeds
remoteOpts = append(remoteOpts, authOpt)
remoteOpts := []remote.Option{
remote.WithTransport(transport),
authOpt,
}
index, err := remote.Referrers(d, remoteOpts...)
if err != nil {
errs = multierror.Append(errs, err)
@@ -77,7 +109,7 @@ func Referrers(ctx context.Context, d name.Digest, option types.RemoteOptions) (
return nil, errs
}
func transport(insecure bool) *http.Transport {
func httpTransport(insecure bool) *http.Transport {
d := &net.Dialer{
Timeout: 10 * time.Minute,
}
@@ -105,13 +137,13 @@ func authOptions(ctx context.Context, ref name.Reference, option types.RemoteOpt
}
switch {
case len(opts) > 0:
return opts
case option.RegistryToken != "":
bearer := authn.Bearer{Token: option.RegistryToken}
return []remote.Option{remote.WithAuth(&bearer)}
default:
return []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain)}
// Use the keychain anyway at the end
opts = append(opts, remote.WithAuthFromKeychain(authn.DefaultKeychain))
return opts
}
}