github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/getter/getter.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package getter
    18  
    19  import (
    20  	"bytes"
    21  	"net/http"
    22  	"time"
    23  
    24  	"github.com/pkg/errors"
    25  
    26  	"github.com/stefanmcshane/helm/pkg/cli"
    27  	"github.com/stefanmcshane/helm/pkg/registry"
    28  )
    29  
    30  // options are generic parameters to be provided to the getter during instantiation.
    31  //
    32  // Getters may or may not ignore these parameters as they are passed in.
    33  type options struct {
    34  	url                   string
    35  	certFile              string
    36  	keyFile               string
    37  	caFile                string
    38  	unTar                 bool
    39  	insecureSkipVerifyTLS bool
    40  	username              string
    41  	password              string
    42  	passCredentialsAll    bool
    43  	userAgent             string
    44  	version               string
    45  	registryClient        *registry.Client
    46  	timeout               time.Duration
    47  	transport             *http.Transport
    48  }
    49  
    50  // Option allows specifying various settings configurable by the user for overriding the defaults
    51  // used when performing Get operations with the Getter.
    52  type Option func(*options)
    53  
    54  // WithURL informs the getter the server name that will be used when fetching objects. Used in conjunction with
    55  // WithTLSClientConfig to set the TLSClientConfig's server name.
    56  func WithURL(url string) Option {
    57  	return func(opts *options) {
    58  		opts.url = url
    59  	}
    60  }
    61  
    62  // WithBasicAuth sets the request's Authorization header to use the provided credentials
    63  func WithBasicAuth(username, password string) Option {
    64  	return func(opts *options) {
    65  		opts.username = username
    66  		opts.password = password
    67  	}
    68  }
    69  
    70  func WithPassCredentialsAll(pass bool) Option {
    71  	return func(opts *options) {
    72  		opts.passCredentialsAll = pass
    73  	}
    74  }
    75  
    76  // WithUserAgent sets the request's User-Agent header to use the provided agent name.
    77  func WithUserAgent(userAgent string) Option {
    78  	return func(opts *options) {
    79  		opts.userAgent = userAgent
    80  	}
    81  }
    82  
    83  // WithInsecureSkipVerifyTLS determines if a TLS Certificate will be checked
    84  func WithInsecureSkipVerifyTLS(insecureSkipVerifyTLS bool) Option {
    85  	return func(opts *options) {
    86  		opts.insecureSkipVerifyTLS = insecureSkipVerifyTLS
    87  	}
    88  }
    89  
    90  // WithTLSClientConfig sets the client auth with the provided credentials.
    91  func WithTLSClientConfig(certFile, keyFile, caFile string) Option {
    92  	return func(opts *options) {
    93  		opts.certFile = certFile
    94  		opts.keyFile = keyFile
    95  		opts.caFile = caFile
    96  	}
    97  }
    98  
    99  // WithTimeout sets the timeout for requests
   100  func WithTimeout(timeout time.Duration) Option {
   101  	return func(opts *options) {
   102  		opts.timeout = timeout
   103  	}
   104  }
   105  
   106  func WithTagName(tagname string) Option {
   107  	return func(opts *options) {
   108  		opts.version = tagname
   109  	}
   110  }
   111  
   112  func WithRegistryClient(client *registry.Client) Option {
   113  	return func(opts *options) {
   114  		opts.registryClient = client
   115  	}
   116  }
   117  
   118  func WithUntar() Option {
   119  	return func(opts *options) {
   120  		opts.unTar = true
   121  	}
   122  }
   123  
   124  // WithTransport sets the http.Transport to allow overwriting the HTTPGetter default.
   125  func WithTransport(transport *http.Transport) Option {
   126  	return func(opts *options) {
   127  		opts.transport = transport
   128  	}
   129  }
   130  
   131  // Getter is an interface to support GET to the specified URL.
   132  type Getter interface {
   133  	// Get file content by url string
   134  	Get(url string, options ...Option) (*bytes.Buffer, error)
   135  }
   136  
   137  // Constructor is the function for every getter which creates a specific instance
   138  // according to the configuration
   139  type Constructor func(options ...Option) (Getter, error)
   140  
   141  // Provider represents any getter and the schemes that it supports.
   142  //
   143  // For example, an HTTP provider may provide one getter that handles both
   144  // 'http' and 'https' schemes.
   145  type Provider struct {
   146  	Schemes []string
   147  	New     Constructor
   148  }
   149  
   150  // Provides returns true if the given scheme is supported by this Provider.
   151  func (p Provider) Provides(scheme string) bool {
   152  	for _, i := range p.Schemes {
   153  		if i == scheme {
   154  			return true
   155  		}
   156  	}
   157  	return false
   158  }
   159  
   160  // Providers is a collection of Provider objects.
   161  type Providers []Provider
   162  
   163  // ByScheme returns a Provider that handles the given scheme.
   164  //
   165  // If no provider handles this scheme, this will return an error.
   166  func (p Providers) ByScheme(scheme string) (Getter, error) {
   167  	for _, pp := range p {
   168  		if pp.Provides(scheme) {
   169  			return pp.New()
   170  		}
   171  	}
   172  	return nil, errors.Errorf("scheme %q not supported", scheme)
   173  }
   174  
   175  var httpProvider = Provider{
   176  	Schemes: []string{"http", "https"},
   177  	New:     NewHTTPGetter,
   178  }
   179  
   180  var ociProvider = Provider{
   181  	Schemes: []string{registry.OCIScheme},
   182  	New:     NewOCIGetter,
   183  }
   184  
   185  // All finds all of the registered getters as a list of Provider instances.
   186  // Currently, the built-in getters and the discovered plugins with downloader
   187  // notations are collected.
   188  func All(settings *cli.EnvSettings) Providers {
   189  	result := Providers{httpProvider, ociProvider}
   190  	pluginDownloaders, _ := collectPlugins(settings)
   191  	result = append(result, pluginDownloaders...)
   192  	return result
   193  }