-
Notifications
You must be signed in to change notification settings - Fork 10
/
aws.go
156 lines (133 loc) · 3.89 KB
/
aws.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"bytes"
"os"
"path/filepath"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
// setup a new aws session
func awsSession(conf AWS) *session.Session {
var sess *session.Session
var err error
if conf.Address != "" {
sess, err = session.NewSession(&aws.Config{
Endpoint: aws.String(conf.Address),
Region: aws.String(conf.BucketRegion),
Credentials: credentials.NewStaticCredentials(conf.Pub, conf.Priv, ""),
S3ForcePathStyle: aws.Bool(true),
})
} else {
sess, err = session.NewSession(&aws.Config{
Region: aws.String(conf.BucketRegion),
Credentials: credentials.NewStaticCredentials(conf.Pub, conf.Priv, ""),
})
}
if err != nil {
// TODO
panic(err)
}
return sess
}
// download txDir/name from s3 bucket and save it to $PWD/name
func awsDownload(sess *session.Session, conf AWS, txDir, name string) (*os.File, error) {
file, err := os.Create(name)
if err != nil {
return nil, err
}
defer file.Close()
downloader := s3manager.NewDownloader(sess)
numBytes, err := downloader.Download(file,
&s3.GetObjectInput{
Bucket: aws.String(conf.Bucket),
Key: aws.String(filepath.Join(txDir, name)),
})
if err != nil {
return nil, err
}
_ = numBytes
return file, nil
}
// upload the dataBytes to txDir/name in the s3 bucket
func awsUpload(sess *session.Session, conf AWS, txDir, name string, dataBytes []byte) error {
uploader := s3manager.NewUploader(sess)
_, err := uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(conf.Bucket),
Key: aws.String(filepath.Join(txDir, name)),
Body: bytes.NewBuffer(dataBytes),
})
return err
}
// make a directory (ie. an empty file) called dirName in the bucket
func awsMkdir(sess *session.Session, conf AWS, dirName string) error {
svc := s3.New(sess)
_, err := svc.PutObject(&s3.PutObjectInput{
Bucket: aws.String(conf.Bucket),
Key: aws.String(dirName),
})
return err
}
// delete an object from the bucket
func awsDelete(sess *session.Session, conf AWS, objName string) error {
svc := s3.New(sess)
_, err := svc.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(conf.Bucket),
Key: aws.String(objName),
})
return err
}
// download all files in the dir and return list of file names
func awsDownloadFilesInDir(sess *session.Session, conf AWS, dirPath string) ([]string, error) {
svc := s3.New(sess)
// list all items in bucket
resp, err := svc.ListObjectsV2(&s3.ListObjectsV2Input{Bucket: aws.String(conf.Bucket)})
if err != nil {
return nil, err
}
dirPath = strings.TrimSuffix(dirPath, "/")
// get only those in our folder
files := []string{}
for _, item := range resp.Contents {
key := *item.Key
keyDir := filepath.Dir(key)
keyBase := strings.TrimPrefix(key, keyDir)
keyBase = strings.TrimPrefix(keyBase, "/")
if keyDir == dirPath && keyBase != "" {
files = append(files, keyBase)
}
}
if len(files) == 0 {
return []string{}, nil
}
for _, f := range files {
// download all files in folder
_, err := awsDownload(sess, conf, dirPath, f)
if err != nil {
return nil, err
}
}
return files, nil
}
// return all files with prefix "chainName/keyName/"
// eg. will return "chainName/keyName/foo" but not "chainName/keyName/" itself
func awsListFilesInDir(sess *session.Session, conf AWS, chainName, keyName string) ([]string, error) {
svc := s3.New(sess)
filePath := filepath.Join(chainName, keyName) + "/"
// list all items in bucket
resp, err := svc.ListObjectsV2(&s3.ListObjectsV2Input{Bucket: aws.String(conf.Bucket)})
if err != nil {
return nil, err
}
files := []string{}
for _, item := range resp.Contents {
key := *item.Key
if strings.HasPrefix(key, filePath) && len(key) > len(filePath) {
files = append(files, key)
}
}
return files, nil
}