fix(region): qcloud bucket set cors

This commit is contained in:
lvyangyang
2020-11-19 14:36:55 +08:00
parent 63d1d27069
commit f1b428be07
9 changed files with 170 additions and 55 deletions
+9 -4
View File
@@ -398,6 +398,7 @@ func init() {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
RuleId string
}
R(&BucketSetCorsOption{}, "bucket-set-cors", "Set bucket cors", func(s *mcclient.ClientSession, args *BucketSetCorsOption) error {
@@ -407,8 +408,9 @@ func init() {
AllowedHeaders: args.AllowedHeaders,
MaxAgeSeconds: args.MaxAgeSeconds,
ExposeHeaders: args.ExposeHeaders,
Id: args.RuleId,
}
rules := api.BucketCORSRules{Rules: []api.BucketCORSRule{rule}}
rules := api.BucketCORSRules{Data: []api.BucketCORSRule{rule}}
result, err := modules.Buckets.PerformAction(s, args.ID, "set-cors", jsonutils.Marshal(rules))
if err != nil {
return err
@@ -430,10 +432,13 @@ func init() {
})
type BucketDeleteCorsOption struct {
ID string `help:"ID or name of bucket" json:"-"`
ID string `help:"ID or name of bucket" json:"-"`
Id []string `"help:Id of rules to delete"`
}
R(&BucketGetWebsiteConfOption{}, "bucket-delete-cors", "Delete bucket cors", func(s *mcclient.ClientSession, args *BucketGetWebsiteConfOption) error {
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-cors", nil)
R(&BucketDeleteCorsOption{}, "bucket-delete-cors", "Delete bucket cors", func(s *mcclient.ClientSession, args *BucketDeleteCorsOption) error {
input := api.BucketCORSRuleDeleteInput{}
input.Id = args.Id
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-cors", jsonutils.Marshal(input))
if err != nil {
return err
}
+10 -4
View File
@@ -225,18 +225,24 @@ type BucketCORSRule struct {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
// 规则区别标识
Id string
}
type BucketCORSRules struct {
Rules []BucketCORSRule
Data []BucketCORSRule `json:"data"`
}
type BucketCORSRuleDeleteInput struct {
Id []string
}
func (input *BucketCORSRules) Validate() error {
for i := range input.Rules {
if len(input.Rules[i].AllowedOrigins) == 0 {
for i := range input.Data {
if len(input.Data[i].AllowedOrigins) == 0 {
return httperrors.NewMissingParameterError("allowed_origins")
}
if len(input.Rules[i].AllowedMethods) == 0 {
if len(input.Data[i].AllowedMethods) == 0 {
return httperrors.NewMissingParameterError("allowed_methods")
}
}
+13 -7
View File
@@ -15,17 +15,23 @@
package compute
const (
CDN_AREA_MAINLAND = "mainland"
CDN_AREA_OVERSEAS = "overseas"
CDN_AREA_GLOBAL = "global"
CDN_ORIGIN_TYPE_DOMAIN = "domain"
CDN_ORIGIN_TYPE_IP = "ip"
CDN_ORIGIN_TYPE_BUCKET = "bucket"
CDN_DOMAIN_STATUS_ONLINE = "online"
CDN_DOMAIN_STATUS_OFFLINE = "offline"
CDN_DOMAIN_STATUS_PROCESSING = "processing"
CDN_DOMAIN_STATUS_REJECTED = "rejected"
CDN_DOMAIN_AREA_MAINLAND = "mainland"
CDN_DOMAIN_AREA_OVERSEAS = "overseas"
CDN_DOMAIN_AREA_GLOBAL = "global"
CDN_DOMAIN_ORIGIN_TYPE_DOMAIN = "domain"
CDN_DOMAIN_ORIGIN_TYPE_IP = "ip"
CDN_DOMAIN_ORIGIN_TYPE_BUCKET = "bucket"
)
type CdnDomain struct {
// cdn加速域名
Domain string
// 状态 rejected(域名未审核)|processing(部署中)|online|offline
Status string
// 区域 mainland|overseas|global
Area string
// cdn Cname
@@ -37,5 +43,5 @@ type CdnDomain struct {
}
type CdnDomains struct {
Domains []CdnDomain
Data []CdnDomain `json:"data"`
}
+2
View File
@@ -17,6 +17,8 @@ package cloudprovider
type SCdnDomain struct {
// cdn加速域名
Domain string
// 状态 rejected(域名未审核)|processing(部署中)|online|offline
Status string
// 区域 mainland|overseas|global
Area string
// cdn Cname
+3 -1
View File
@@ -105,6 +105,8 @@ type SBucketCORSRule struct {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
// 规则区别标识
Id string
}
type SBucketRefererConf struct {
@@ -216,7 +218,7 @@ type ICloudBucket interface {
SetCORS(rules []SBucketCORSRule) error
GetCORSRules() ([]SBucketCORSRule, error)
DeleteCORS() error
DeleteCORS(id []string) error
SetReferer(conf SBucketRefererConf) error
GetReferer() (SBucketRefererConf, error)
+14 -11
View File
@@ -1367,13 +1367,14 @@ func (bucket *SBucket) PerformSetCors(
return nil, errors.Wrap(err, "GetIBucket")
}
rules := []cloudprovider.SBucketCORSRule{}
for i := range input.Rules {
for i := range input.Data {
rules = append(rules, cloudprovider.SBucketCORSRule{
AllowedOrigins: input.Rules[i].AllowedOrigins,
AllowedMethods: input.Rules[i].AllowedMethods,
AllowedHeaders: input.Rules[i].AllowedHeaders,
MaxAgeSeconds: input.Rules[i].MaxAgeSeconds,
ExposeHeaders: input.Rules[i].ExposeHeaders,
AllowedOrigins: input.Data[i].AllowedOrigins,
AllowedMethods: input.Data[i].AllowedMethods,
AllowedHeaders: input.Data[i].AllowedHeaders,
MaxAgeSeconds: input.Data[i].MaxAgeSeconds,
ExposeHeaders: input.Data[i].ExposeHeaders,
Id: input.Data[i].Id,
})
}
err = iBucket.SetCORS(rules)
@@ -1388,7 +1389,7 @@ func (bucket *SBucket) PerformSetCors(
func (bucket *SBucket) AllowPerformDeleteCors(
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input jsonutils.JSONObject,
input api.BucketCORSRuleDeleteInput,
) bool {
return bucket.IsOwner(userCred)
}
@@ -1397,13 +1398,13 @@ func (bucket *SBucket) PerformDeleteCors(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input jsonutils.JSONObject,
input api.BucketCORSRuleDeleteInput,
) (jsonutils.JSONObject, error) {
iBucket, err := bucket.GetIBucket()
if err != nil {
return nil, errors.Wrap(err, "GetIBucket")
}
err = iBucket.DeleteCORS()
err = iBucket.DeleteCORS(input.Id)
if err != nil {
return nil, httperrors.NewInternalServerError("iBucket.DeleteCORS error %s", err)
}
@@ -1436,12 +1437,13 @@ func (bucket *SBucket) GetDetailsCors(
}
for i := range corsRules {
rules.Rules = append(rules.Rules, api.BucketCORSRule{
rules.Data = append(rules.Data, api.BucketCORSRule{
AllowedOrigins: corsRules[i].AllowedOrigins,
AllowedMethods: corsRules[i].AllowedMethods,
AllowedHeaders: corsRules[i].AllowedHeaders,
MaxAgeSeconds: corsRules[i].MaxAgeSeconds,
ExposeHeaders: corsRules[i].ExposeHeaders,
Id: corsRules[i].Id,
})
}
@@ -1471,8 +1473,9 @@ func (bucket *SBucket) GetDetailsCdnDomain(
return domains, httperrors.NewInternalServerError("iBucket.GetCdnDomains error %s", err)
}
for i := range cdnDomains {
domains.Domains = append(domains.Domains, api.CdnDomain{
domains.Data = append(domains.Data, api.CdnDomain{
Domain: cdnDomains[i].Domain,
Status: cdnDomains[i].Status,
Area: cdnDomains[i].Area,
Cname: cdnDomains[i].Cname,
Origin: cdnDomains[i].Origin,
+1 -1
View File
@@ -94,7 +94,7 @@ func (b *SBaseBucket) GetCORSRules() ([]cloudprovider.SBucketCORSRule, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (b *SBaseBucket) DeleteCORS() error {
func (b *SBaseBucket) DeleteCORS(id []string) error {
return cloudprovider.ErrNotImplemented
}
+6 -3
View File
@@ -451,6 +451,7 @@ func S3Shell() {
AllowedHeaders []string
MaxAgeSeconds int
ExposeHeaders []string
Id string
}
shellutils.R(&BucketSetCorsOption{}, "bucket-set-cors", "Set bucket cors", func(cli cloudprovider.ICloudRegion, args *BucketSetCorsOption) error {
bucket, err := cli.GetIBucketById(args.BUCKET)
@@ -463,6 +464,7 @@ func S3Shell() {
AllowedHeaders: args.AllowedHeaders,
MaxAgeSeconds: args.MaxAgeSeconds,
ExposeHeaders: args.ExposeHeaders,
Id: args.Id,
}
err = bucket.SetCORS([]cloudprovider.SBucketCORSRule{rule})
if err != nil {
@@ -489,14 +491,15 @@ func S3Shell() {
})
type BucketDeleteCorsOption struct {
BUCKET string `help:"name of bucket to put object"`
BUCKET string `help:"name of bucket to put object"`
Ids []string `help:"rule ids to delete"`
}
shellutils.R(&BucketGetWebsiteConfOption{}, "bucket-delete-cors", "Delete bucket cors", func(cli cloudprovider.ICloudRegion, args *BucketGetWebsiteConfOption) error {
shellutils.R(&BucketDeleteCorsOption{}, "bucket-delete-cors", "Delete bucket cors", func(cli cloudprovider.ICloudRegion, args *BucketDeleteCorsOption) error {
bucket, err := cli.GetIBucketById(args.BUCKET)
if err != nil {
return err
}
err = bucket.DeleteCORS()
err = bucket.DeleteCORS(args.Ids)
if err != nil {
return err
}
+112 -24
View File
@@ -19,6 +19,7 @@ import (
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
@@ -642,9 +643,40 @@ func (b *SBucket) SetCORS(rules []cloudprovider.SBucketCORSRule) error {
AllowedHeaders: rules[i].AllowedHeaders,
MaxAgeSeconds: rules[i].MaxAgeSeconds,
ExposeHeaders: rules[i].ExposeHeaders,
ID: rules[i].Id,
})
}
_, err = coscli.Bucket.PutCORS(context.Background(), &opts)
newSet := []cos.BucketCORSRule{}
updateSet := map[int]cos.BucketCORSRule{}
oldConf, _, err := coscli.Bucket.GetCORS(context.Background())
if err != nil {
if !strings.Contains(err.Error(), "NoSuchCORSConfiguration") {
return errors.Wrap(err, "b.region.GetCORS")
}
}
for i := range opts.Rules {
index, err := strconv.Atoi(opts.Rules[i].ID)
if err == nil && index < len(oldConf.Rules) {
updateSet[index] = opts.Rules[i]
} else {
newSet = append(newSet, opts.Rules[i])
}
}
updatedOpts := cos.BucketPutCORSOptions{}
for i := range oldConf.Rules {
if _, ok := updateSet[i]; !ok {
updatedOpts.Rules = append(updatedOpts.Rules, oldConf.Rules[i])
} else {
updatedOpts.Rules = append(updatedOpts.Rules, updateSet[i])
}
}
updatedOpts.Rules = append(updatedOpts.Rules, newSet...)
_, err = coscli.Bucket.PutCORS(context.Background(), &updatedOpts)
if err != nil {
return errors.Wrap(err, "coscli.Bucket.PutCORS")
}
@@ -657,6 +689,12 @@ func (b *SBucket) GetCORSRules() ([]cloudprovider.SBucketCORSRule, error) {
return nil, errors.Wrap(err, "b.region.GetCosClient")
}
conf, _, err := coscli.Bucket.GetCORS(context.Background())
if err != nil {
if strings.Contains(err.Error(), "NoSuchCORSConfiguration") {
return nil, nil
}
return nil, errors.Wrap(err, "b.region.GetCORS")
}
result := []cloudprovider.SBucketCORSRule{}
for i := range conf.Rules {
result = append(result, cloudprovider.SBucketCORSRule{
@@ -665,19 +703,55 @@ func (b *SBucket) GetCORSRules() ([]cloudprovider.SBucketCORSRule, error) {
AllowedHeaders: conf.Rules[i].AllowedHeaders,
MaxAgeSeconds: conf.Rules[i].MaxAgeSeconds,
ExposeHeaders: conf.Rules[i].ExposeHeaders,
Id: strconv.Itoa(i),
})
}
return result, nil
}
func (b *SBucket) DeleteCORS() error {
func (b *SBucket) DeleteCORS(id []string) error {
coscli, err := b.region.GetCosClient(b)
if err != nil {
return errors.Wrap(err, "b.region.GetCosClient")
}
_, err = coscli.Bucket.DeleteCORS(context.Background())
if err != nil {
return errors.Wrap(err, "coscli.Bucket.DeleteCORS")
existedRules := []cos.BucketCORSRule{}
if len(id) > 0 {
conf, _, err := coscli.Bucket.GetCORS(context.Background())
if err != nil {
if strings.Contains(err.Error(), "NoSuchCORSConfiguration") {
return nil
}
return errors.Wrap(err, "b.region.GetCORS")
}
existedRules = conf.Rules
}
excludeMap := map[int]bool{}
for i := range id {
index, err := strconv.Atoi(id[i])
if err == nil {
excludeMap[index] = true
}
}
newRules := []cos.BucketCORSRule{}
for i := range existedRules {
if _, ok := excludeMap[i]; !ok {
newRules = append(newRules, existedRules[i])
}
}
if len(newRules) < len(existedRules) {
if len(newRules) == 0 {
_, err = coscli.Bucket.DeleteCORS(context.Background())
if err != nil {
return errors.Wrap(err, "coscli.Bucket.DeleteCORS")
}
return nil
}
_, err = coscli.Bucket.PutCORS(context.Background(), &cos.BucketPutCORSOptions{Rules: newRules})
if err != nil {
return errors.Wrap(err, "coscli.Bucket.PutCORS")
}
}
return nil
}
@@ -715,6 +789,9 @@ func (b *SBucket) GetReferer() (cloudprovider.SBucketRefererConf, error) {
return result, errors.Wrap(err, "b.region.GetCosClient")
}
referResult, _, err := coscli.Bucket.GetReferer(context.Background())
if err != nil {
return result, errors.Wrap(err, " coscli.Bucket.GetReferer")
}
result.Enabled = true
result.Type = "White-List"
@@ -736,11 +813,25 @@ func (b *SBucket) GetReferer() (cloudprovider.SBucketRefererConf, error) {
func toAPICdnArea(area string) string {
switch area {
case "mainland":
return api.CDN_AREA_MAINLAND
return api.CDN_DOMAIN_AREA_MAINLAND
case "overseas":
return api.CDN_AREA_OVERSEAS
return api.CDN_DOMAIN_AREA_OVERSEAS
case "global":
return api.CDN_AREA_GLOBAL
return api.CDN_DOMAIN_AREA_GLOBAL
default:
return ""
}
}
func toAPICdnStatus(status string) string {
switch status {
case "online":
return api.CDN_DOMAIN_STATUS_ONLINE
case "offline":
return api.CDN_DOMAIN_STATUS_OFFLINE
case "processing":
return api.CDN_DOMAIN_STATUS_PROCESSING
case "rejected":
return api.CDN_DOMAIN_STATUS_REJECTED
default:
return ""
}
@@ -755,16 +846,15 @@ func (b *SBucket) GetCdnDomains() ([]cloudprovider.SCdnDomain, error) {
if err != nil {
return nil, errors.Wrapf(err, `b.region.client.DescribeAllCdnDomains(nil, []string{%s}, "cos")`, bucketHost)
}
if len(bucketCdnDomains) > 1 {
return nil, cloudprovider.ErrDuplicateId
}
if len(bucketCdnDomains) == 1 {
for i := range bucketCdnDomains {
result = append(result, cloudprovider.SCdnDomain{
Domain: bucketCdnDomains[0].Domain,
Cname: bucketCdnDomains[0].Cname,
Area: toAPICdnArea(bucketCdnDomains[0].Area),
Domain: bucketCdnDomains[i].Domain,
Status: toAPICdnStatus(bucketCdnDomains[i].Status),
Cname: bucketCdnDomains[i].Cname,
Area: toAPICdnArea(bucketCdnDomains[i].Area),
Origin: bucketHost,
OriginType: api.CDN_ORIGIN_TYPE_BUCKET,
OriginType: api.CDN_DOMAIN_ORIGIN_TYPE_BUCKET,
})
}
@@ -772,17 +862,15 @@ func (b *SBucket) GetCdnDomains() ([]cloudprovider.SCdnDomain, error) {
if err != nil {
return nil, errors.Wrapf(err, `b.region.client.DescribeAllCdnDomains(nil, []string{%s}, "cos")`, bucketWebsiteHost)
}
if len(bucketWebsiteCdnDomains) > 1 {
return nil, cloudprovider.ErrDuplicateId
}
if len(bucketWebsiteCdnDomains) == 1 {
for i := range bucketWebsiteCdnDomains {
result = append(result, cloudprovider.SCdnDomain{
Domain: bucketWebsiteCdnDomains[0].Domain,
Cname: bucketWebsiteCdnDomains[0].Cname,
Area: toAPICdnArea(bucketWebsiteCdnDomains[0].Area),
Domain: bucketWebsiteCdnDomains[i].Domain,
Status: toAPICdnStatus(bucketCdnDomains[i].Status),
Cname: bucketWebsiteCdnDomains[i].Cname,
Area: toAPICdnArea(bucketWebsiteCdnDomains[i].Area),
Origin: bucketWebsiteHost,
OriginType: api.CDN_ORIGIN_TYPE_BUCKET,
OriginType: api.CDN_DOMAIN_ORIGIN_TYPE_BUCKET,
})
}
return result, nil