228 lines
6.2 KiB
Go
228 lines
6.2 KiB
Go
/*
|
|
* Copyright 2022 The Dragonfly Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package objectstorage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"time"
|
|
|
|
huaweiobs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
|
|
)
|
|
|
|
type obs struct {
|
|
// OBS client.
|
|
client *huaweiobs.ObsClient
|
|
}
|
|
|
|
// New oss instance.
|
|
func newOBS(region, endpoint, accessKey, secretKey string) (ObjectStorage, error) {
|
|
client, err := huaweiobs.New(accessKey, secretKey, endpoint)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("new obs client failed: %s", err)
|
|
}
|
|
|
|
return &obs{
|
|
client: client,
|
|
}, nil
|
|
}
|
|
|
|
// GetBucketMetadata returns metadata of bucket.
|
|
func (o *obs) GetBucketMetadata(ctx context.Context, bucketName string) (*BucketMetadata, error) {
|
|
if _, err := o.client.GetBucketMetadata(&huaweiobs.GetBucketMetadataInput{Bucket: bucketName}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &BucketMetadata{
|
|
Name: bucketName,
|
|
}, nil
|
|
}
|
|
|
|
// CreateBucket creates bucket of object storage.
|
|
func (o *obs) CreateBucket(ctx context.Context, bucketName string) error {
|
|
_, err := o.client.CreateBucket(&huaweiobs.CreateBucketInput{Bucket: bucketName})
|
|
return err
|
|
}
|
|
|
|
// DeleteBucket deletes bucket of object storage.
|
|
func (o *obs) DeleteBucket(ctx context.Context, bucketName string) error {
|
|
_, err := o.client.DeleteBucket(bucketName)
|
|
return err
|
|
}
|
|
|
|
// ListBucketMetadatas list bucket meta data of object storage.
|
|
func (o *obs) ListBucketMetadatas(ctx context.Context) ([]*BucketMetadata, error) {
|
|
resp, err := o.client.ListBuckets(&huaweiobs.ListBucketsInput{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var metadatas []*BucketMetadata
|
|
for _, bucket := range resp.Buckets {
|
|
metadatas = append(metadatas, &BucketMetadata{
|
|
Name: bucket.Name,
|
|
CreateAt: bucket.CreationDate,
|
|
})
|
|
}
|
|
|
|
return metadatas, nil
|
|
}
|
|
|
|
// GetObjectMetadata returns metadata of object.
|
|
func (o *obs) GetObjectMetadata(ctx context.Context, bucketName, objectKey string) (*ObjectMetadata, bool, error) {
|
|
metadata, err := o.client.GetObjectMetadata(&huaweiobs.GetObjectMetadataInput{Bucket: bucketName, Key: objectKey})
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "404") {
|
|
return nil, false, nil
|
|
}
|
|
|
|
return nil, false, err
|
|
}
|
|
|
|
object, err := o.client.GetObject(&huaweiobs.GetObjectInput{
|
|
GetObjectMetadataInput: huaweiobs.GetObjectMetadataInput{
|
|
Bucket: bucketName,
|
|
Key: objectKey,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
return &ObjectMetadata{
|
|
Key: objectKey,
|
|
ContentDisposition: object.ContentDisposition,
|
|
ContentEncoding: object.ContentEncoding,
|
|
ContentLanguage: object.ContentLanguage,
|
|
ContentLength: metadata.ContentLength,
|
|
ContentType: metadata.ContentType,
|
|
ETag: metadata.ETag,
|
|
Digest: metadata.Metadata[MetaDigest],
|
|
}, true, nil
|
|
}
|
|
|
|
// GetOject returns data of object.
|
|
func (o *obs) GetOject(ctx context.Context, bucketName, objectKey string) (io.ReadCloser, error) {
|
|
resp, err := o.client.GetObject(&huaweiobs.GetObjectInput{
|
|
GetObjectMetadataInput: huaweiobs.GetObjectMetadataInput{
|
|
Bucket: bucketName,
|
|
Key: objectKey,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp.Body, nil
|
|
}
|
|
|
|
// PutObject puts data of object.
|
|
func (o *obs) PutObject(ctx context.Context, bucketName, objectKey, digest string, reader io.Reader) error {
|
|
_, err := o.client.PutObject(&huaweiobs.PutObjectInput{
|
|
PutObjectBasicInput: huaweiobs.PutObjectBasicInput{
|
|
ObjectOperationInput: huaweiobs.ObjectOperationInput{
|
|
Bucket: bucketName,
|
|
Key: objectKey,
|
|
Metadata: map[string]string{
|
|
MetaDigest: digest,
|
|
},
|
|
},
|
|
},
|
|
Body: reader,
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
// DeleteObject deletes data of object.
|
|
func (o *obs) DeleteObject(ctx context.Context, bucketName, objectKey string) error {
|
|
_, err := o.client.DeleteObject(&huaweiobs.DeleteObjectInput{Bucket: bucketName, Key: objectKey})
|
|
return err
|
|
}
|
|
|
|
// ListObjectMetadatas returns metadata of objects.
|
|
func (o *obs) ListObjectMetadatas(ctx context.Context, bucketName, prefix, marker string, limit int64) ([]*ObjectMetadata, error) {
|
|
resp, err := o.client.ListObjects(&huaweiobs.ListObjectsInput{
|
|
ListObjsInput: huaweiobs.ListObjsInput{
|
|
Prefix: prefix,
|
|
MaxKeys: int(limit),
|
|
},
|
|
Bucket: bucketName,
|
|
Marker: marker,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var metadatas []*ObjectMetadata
|
|
for _, object := range resp.Contents {
|
|
metadatas = append(metadatas, &ObjectMetadata{
|
|
Key: object.Key,
|
|
ETag: object.ETag,
|
|
})
|
|
}
|
|
|
|
return metadatas, nil
|
|
}
|
|
|
|
// IsObjectExist returns whether the object exists.
|
|
func (o *obs) IsObjectExist(ctx context.Context, bucketName, objectKey string) (bool, error) {
|
|
_, isExist, err := o.GetObjectMetadata(ctx, bucketName, objectKey)
|
|
return isExist, err
|
|
}
|
|
|
|
// IsBucketExist returns whether the bucket exists.
|
|
func (o *obs) IsBucketExist(ctx context.Context, bucketName string) (bool, error) {
|
|
if _, err := o.client.HeadBucket(bucketName); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// GetSignURL returns sign url of object.
|
|
func (o *obs) GetSignURL(ctx context.Context, bucketName, objectKey string, method Method, expire time.Duration) (string, error) {
|
|
var obsHTTPMethod huaweiobs.HttpMethodType
|
|
switch method {
|
|
case MethodGet:
|
|
obsHTTPMethod = huaweiobs.HttpMethodGet
|
|
case MethodPut:
|
|
obsHTTPMethod = huaweiobs.HttpMethodPut
|
|
case MethodHead:
|
|
obsHTTPMethod = huaweiobs.HTTP_HEAD
|
|
case MethodPost:
|
|
obsHTTPMethod = huaweiobs.HttpMethodPost
|
|
case MethodDelete:
|
|
obsHTTPMethod = huaweiobs.HTTP_DELETE
|
|
default:
|
|
return "", fmt.Errorf("not support method %s", method)
|
|
}
|
|
|
|
resp, err := o.client.CreateSignedUrl(&huaweiobs.CreateSignedUrlInput{
|
|
Bucket: bucketName,
|
|
Key: objectKey,
|
|
Method: obsHTTPMethod,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return resp.SignedUrl, nil
|
|
}
|