package remotefileupload import ( "bytes" "fmt" "net/http" "path/filepath" "fiskerinc.com/modules/logger" "fiskerinc.com/modules/utils/envtool" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) var ( awsBucketRegion = envtool.GetEnv("AWS_REGION", "us-west-2") awsBucketName = envtool.GetEnv("AWS_BUCKET_NAME", "fisker-data-test") awsFileExtension = envtool.GetEnv("AWS_FILE_EXTENSION", ".csv") ) // NewS3Uploader creates a new S3Uploader instance using env variables // requires ENV vars: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN func NewS3Uploader(awsBucketName string) Uploader { var uploader *S3Uploader cfg := aws.NewConfig().WithRegion(awsBucketRegion) sess := session.Must(session.NewSession()) uploader = &S3Uploader{ service: s3.New(sess, cfg), bucketRegion: awsBucketRegion, bucketName: awsBucketName, fileExtension: awsFileExtension, } return uploader } type S3Uploader struct { service *s3.S3 bucketRegion string bucketName string fileExtension string } // Upload creates a new object within S3 under the designated path // // objects can be up to 15MB before requiring multi-upload func (s *S3Uploader) Upload(block []byte, logValue LogPayload, filePath ...string) (string, error) { fileType := http.DetectContentType(block) path := s.s3ObjectURL(filePath) input := &s3.PutObjectInput{ Bucket: aws.String(s.bucketName), Key: aws.String(path), ContentType: aws.String(fileType), Body: bytes.NewReader(block), } logger.Debug().Str(logValue.Title, logValue.Value).Msgf("sending block of length %d to aws object: %s", len(block), path) _, err := s.service.PutObject(input) if err != nil { return "", err } logger.Debug().Str(logValue.Title, logValue.Value).Msgf("upload complete") return path, nil } // s3ObjectURL is the URL formatter for an S3 object func (s *S3Uploader) s3ObjectURL(filePath []string) string { fileName := fmt.Sprintf("%s%s", "raw", s.fileExtension) finalPath := filepath.Join(filepath.Join(filePath...), fileName) return finalPath }