github.com/StarfishStorage/goofys@v0.23.2-0.20200415030923-535558486b34/api/common/conf_s3.go (about)

     1  // Copyright 2019 Databricks
     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 common
    16  
    17  import (
    18  	"crypto/md5"
    19  	"encoding/base64"
    20  	"fmt"
    21  	"net/http"
    22  
    23  	"github.com/aws/aws-sdk-go/aws"
    24  	"github.com/aws/aws-sdk-go/aws/client"
    25  	"github.com/aws/aws-sdk-go/aws/credentials"
    26  	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
    27  	"github.com/aws/aws-sdk-go/aws/session"
    28  )
    29  
    30  type S3Config struct {
    31  	Profile         string
    32  	AccessKey       string
    33  	SecretKey       string
    34  	RoleArn         string
    35  	RoleExternalId  string
    36  	RoleSessionName string
    37  	StsEndpoint     string
    38  
    39  	RequesterPays bool
    40  	Region        string
    41  	RegionSet     bool
    42  
    43  	StorageClass string
    44  
    45  	UseSSE     bool
    46  	UseKMS     bool
    47  	KMSKeyID   string
    48  	SseC       string
    49  	SseCDigest string
    50  	ACL        string
    51  
    52  	Subdomain bool
    53  
    54  	Credentials *credentials.Credentials
    55  	Session     *session.Session
    56  }
    57  
    58  var s3Session *session.Session
    59  
    60  func (c *S3Config) Init() *S3Config {
    61  	if c.Region == "" {
    62  		c.Region = "us-east-1"
    63  	}
    64  	if c.StorageClass == "" {
    65  		c.StorageClass = "STANDARD"
    66  	}
    67  	return c
    68  }
    69  
    70  func (c *S3Config) ToAwsConfig(flags *FlagStorage) (*aws.Config, error) {
    71  	awsConfig := (&aws.Config{
    72  		Region: &c.Region,
    73  		Logger: GetLogger("s3"),
    74  	}).WithHTTPClient(&http.Client{
    75  		Transport: &defaultHTTPTransport,
    76  		Timeout:   flags.HTTPTimeout,
    77  	})
    78  	if flags.DebugS3 {
    79  		awsConfig.LogLevel = aws.LogLevel(aws.LogDebug | aws.LogDebugWithRequestErrors)
    80  	}
    81  
    82  	if c.Credentials == nil {
    83  		if c.AccessKey != "" {
    84  			c.Credentials = credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, "")
    85  		}
    86  	}
    87  	if flags.Endpoint != "" {
    88  		awsConfig.Endpoint = &flags.Endpoint
    89  	}
    90  
    91  	awsConfig.S3ForcePathStyle = aws.Bool(!c.Subdomain)
    92  
    93  	if c.Session == nil {
    94  		if s3Session == nil {
    95  			var err error
    96  			s3Session, err = session.NewSessionWithOptions(session.Options{
    97  				Profile:           c.Profile,
    98  				SharedConfigState: session.SharedConfigEnable,
    99  			})
   100  			if err != nil {
   101  				return nil, err
   102  			}
   103  		}
   104  		c.Session = s3Session
   105  	}
   106  
   107  	if c.RoleArn != "" {
   108  		c.Credentials = stscreds.NewCredentials(stsConfigProvider{c}, c.RoleArn,
   109  			func(p *stscreds.AssumeRoleProvider) {
   110  				if c.RoleExternalId != "" {
   111  					p.ExternalID = &c.RoleExternalId
   112  				}
   113  				p.RoleSessionName = c.RoleSessionName
   114  			})
   115  	}
   116  
   117  	if c.Credentials != nil {
   118  		awsConfig.Credentials = c.Credentials
   119  	}
   120  
   121  	if c.SseC != "" {
   122  		key, err := base64.StdEncoding.DecodeString(c.SseC)
   123  		if err != nil {
   124  			return nil, fmt.Errorf("sse-c is not base64-encoded: %v", err)
   125  		}
   126  
   127  		c.SseC = string(key)
   128  		m := md5.Sum(key)
   129  		c.SseCDigest = base64.StdEncoding.EncodeToString(m[:])
   130  	}
   131  
   132  	return awsConfig, nil
   133  }
   134  
   135  type stsConfigProvider struct {
   136  	*S3Config
   137  }
   138  
   139  func (c stsConfigProvider) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
   140  	config := c.Session.ClientConfig(serviceName, cfgs...)
   141  	if c.Credentials != nil {
   142  		config.Config.Credentials = c.Credentials
   143  	}
   144  	if c.StsEndpoint != "" {
   145  		config.Endpoint = c.StsEndpoint
   146  	}
   147  
   148  	return config
   149  }