Merge pull request #2772 from swordqiu/hotfix/qj-bucket-set-acl-batch-set

fix: allow set object acl in batch
This commit is contained in:
yunion-ci-robot
2019-09-07 13:01:16 +08:00
committed by GitHub
4 changed files with 63 additions and 19 deletions
+4 -7
View File
@@ -213,15 +213,12 @@ func init() {
})
type BucketSetAclOptions struct {
ID string `help:"ID or name of bucket" json:"-"`
ACL string `help:"ACL to set" choices:"default|private|public-read|public-read-write"`
Key string `help:"Optional object key"`
ID string `help:"ID or name of bucket" json:"-"`
ACL string `help:"ACL to set" choices:"default|private|public-read|public-read-write" json:"acl"`
Key []string `help:"Optional object key" json:"key"`
}
R(&BucketSetAclOptions{}, "bucket-set-acl", "Set ACL of bucket or object", func(s *mcclient.ClientSession, args *BucketSetAclOptions) error {
params, err := options.StructToParams(args)
if err != nil {
return err
}
params := jsonutils.Marshal(args)
result, err := modules.Buckets.PerformAction(s, args.ID, "acl", params)
if err != nil {
return err
+14
View File
@@ -1,3 +1,17 @@
// Copyright 2019 Yunion
//
// 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 db
import (
+13 -2
View File
@@ -23,6 +23,7 @@ import (
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/s3cli"
@@ -166,15 +167,25 @@ type ICloudObject interface {
SetAcl(acl TBucketACLType) error
}
func ICloudObject2BaseCloudObject(obj ICloudObject) SBaseCloudObject {
return SBaseCloudObject{
func ICloudObject2JSONObject(obj ICloudObject) jsonutils.JSONObject {
obj2 := struct {
Key string
SizeBytes int64
StorageClass string
ETag string
LastModified time.Time
ContentType string
Acl string
}{
Key: obj.GetKey(),
SizeBytes: obj.GetSizeBytes(),
StorageClass: obj.GetStorageClass(),
ETag: obj.GetETag(),
LastModified: obj.GetLastModified(),
ContentType: obj.GetContentType(),
Acl: string(obj.GetAcl()),
}
return jsonutils.Marshal(obj2)
}
func (o *SBaseCloudObject) GetKey() string {
+32 -10
View File
@@ -599,7 +599,7 @@ func (bucket *SBucket) GetDetailsObjects(
}
retArray := jsonutils.NewArray()
for i := range objects {
retArray.Add(jsonutils.Marshal(cloudprovider.ICloudObject2BaseCloudObject(objects[i])))
retArray.Add(cloudprovider.ICloudObject2JSONObject(objects[i]))
}
ret := jsonutils.NewDict()
ret.Add(retArray, "objects")
@@ -882,7 +882,6 @@ func (bucket *SBucket) PerformAcl(
data jsonutils.JSONObject,
) (jsonutils.JSONObject, error) {
aclStr, _ := data.GetString("acl")
objKey, _ := data.GetString("key")
switch cloudprovider.TBucketACLType(aclStr) {
case cloudprovider.ACLPrivate, cloudprovider.ACLAuthRead, cloudprovider.ACLPublicRead, cloudprovider.ACLPublicReadWrite:
// do nothing
@@ -895,7 +894,8 @@ func (bucket *SBucket) PerformAcl(
return nil, httperrors.NewInternalServerError("fail to find external bucket: %s", err)
}
if len(objKey) == 0 {
objKey, _ := data.Get("key")
if objKey == nil {
err = iBucket.SetAcl(cloudprovider.TBucketACLType(aclStr))
if err != nil {
return nil, httperrors.NewInternalServerError("setAcl error %s", err)
@@ -905,16 +905,38 @@ func (bucket *SBucket) PerformAcl(
if err != nil {
return nil, httperrors.NewInternalServerError("syncWithCloudBucket error %s", err)
}
} else {
object, err := cloudprovider.GetIObject(iBucket, objKey)
if err != nil {
if err == cloudprovider.ErrNotFound {
return nil, httperrors.NewResourceNotFoundError("object %s not found", objKey)
} else {
return nil, nil
}
var keys []string
switch jsonObj := objKey.(type) {
case *jsonutils.JSONString:
key, _ := jsonObj.GetString()
keys = []string{key}
case *jsonutils.JSONArray:
keys = jsonObj.GetStringArray()
}
var objects []cloudprovider.ICloudObject
for _, key := range keys {
if strings.HasSuffix(key, "/") {
objs, err := cloudprovider.GetIObjects(iBucket, key, true)
if err != nil {
return nil, httperrors.NewInternalServerError("iBucket.GetIObjects error %s", err)
}
objects = append(objects, objs...)
} else {
object, err := cloudprovider.GetIObject(iBucket, key)
if err != nil {
if err == cloudprovider.ErrNotFound {
return nil, httperrors.NewResourceNotFoundError("object %s not found", objKey)
} else {
return nil, httperrors.NewInternalServerError("iBucket.GetIObject error %s", err)
}
}
objects = append(objects, object)
}
err = object.SetAcl(cloudprovider.TBucketACLType(aclStr))
}
for _, object := range objects {
err := object.SetAcl(cloudprovider.TBucketACLType(aclStr))
if err != nil {
return nil, httperrors.NewInternalServerError("setAcl error %s", err)
}