@@ -11,6 +11,7 @@ import (
11
11
12
12
"github.com/aws/aws-sdk-go-v2/aws"
13
13
"github.com/aws/aws-sdk-go-v2/config"
14
+ "github.com/aws/aws-sdk-go-v2/credentials"
14
15
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
15
16
"github.com/aws/aws-sdk-go-v2/service/s3"
16
17
log "github.com/sirupsen/logrus"
@@ -64,18 +65,13 @@ func New(u url.URL, opts ...Option) *S3 {
64
65
}
65
66
66
67
func (s * S3 ) Pull (source , target string ) (int64 , error ) {
67
- // TODO: need to find way to include cli opts and cli_s3_cp_opts
68
- // old was:
69
- // aws ${AWS_CLI_OPTS} s3 cp ${AWS_CLI_S3_CP_OPTS} "${DB_RESTORE_TARGET}" $TMPRESTORE
70
-
71
- bucket , path := s .url .Hostname (), path .Join (s .url .Path , source )
72
- // The session the S3 Downloader will use
73
- cfg , err := getConfig (s .endpoint )
68
+ // get the s3 client
69
+ client , err := s .getClient ()
74
70
if err != nil {
75
- return 0 , fmt .Errorf ("failed to load AWS config : %v" , err )
71
+ return 0 , fmt .Errorf ("failed to get AWS client : %v" , err )
76
72
}
77
73
78
- client := s3 . NewFromConfig ( cfg )
74
+ bucket , path := s . url . Hostname (), path . Join ( s . url . Path , source )
79
75
80
76
// Create a downloader with the session and default options
81
77
downloader := manager .NewDownloader (client )
@@ -99,18 +95,13 @@ func (s *S3) Pull(source, target string) (int64, error) {
99
95
}
100
96
101
97
func (s * S3 ) Push (target , source string ) (int64 , error ) {
102
- // TODO: need to find way to include cli opts and cli_s3_cp_opts
103
- // old was:
104
- // aws ${AWS_CLI_OPTS} s3 cp ${AWS_CLI_S3_CP_OPTS} "${DB_RESTORE_TARGET}" $TMPRESTORE
105
-
106
- bucket , key := s .url .Hostname (), s .url .Path
107
- // The session the S3 Downloader will use
108
- cfg , err := getConfig (s .endpoint )
98
+ // get the s3 client
99
+ client , err := s .getClient ()
109
100
if err != nil {
110
- return 0 , fmt .Errorf ("failed to load AWS config : %v" , err )
101
+ return 0 , fmt .Errorf ("failed to get AWS client : %v" , err )
111
102
}
103
+ bucket , key := s .url .Hostname (), s .url .Path
112
104
113
- client := s3 .NewFromConfig (cfg )
114
105
// Create an uploader with the session and default options
115
106
uploader := manager .NewUploader (client )
116
107
@@ -142,17 +133,14 @@ func (s *S3) URL() string {
142
133
}
143
134
144
135
func (s * S3 ) ReadDir (dirname string ) ([]fs.FileInfo , error ) {
145
- // Get the AWS config
146
- cfg , err := getConfig ( s . endpoint )
136
+ // get the s3 client
137
+ client , err := s . getClient ( )
147
138
if err != nil {
148
- return nil , fmt .Errorf ("failed to load AWS config : %v" , err )
139
+ return nil , fmt .Errorf ("failed to get AWS client : %v" , err )
149
140
}
150
141
151
- // Create a new S3 service client
152
- svc := s3 .NewFromConfig (cfg )
153
-
154
142
// Call ListObjectsV2 with your bucket and prefix
155
- result , err := svc .ListObjectsV2 (context .TODO (), & s3.ListObjectsV2Input {Bucket : aws .String (s .url .Hostname ()), Prefix : aws .String (dirname )})
143
+ result , err := client .ListObjectsV2 (context .TODO (), & s3.ListObjectsV2Input {Bucket : aws .String (s .url .Hostname ()), Prefix : aws .String (dirname )})
156
144
if err != nil {
157
145
return nil , fmt .Errorf ("failed to list objects, %v" , err )
158
146
}
@@ -171,17 +159,14 @@ func (s *S3) ReadDir(dirname string) ([]fs.FileInfo, error) {
171
159
}
172
160
173
161
func (s * S3 ) Remove (target string ) error {
174
- // Get the AWS config
175
- cfg , err := getConfig ( s . endpoint )
162
+ // Get the AWS client
163
+ client , err := s . getClient ( )
176
164
if err != nil {
177
- return fmt .Errorf ("failed to load AWS config : %v" , err )
165
+ return fmt .Errorf ("failed to get AWS client : %v" , err )
178
166
}
179
167
180
- // Create a new S3 service client
181
- svc := s3 .NewFromConfig (cfg )
182
-
183
168
// Call DeleteObject with your bucket and the key of the object you want to delete
184
- _ , err = svc .DeleteObject (context .TODO (), & s3.DeleteObjectInput {
169
+ _ , err = client .DeleteObject (context .TODO (), & s3.DeleteObjectInput {
185
170
Bucket : aws .String (s .url .Hostname ()),
186
171
Key : aws .String (target ),
187
172
})
@@ -192,9 +177,44 @@ func (s *S3) Remove(target string) error {
192
177
return nil
193
178
}
194
179
180
+ func (s * S3 ) getClient () (* s3.Client , error ) {
181
+ // Get the AWS config
182
+ cleanEndpoint := getEndpoint (s .endpoint )
183
+ opts := []func (* config.LoadOptions ) error {
184
+ config .WithEndpointResolverWithOptions (
185
+ aws .EndpointResolverWithOptionsFunc (func (service , region string , options ... interface {}) (aws.Endpoint , error ) {
186
+ return aws.Endpoint {URL : cleanEndpoint }, nil
187
+ }),
188
+ ),
189
+ }
190
+ if log .IsLevelEnabled (log .TraceLevel ) {
191
+ opts = append (opts , config .WithClientLogMode (aws .LogRequestWithBody | aws .LogResponse ))
192
+ }
193
+ if s .region != "" {
194
+ opts = append (opts , config .WithRegion (s .region ))
195
+ }
196
+ if s .accessKeyId != "" {
197
+ opts = append (opts , config .WithCredentialsProvider (credentials .NewStaticCredentialsProvider (
198
+ s .accessKeyId ,
199
+ s .secretAccessKey ,
200
+ "" ,
201
+ )))
202
+ }
203
+ cfg , err := config .LoadDefaultConfig (context .TODO (),
204
+ opts ... ,
205
+ )
206
+ if err != nil {
207
+ return nil , fmt .Errorf ("failed to load AWS config: %v" , err )
208
+ }
209
+
210
+ // Create a new S3 service client
211
+ return s3 .NewFromConfig (cfg ), nil
212
+ }
213
+
214
+ // getEndpoint returns a clean (for AWS client) endpoint. Normally, this is unchanged,
215
+ // but for some reason, the lookup gets flaky when the endpoint is 127.0.0.1,
216
+ // so in that case, set it to localhost explicitly.
195
217
func getEndpoint (endpoint string ) string {
196
- // for some reason, the lookup gets flaky when the endpoint is 127.0.0.1
197
- // so you have to set it to localhost explicitly.
198
218
e := endpoint
199
219
u , err := url .Parse (endpoint )
200
220
if err == nil {
@@ -210,24 +230,6 @@ func getEndpoint(endpoint string) string {
210
230
return e
211
231
}
212
232
213
- func getConfig (endpoint string ) (aws.Config , error ) {
214
- cleanEndpoint := getEndpoint (endpoint )
215
- opts := []func (* config.LoadOptions ) error {
216
- config .WithEndpointResolverWithOptions (
217
- aws .EndpointResolverWithOptionsFunc (func (service , region string , options ... interface {}) (aws.Endpoint , error ) {
218
- return aws.Endpoint {URL : cleanEndpoint }, nil
219
- }),
220
- ),
221
- }
222
- if log .IsLevelEnabled (log .TraceLevel ) {
223
- opts = append (opts , config .WithClientLogMode (aws .LogRequestWithBody | aws .LogResponse ))
224
- }
225
- return config .LoadDefaultConfig (context .TODO (),
226
- opts ... ,
227
- )
228
-
229
- }
230
-
231
233
type s3FileInfo struct {
232
234
name string
233
235
lastModified time.Time
0 commit comments