github.com/kubeshop/testkube@v1.17.23/pkg/storage/minio/minio_connecter.go (about)

     1  package minio
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"fmt"
     7  	"os"
     8  
     9  	"github.com/minio/minio-go/v7"
    10  	"github.com/minio/minio-go/v7/pkg/credentials"
    11  	"github.com/pkg/errors"
    12  	"go.uber.org/zap"
    13  )
    14  
    15  type Option func(*Connecter) error
    16  
    17  // Insecure is an Option to enable TLS secure connections that skip server verification.
    18  func Insecure() Option {
    19  	return func(o *Connecter) error {
    20  		if o.TlsConfig == nil {
    21  			o.TlsConfig = &tls.Config{MinVersion: tls.VersionTLS12}
    22  		}
    23  		o.TlsConfig.InsecureSkipVerify = true
    24  		o.Ssl = true
    25  		return nil
    26  	}
    27  }
    28  
    29  // RootCAs is a helper option to provide the RootCAs pool from a list of filenames.
    30  // If Secure is not already set this will set it as well.
    31  func RootCAs(file ...string) Option {
    32  	return func(o *Connecter) error {
    33  		pool := x509.NewCertPool()
    34  		for _, f := range file {
    35  			rootPEM, err := os.ReadFile(f)
    36  			if err != nil || rootPEM == nil {
    37  				return fmt.Errorf("nats: error loading or parsing rootCA file: %v", err)
    38  			}
    39  			ok := pool.AppendCertsFromPEM(rootPEM)
    40  			if !ok {
    41  				return fmt.Errorf("nats: failed to parse root certificate from %q", f)
    42  			}
    43  		}
    44  		if o.TlsConfig == nil {
    45  			o.TlsConfig = &tls.Config{MinVersion: tls.VersionTLS12}
    46  		}
    47  		o.TlsConfig.RootCAs = pool
    48  		o.Ssl = true
    49  		return nil
    50  	}
    51  }
    52  
    53  // ClientCert is a helper option to provide the client certificate from a file.
    54  // If Secure is not already set this will set it as well.
    55  func ClientCert(certFile, keyFile string) Option {
    56  	return func(o *Connecter) error {
    57  		cert, err := tls.LoadX509KeyPair(certFile, keyFile)
    58  		if err != nil {
    59  			return fmt.Errorf("nats: error loading client certificate: %v", err)
    60  		}
    61  		cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
    62  		if err != nil {
    63  			return fmt.Errorf("nats: error parsing client certificate: %v", err)
    64  		}
    65  		if o.TlsConfig == nil {
    66  			o.TlsConfig = &tls.Config{MinVersion: tls.VersionTLS12}
    67  		}
    68  		o.TlsConfig.Certificates = []tls.Certificate{cert}
    69  		o.Ssl = true
    70  		return nil
    71  	}
    72  }
    73  
    74  type Connecter struct {
    75  	Endpoint        string
    76  	AccessKeyID     string
    77  	SecretAccessKey string
    78  	Region          string
    79  	Token           string
    80  	Bucket          string
    81  	Ssl             bool
    82  	TlsConfig       *tls.Config
    83  	Opts            []Option
    84  	Log             *zap.SugaredLogger
    85  	client          *minio.Client
    86  }
    87  
    88  // NewConnecter creates a new Connecter
    89  func NewConnecter(endpoint, accessKeyID, secretAccessKey, region, token, bucket string, log *zap.SugaredLogger, opts ...Option) *Connecter {
    90  	c := &Connecter{
    91  		Endpoint:        endpoint,
    92  		AccessKeyID:     accessKeyID,
    93  		SecretAccessKey: secretAccessKey,
    94  		Region:          region,
    95  		Token:           token,
    96  		Bucket:          bucket,
    97  		Opts:            opts,
    98  		Log:             log,
    99  	}
   100  	return c
   101  }
   102  
   103  // GetClient() connects to MinIO
   104  func (c *Connecter) GetClient() (*minio.Client, error) {
   105  	if c.client != nil {
   106  		return c.client, nil
   107  	}
   108  
   109  	for _, opt := range c.Opts {
   110  		if err := opt(c); err != nil {
   111  			return nil, errors.Wrapf(err, "error connecting to server")
   112  		}
   113  	}
   114  	creds := credentials.NewIAM("")
   115  	c.Log.Debugw("connecting to server",
   116  		"endpoint", c.Endpoint,
   117  		"accessKeyID", c.AccessKeyID,
   118  		"region", c.Region,
   119  		"token", c.Token,
   120  		"bucket", c.Bucket,
   121  		"ssl", c.Ssl)
   122  	if c.AccessKeyID != "" && c.SecretAccessKey != "" {
   123  		creds = credentials.NewStaticV4(c.AccessKeyID, c.SecretAccessKey, c.Token)
   124  	}
   125  	transport, err := minio.DefaultTransport(c.Ssl)
   126  	if err != nil {
   127  		c.Log.Errorw("error creating minio transport", "error", err)
   128  		return nil, err
   129  	}
   130  	transport.TLSClientConfig = c.TlsConfig
   131  	opts := &minio.Options{
   132  		Creds:     creds,
   133  		Secure:    c.Ssl,
   134  		Transport: transport,
   135  	}
   136  	if c.Region != "" {
   137  		opts.Region = c.Region
   138  	}
   139  	mclient, err := minio.New(c.Endpoint, opts)
   140  	if err != nil {
   141  		c.Log.Errorw("error connecting to minio", "error", err)
   142  		return nil, err
   143  	}
   144  
   145  	c.client = mclient
   146  	return mclient, nil
   147  }