2020-12-09 15:31:34 +00:00
|
|
|
package backend
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
2021-02-09 18:43:39 +00:00
|
|
|
"github.com/pkg/errors"
|
2021-12-06 13:29:39 +00:00
|
|
|
"github.com/snyk/driftctl/pkg/envproxy"
|
2020-12-09 15:31:34 +00:00
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/service/s3"
|
|
|
|
"github.com/aws/aws-sdk-go/service/s3/s3iface"
|
|
|
|
)
|
|
|
|
|
2021-02-23 12:44:17 +00:00
|
|
|
const BackendKeyS3 = "s3"
|
2020-12-09 15:31:34 +00:00
|
|
|
|
|
|
|
type S3Backend struct {
|
|
|
|
input s3.GetObjectInput
|
|
|
|
reader io.ReadCloser
|
|
|
|
S3Client s3iface.S3API
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewS3Reader(path string) (*S3Backend, error) {
|
|
|
|
|
|
|
|
backend := S3Backend{}
|
|
|
|
bucketPath := strings.Split(path, "/")
|
|
|
|
if len(bucketPath) < 2 {
|
2021-02-10 13:37:59 +00:00
|
|
|
return nil, errors.Errorf("Unable to parse S3 path: %s. Must be BUCKET_NAME/PATH/TO/OBJECT", path)
|
2020-12-09 15:31:34 +00:00
|
|
|
}
|
|
|
|
bucket := bucketPath[0]
|
|
|
|
key := strings.Join(bucketPath[1:], "/")
|
|
|
|
|
|
|
|
backend.input = s3.GetObjectInput{
|
|
|
|
Key: &key,
|
|
|
|
Bucket: &bucket,
|
|
|
|
}
|
2021-07-02 12:48:25 +00:00
|
|
|
envProxy := envproxy.NewEnvProxy("DCTL_S3_", "AWS_")
|
|
|
|
envProxy.Apply()
|
2020-12-09 15:31:34 +00:00
|
|
|
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
|
|
SharedConfigState: session.SharedConfigEnable,
|
|
|
|
}))
|
2021-07-02 12:48:25 +00:00
|
|
|
envProxy.Restore()
|
2020-12-09 15:31:34 +00:00
|
|
|
backend.S3Client = s3.New(sess)
|
|
|
|
return &backend, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *S3Backend) Read(p []byte) (n int, err error) {
|
|
|
|
if s.reader == nil {
|
|
|
|
response, err := s.S3Client.GetObject(&s.input)
|
|
|
|
if err != nil {
|
|
|
|
requestFailure, ok := err.(s3.RequestFailure)
|
|
|
|
if ok {
|
2021-02-10 13:37:59 +00:00
|
|
|
return 0, errors.Errorf(
|
|
|
|
"Error reading state '%s' from s3 bucket '%s': %s",
|
|
|
|
*s.input.Key,
|
|
|
|
*s.input.Bucket,
|
|
|
|
requestFailure.Message(),
|
2021-02-09 18:43:39 +00:00
|
|
|
)
|
2020-12-09 15:31:34 +00:00
|
|
|
}
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
s.reader = response.Body
|
|
|
|
}
|
|
|
|
return s.reader.Read(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *S3Backend) Close() error {
|
|
|
|
if s.reader != nil {
|
|
|
|
return s.reader.Close()
|
|
|
|
}
|
2021-02-09 18:43:39 +00:00
|
|
|
return errors.New("Unable to close reader as nothing was opened")
|
2020-12-09 15:31:34 +00:00
|
|
|
}
|