-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add internal/controller/internal/objectstorage
Signed-off-by: Ryotaro Banno <[email protected]>
- Loading branch information
1 parent
3be1c85
commit dd197c5
Showing
6 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
internal/controller/internal/objectstorage/objectstorage.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package objectstorage | ||
|
||
import "context" | ||
|
||
type Bucket interface { | ||
Exists(ctx context.Context, path string) (bool, error) | ||
|
||
// Delete deletes the specified object. Delete will return nil if the object is not found. | ||
Delete(ctx context.Context, path string) error | ||
} |
70 changes: 70 additions & 0 deletions
70
internal/controller/internal/objectstorage/objectstorage_mock.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package objectstorage | ||
|
||
import ( | ||
"context" | ||
"crypto/tls" | ||
"crypto/x509" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/aws/aws-sdk-go-v2/aws" | ||
awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" | ||
"github.com/aws/aws-sdk-go-v2/config" | ||
"github.com/aws/aws-sdk-go-v2/service/s3" | ||
"github.com/aws/aws-sdk-go-v2/service/s3/types" | ||
) | ||
|
||
type S3Bucket struct { | ||
caPEMCerts []byte | ||
bucketName, endpoint string | ||
s3Client *s3.Client | ||
} | ||
|
||
var _ Bucket = &S3Bucket{} | ||
|
||
func NewS3Bucket(ctx context.Context, bucketName, endpoint, accessKeyID, secretAccessKey string, caPEMCerts []byte) (*S3Bucket, error) { | ||
var httpClient config.HTTPClient | ||
if caPEMCerts != nil { | ||
certPool := x509.NewCertPool() | ||
if ok := certPool.AppendCertsFromPEM(caPEMCerts); !ok { | ||
return nil, errors.New("failed to append certs to pool") | ||
} | ||
httpClient = awshttp.NewBuildableClient().WithTransportOptions(func(tr *http.Transport) { | ||
if tr.TLSClientConfig == nil { | ||
tr.TLSClientConfig = &tls.Config{} | ||
} | ||
tr.TLSClientConfig.RootCAs = certPool | ||
}) | ||
} | ||
|
||
sdkConfig, err := config.LoadDefaultConfig( | ||
ctx, | ||
config.WithHTTPClient(httpClient), | ||
config.WithRegion("ceph"), | ||
config.WithCredentialsProvider( | ||
aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) { | ||
return aws.Credentials{ | ||
AccessKeyID: accessKeyID, | ||
SecretAccessKey: secretAccessKey, | ||
}, nil | ||
}), | ||
), | ||
) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to load default config: %w", err) | ||
} | ||
s3Client := s3.NewFromConfig(sdkConfig, func(o *s3.Options) { | ||
o.BaseEndpoint = &endpoint | ||
o.UsePathStyle = true | ||
}) | ||
|
||
return &S3Bucket{caPEMCerts, bucketName, endpoint, s3Client}, nil | ||
} | ||
|
||
func (b *S3Bucket) Exists(ctx context.Context, key string) (bool, error) { | ||
if _, err := b.s3Client.HeadObject(ctx, &s3.HeadObjectInput{ | ||
Bucket: &b.bucketName, | ||
Key: &key, | ||
}); err != nil { | ||
var notFound *types.NotFound | ||
if errors.As(err, ¬Found) { | ||
return false, nil | ||
} | ||
return false, fmt.Errorf("HeadObject failed: %s: %s: %s: %w", b.endpoint, b.bucketName, key, err) | ||
} | ||
|
||
return true, nil | ||
} | ||
|
||
func (b *S3Bucket) Delete(ctx context.Context, key string) error { | ||
if _, err := b.s3Client.DeleteObject(ctx, &s3.DeleteObjectInput{ | ||
Bucket: &b.bucketName, | ||
Key: &key, | ||
}); err != nil { | ||
var notFound *types.NotFound | ||
if errors.As(err, ¬Found) { | ||
return nil | ||
} | ||
return fmt.Errorf("Delete failed: %s: %s: %s: %w", b.endpoint, b.bucketName, key, err) | ||
} | ||
return nil | ||
} |