...

Source file src/github.com/google/go-containerregistry/pkg/crane/options.go

Documentation: github.com/google/go-containerregistry/pkg/crane

     1  // Copyright 2019 Google LLC All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package crane
    16  
    17  import (
    18  	"context"
    19  	"crypto/tls"
    20  	"net/http"
    21  
    22  	"github.com/google/go-containerregistry/pkg/authn"
    23  	"github.com/google/go-containerregistry/pkg/name"
    24  	v1 "github.com/google/go-containerregistry/pkg/v1"
    25  	"github.com/google/go-containerregistry/pkg/v1/remote"
    26  )
    27  
    28  // Options hold the options that crane uses when calling other packages.
    29  type Options struct {
    30  	Name      []name.Option
    31  	Remote    []remote.Option
    32  	Platform  *v1.Platform
    33  	Keychain  authn.Keychain
    34  	Transport http.RoundTripper
    35  
    36  	auth      authn.Authenticator
    37  	insecure  bool
    38  	jobs      int
    39  	noclobber bool
    40  	ctx       context.Context
    41  }
    42  
    43  // GetOptions exposes the underlying []remote.Option, []name.Option, and
    44  // platform, based on the passed Option. Generally, you shouldn't need to use
    45  // this unless you've painted yourself into a dependency corner as we have
    46  // with the crane and gcrane cli packages.
    47  func GetOptions(opts ...Option) Options {
    48  	return makeOptions(opts...)
    49  }
    50  
    51  func makeOptions(opts ...Option) Options {
    52  	opt := Options{
    53  		Remote: []remote.Option{
    54  			remote.WithAuthFromKeychain(authn.DefaultKeychain),
    55  		},
    56  		Keychain: authn.DefaultKeychain,
    57  		jobs:     4,
    58  		ctx:      context.Background(),
    59  	}
    60  
    61  	for _, o := range opts {
    62  		o(&opt)
    63  	}
    64  
    65  	// Allow for untrusted certificates if the user
    66  	// passed Insecure but no custom transport.
    67  	if opt.insecure && opt.Transport == nil {
    68  		transport := remote.DefaultTransport.(*http.Transport).Clone()
    69  		transport.TLSClientConfig = &tls.Config{
    70  			InsecureSkipVerify: true, //nolint: gosec
    71  		}
    72  
    73  		WithTransport(transport)(&opt)
    74  	} else if opt.Transport == nil {
    75  		opt.Transport = remote.DefaultTransport
    76  	}
    77  
    78  	return opt
    79  }
    80  
    81  // Option is a functional option for crane.
    82  type Option func(*Options)
    83  
    84  // WithTransport is a functional option for overriding the default transport
    85  // for remote operations. Setting a transport will override the Insecure option's
    86  // configuration allowing for image registries to use untrusted certificates.
    87  func WithTransport(t http.RoundTripper) Option {
    88  	return func(o *Options) {
    89  		o.Remote = append(o.Remote, remote.WithTransport(t))
    90  		o.Transport = t
    91  	}
    92  }
    93  
    94  // Insecure is an Option that allows image references to be fetched without TLS.
    95  // This will also allow for untrusted (e.g. self-signed) certificates in cases where
    96  // the default transport is used (i.e. when WithTransport is not used).
    97  func Insecure(o *Options) {
    98  	o.Name = append(o.Name, name.Insecure)
    99  	o.insecure = true
   100  }
   101  
   102  // WithPlatform is an Option to specify the platform.
   103  func WithPlatform(platform *v1.Platform) Option {
   104  	return func(o *Options) {
   105  		if platform != nil {
   106  			o.Remote = append(o.Remote, remote.WithPlatform(*platform))
   107  		}
   108  		o.Platform = platform
   109  	}
   110  }
   111  
   112  // WithAuthFromKeychain is a functional option for overriding the default
   113  // authenticator for remote operations, using an authn.Keychain to find
   114  // credentials.
   115  //
   116  // By default, crane will use authn.DefaultKeychain.
   117  func WithAuthFromKeychain(keys authn.Keychain) Option {
   118  	return func(o *Options) {
   119  		// Replace the default keychain at position 0.
   120  		o.Remote[0] = remote.WithAuthFromKeychain(keys)
   121  		o.Keychain = keys
   122  	}
   123  }
   124  
   125  // WithAuth is a functional option for overriding the default authenticator
   126  // for remote operations.
   127  //
   128  // By default, crane will use authn.DefaultKeychain.
   129  func WithAuth(auth authn.Authenticator) Option {
   130  	return func(o *Options) {
   131  		// Replace the default keychain at position 0.
   132  		o.Remote[0] = remote.WithAuth(auth)
   133  		o.auth = auth
   134  	}
   135  }
   136  
   137  // WithUserAgent adds the given string to the User-Agent header for any HTTP
   138  // requests.
   139  func WithUserAgent(ua string) Option {
   140  	return func(o *Options) {
   141  		o.Remote = append(o.Remote, remote.WithUserAgent(ua))
   142  	}
   143  }
   144  
   145  // WithNondistributable is an option that allows pushing non-distributable
   146  // layers.
   147  func WithNondistributable() Option {
   148  	return func(o *Options) {
   149  		o.Remote = append(o.Remote, remote.WithNondistributable)
   150  	}
   151  }
   152  
   153  // WithContext is a functional option for setting the context.
   154  func WithContext(ctx context.Context) Option {
   155  	return func(o *Options) {
   156  		o.ctx = ctx
   157  		o.Remote = append(o.Remote, remote.WithContext(ctx))
   158  	}
   159  }
   160  
   161  // WithJobs sets the number of concurrent jobs to run.
   162  //
   163  // The default number of jobs is GOMAXPROCS.
   164  func WithJobs(jobs int) Option {
   165  	return func(o *Options) {
   166  		if jobs > 0 {
   167  			o.jobs = jobs
   168  		}
   169  		o.Remote = append(o.Remote, remote.WithJobs(o.jobs))
   170  	}
   171  }
   172  
   173  // WithNoClobber modifies behavior to avoid overwriting existing tags, if possible.
   174  func WithNoClobber(noclobber bool) Option {
   175  	return func(o *Options) {
   176  		o.noclobber = noclobber
   177  	}
   178  }
   179  

View as plain text