yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/bucket.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aliyun 16 17 import ( 18 "context" 19 "fmt" 20 "io" 21 "net/http" 22 "strconv" 23 "strings" 24 "time" 25 26 "github.com/aliyun/aliyun-oss-go-sdk/oss" 27 28 "yunion.io/x/jsonutils" 29 "yunion.io/x/log" 30 "yunion.io/x/pkg/errors" 31 32 api "yunion.io/x/cloudmux/pkg/apis/compute" 33 "yunion.io/x/cloudmux/pkg/cloudprovider" 34 "yunion.io/x/cloudmux/pkg/multicloud" 35 ) 36 37 type SBucket struct { 38 multicloud.SBaseBucket 39 AliyunTags 40 41 region *SRegion 42 43 Name string 44 Location string 45 CreationDate time.Time 46 StorageClass string 47 } 48 49 func (b *SBucket) GetProjectId() string { 50 return "" 51 } 52 53 func (b *SBucket) GetGlobalId() string { 54 return b.Name 55 } 56 57 func (b *SBucket) GetName() string { 58 return b.Name 59 } 60 61 func (b *SBucket) GetAcl() cloudprovider.TBucketACLType { 62 acl := cloudprovider.ACLPrivate 63 osscli, err := b.getOssClient() 64 if err != nil { 65 log.Errorf("b.region.GetOssClient fail %s", err) 66 return acl 67 } 68 aclResp, err := osscli.GetBucketACL(b.Name) 69 if err != nil { 70 log.Errorf("osscli.GetBucketACL fail %s", err) 71 return acl 72 } 73 acl = cloudprovider.TBucketACLType(aclResp.ACL) 74 return acl 75 } 76 77 func (b *SBucket) GetLocation() string { 78 return b.Location 79 } 80 81 func (b *SBucket) GetIRegion() cloudprovider.ICloudRegion { 82 return b.region 83 } 84 85 func (b *SBucket) GetCreatedAt() time.Time { 86 return b.CreationDate 87 } 88 89 func (b *SBucket) GetStorageClass() string { 90 return b.StorageClass 91 } 92 93 func (b *SBucket) GetAccessUrls() []cloudprovider.SBucketAccessUrl { 94 ret := []cloudprovider.SBucketAccessUrl{ 95 { 96 Url: fmt.Sprintf("%s.%s", b.Name, b.region.getOSSExternalDomain()), 97 Description: "ExtranetEndpoint", 98 Primary: true, 99 }, 100 { 101 Url: fmt.Sprintf("%s.%s", b.Name, b.region.getOSSInternalDomain()), 102 Description: "IntranetEndpoint", 103 }, 104 } 105 return ret 106 } 107 108 func (b *SBucket) GetStats() cloudprovider.SBucketStats { 109 stats, err := cloudprovider.GetIBucketStats(b) 110 if err != nil { 111 log.Errorf("GetStats fail %s", err) 112 } 113 return stats 114 } 115 116 func (b *SBucket) SetAcl(aclStr cloudprovider.TBucketACLType) error { 117 osscli, err := b.region.GetOssClient() 118 if err != nil { 119 log.Errorf("b.region.GetOssClient fail %s", err) 120 return errors.Wrap(err, "b.region.GetOssClient") 121 } 122 acl, err := str2Acl(string(aclStr)) 123 if err != nil { 124 return errors.Wrap(err, "str2Acl") 125 } 126 err = osscli.SetBucketACL(b.Name, acl) 127 if err != nil { 128 return errors.Wrap(err, "SetBucketACL") 129 } 130 return nil 131 } 132 133 func (b *SBucket) getOssClient() (*oss.Client, error) { 134 if b.region.client.GetAccessEnv() == ALIYUN_FINANCE_CLOUDENV { 135 osscli, err := b.region.GetOssClient() 136 if err != nil { 137 return nil, errors.Wrapf(err, "GetOssClient") 138 } 139 info, err := osscli.GetBucketInfo(b.Name) 140 if err != nil { 141 return nil, errors.Wrapf(err, "GetBucketInfo") 142 } 143 if len(info.BucketInfo.ExtranetEndpoint) > 0 { 144 return b.region.client.getOssClientByEndpoint(info.BucketInfo.ExtranetEndpoint) 145 } 146 } 147 return b.region.GetOssClient() 148 } 149 150 func (b *SBucket) ListObjects(prefix string, marker string, delimiter string, maxCount int) (cloudprovider.SListObjectResult, error) { 151 result := cloudprovider.SListObjectResult{} 152 osscli, err := b.region.GetOssClient() 153 if err != nil { 154 return result, errors.Wrap(err, "GetOssClient") 155 } 156 bucket, err := osscli.Bucket(b.Name) 157 if err != nil { 158 return result, errors.Wrap(err, "Bucket") 159 } 160 opts := make([]oss.Option, 0) 161 if len(prefix) > 0 { 162 opts = append(opts, oss.Prefix(prefix)) 163 } 164 if len(delimiter) > 0 { 165 opts = append(opts, oss.Delimiter(delimiter)) 166 } 167 if len(marker) > 0 { 168 opts = append(opts, oss.Marker(marker)) 169 } 170 if maxCount > 0 { 171 opts = append(opts, oss.MaxKeys(maxCount)) 172 } 173 oResult, err := bucket.ListObjects(opts...) 174 if err != nil { 175 return result, errors.Wrap(err, "ListObjects") 176 } 177 result.Objects = make([]cloudprovider.ICloudObject, 0) 178 for _, object := range oResult.Objects { 179 obj := &SObject{ 180 bucket: b, 181 SBaseCloudObject: cloudprovider.SBaseCloudObject{ 182 StorageClass: object.StorageClass, 183 Key: object.Key, 184 SizeBytes: object.Size, 185 ETag: object.ETag, 186 LastModified: object.LastModified, 187 }, 188 } 189 result.Objects = append(result.Objects, obj) 190 } 191 if oResult.CommonPrefixes != nil { 192 result.CommonPrefixes = make([]cloudprovider.ICloudObject, len(oResult.CommonPrefixes)) 193 for i, commPrefix := range oResult.CommonPrefixes { 194 result.CommonPrefixes[i] = &SObject{ 195 bucket: b, 196 SBaseCloudObject: cloudprovider.SBaseCloudObject{Key: commPrefix}, 197 } 198 } 199 } 200 result.IsTruncated = oResult.IsTruncated 201 result.NextMarker = oResult.NextMarker 202 return result, nil 203 } 204 205 func metaOpts(opts []oss.Option, meta http.Header) []oss.Option { 206 for k, v := range meta { 207 if len(v) == 0 { 208 continue 209 } 210 switch http.CanonicalHeaderKey(k) { 211 case cloudprovider.META_HEADER_CONTENT_TYPE: 212 opts = append(opts, oss.ContentType(v[0])) 213 case cloudprovider.META_HEADER_CONTENT_MD5: 214 opts = append(opts, oss.ContentMD5(v[0])) 215 case cloudprovider.META_HEADER_CONTENT_LANGUAGE: 216 opts = append(opts, oss.ContentLanguage(v[0])) 217 case cloudprovider.META_HEADER_CONTENT_ENCODING: 218 opts = append(opts, oss.ContentEncoding(v[0])) 219 case cloudprovider.META_HEADER_CONTENT_DISPOSITION: 220 opts = append(opts, oss.ContentDisposition(v[0])) 221 case cloudprovider.META_HEADER_CACHE_CONTROL: 222 opts = append(opts, oss.CacheControl(v[0])) 223 default: 224 opts = append(opts, oss.Meta(http.CanonicalHeaderKey(k), v[0])) 225 } 226 } 227 return opts 228 } 229 230 func (b *SBucket) PutObject(ctx context.Context, key string, input io.Reader, sizeBytes int64, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) error { 231 osscli, err := b.region.GetOssClient() 232 if err != nil { 233 return errors.Wrap(err, "GetOssClient") 234 } 235 bucket, err := osscli.Bucket(b.Name) 236 if err != nil { 237 return errors.Wrap(err, "Bucket") 238 } 239 opts := make([]oss.Option, 0) 240 if sizeBytes > 0 { 241 opts = append(opts, oss.ContentLength(sizeBytes)) 242 } 243 if meta != nil { 244 opts = metaOpts(opts, meta) 245 } 246 if len(cannedAcl) == 0 { 247 cannedAcl = b.GetAcl() 248 } 249 acl, err := str2Acl(string(cannedAcl)) 250 if err != nil { 251 return errors.Wrap(err, "") 252 } 253 opts = append(opts, oss.ObjectACL(acl)) 254 if len(storageClassStr) > 0 { 255 storageClass, err := str2StorageClass(storageClassStr) 256 if err != nil { 257 return errors.Wrap(err, "str2StorageClass") 258 } 259 opts = append(opts, oss.ObjectStorageClass(storageClass)) 260 } 261 return bucket.PutObject(key, input, opts...) 262 } 263 264 func (b *SBucket) NewMultipartUpload(ctx context.Context, key string, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) (string, error) { 265 osscli, err := b.region.GetOssClient() 266 if err != nil { 267 return "", errors.Wrap(err, "GetOssClient") 268 } 269 bucket, err := osscli.Bucket(b.Name) 270 if err != nil { 271 return "", errors.Wrap(err, "Bucket") 272 } 273 opts := make([]oss.Option, 0) 274 if meta != nil { 275 opts = metaOpts(opts, meta) 276 } 277 if len(cannedAcl) == 0 { 278 cannedAcl = b.GetAcl() 279 } 280 acl, err := str2Acl(string(cannedAcl)) 281 if err != nil { 282 return "", errors.Wrap(err, "str2Acl") 283 } 284 opts = append(opts, oss.ObjectACL(acl)) 285 if len(storageClassStr) > 0 { 286 storageClass, err := str2StorageClass(storageClassStr) 287 if err != nil { 288 return "", errors.Wrap(err, "str2StorageClass") 289 } 290 opts = append(opts, oss.ObjectStorageClass(storageClass)) 291 } 292 result, err := bucket.InitiateMultipartUpload(key, opts...) 293 if err != nil { 294 return "", errors.Wrap(err, "bucket.InitiateMultipartUpload") 295 } 296 return result.UploadID, nil 297 } 298 299 func (b *SBucket) UploadPart(ctx context.Context, key string, uploadId string, partIndex int, input io.Reader, partSize int64, offset, totalSize int64) (string, error) { 300 osscli, err := b.region.GetOssClient() 301 if err != nil { 302 return "", errors.Wrap(err, "GetOssClient") 303 } 304 bucket, err := osscli.Bucket(b.Name) 305 if err != nil { 306 return "", errors.Wrap(err, "Bucket") 307 } 308 imur := oss.InitiateMultipartUploadResult{ 309 Bucket: b.Name, 310 Key: key, 311 UploadID: uploadId, 312 } 313 part, err := bucket.UploadPart(imur, input, partSize, partIndex) 314 if err != nil { 315 return "", errors.Wrap(err, "bucket.UploadPart") 316 } 317 if b.region.client.debug { 318 log.Debugf("upload part key:%s uploadId:%s partIndex:%d etag:%s", key, uploadId, partIndex, part.ETag) 319 } 320 return part.ETag, nil 321 } 322 323 func (b *SBucket) CompleteMultipartUpload(ctx context.Context, key string, uploadId string, partEtags []string) error { 324 osscli, err := b.region.GetOssClient() 325 if err != nil { 326 return errors.Wrap(err, "GetOssClient") 327 } 328 bucket, err := osscli.Bucket(b.Name) 329 if err != nil { 330 return errors.Wrap(err, "Bucket") 331 } 332 imur := oss.InitiateMultipartUploadResult{ 333 Bucket: b.Name, 334 Key: key, 335 UploadID: uploadId, 336 } 337 parts := make([]oss.UploadPart, len(partEtags)) 338 for i := range partEtags { 339 parts[i] = oss.UploadPart{ 340 PartNumber: i + 1, 341 ETag: partEtags[i], 342 } 343 } 344 result, err := bucket.CompleteMultipartUpload(imur, parts) 345 if err != nil { 346 return errors.Wrap(err, "bucket.CompleteMultipartUpload") 347 } 348 if b.region.client.debug { 349 log.Debugf("CompleteMultipartUpload bucket:%s key:%s etag:%s location:%s", result.Bucket, result.Key, result.ETag, result.Location) 350 } 351 return nil 352 } 353 354 func (b *SBucket) AbortMultipartUpload(ctx context.Context, key string, uploadId string) error { 355 osscli, err := b.region.GetOssClient() 356 if err != nil { 357 return errors.Wrap(err, "GetOssClient") 358 } 359 bucket, err := osscli.Bucket(b.Name) 360 if err != nil { 361 return errors.Wrap(err, "Bucket") 362 } 363 imur := oss.InitiateMultipartUploadResult{ 364 Bucket: b.Name, 365 Key: key, 366 UploadID: uploadId, 367 } 368 err = bucket.AbortMultipartUpload(imur) 369 if err != nil { 370 return errors.Wrap(err, "AbortMultipartUpload") 371 } 372 return nil 373 } 374 375 func (b *SBucket) DeleteObject(ctx context.Context, key string) error { 376 osscli, err := b.region.GetOssClient() 377 if err != nil { 378 return errors.Wrap(err, "GetOssClient") 379 } 380 bucket, err := osscli.Bucket(b.Name) 381 if err != nil { 382 return errors.Wrap(err, "Bucket") 383 } 384 err = bucket.DeleteObject(key) 385 if err != nil { 386 return errors.Wrap(err, "DeleteObject") 387 } 388 return nil 389 } 390 391 func (b *SBucket) GetTempUrl(method string, key string, expire time.Duration) (string, error) { 392 if method != "GET" && method != "PUT" && method != "DELETE" { 393 return "", errors.Error("unsupported method") 394 } 395 osscli, err := b.region.GetOssClient() 396 if err != nil { 397 return "", errors.Wrap(err, "GetOssClient") 398 } 399 bucket, err := osscli.Bucket(b.Name) 400 if err != nil { 401 return "", errors.Wrap(err, "Bucket") 402 } 403 urlStr, err := bucket.SignURL(key, oss.HTTPMethod(method), int64(expire/time.Second)) 404 if err != nil { 405 return "", errors.Wrap(err, "SignURL") 406 } 407 return urlStr, nil 408 } 409 410 func (b *SBucket) CopyObject(ctx context.Context, destKey string, srcBucket, srcKey string, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) error { 411 osscli, err := b.region.GetOssClient() 412 if err != nil { 413 return errors.Wrap(err, "GetOssClient") 414 } 415 bucket, err := osscli.Bucket(b.Name) 416 if err != nil { 417 return errors.Wrap(err, "Bucket") 418 } 419 opts := make([]oss.Option, 0) 420 if meta != nil { 421 opts = metaOpts(opts, meta) 422 } 423 if len(cannedAcl) == 0 { 424 cannedAcl = b.GetAcl() 425 } 426 acl, err := str2Acl(string(cannedAcl)) 427 if err != nil { 428 return errors.Wrap(err, "str2Acl") 429 } 430 opts = append(opts, oss.ObjectACL(acl)) 431 if len(storageClassStr) > 0 { 432 storageClass, err := str2StorageClass(storageClassStr) 433 if err != nil { 434 return errors.Wrap(err, "str2StorageClass") 435 } 436 opts = append(opts, oss.ObjectStorageClass(storageClass)) 437 } 438 _, err = bucket.CopyObjectFrom(srcBucket, srcKey, destKey, opts...) 439 if err != nil { 440 return errors.Wrap(err, "CopyObjectFrom") 441 } 442 return nil 443 } 444 445 func (b *SBucket) GetObject(ctx context.Context, key string, rangeOpt *cloudprovider.SGetObjectRange) (io.ReadCloser, error) { 446 osscli, err := b.region.GetOssClient() 447 if err != nil { 448 return nil, errors.Wrap(err, "GetOssClient") 449 } 450 bucket, err := osscli.Bucket(b.Name) 451 if err != nil { 452 return nil, errors.Wrap(err, "Bucket") 453 } 454 opts := make([]oss.Option, 0) 455 if rangeOpt != nil { 456 opts = append(opts, oss.NormalizedRange(rangeOpt.String())) 457 } 458 output, err := bucket.GetObject(key, opts...) 459 if err != nil { 460 return nil, errors.Wrap(err, "bucket.GetObject") 461 } 462 return output, nil 463 } 464 465 func (b *SBucket) CopyPart(ctx context.Context, key string, uploadId string, partNumber int, srcBucket string, srcKey string, srcOffset int64, srcLength int64) (string, error) { 466 osscli, err := b.region.GetOssClient() 467 if err != nil { 468 return "", errors.Wrap(err, "GetOssClient") 469 } 470 bucket, err := osscli.Bucket(b.Name) 471 if err != nil { 472 return "", errors.Wrap(err, "Bucket") 473 } 474 imur := oss.InitiateMultipartUploadResult{ 475 Bucket: b.Name, 476 Key: key, 477 UploadID: uploadId, 478 } 479 opts := make([]oss.Option, 0) 480 part, err := bucket.UploadPartCopy(imur, srcBucket, srcKey, srcOffset, srcLength, partNumber, opts...) 481 if err != nil { 482 return "", errors.Wrap(err, "bucket.UploadPartCopy") 483 } 484 return part.ETag, nil 485 } 486 487 func (b *SBucket) SetWebsite(websitConf cloudprovider.SBucketWebsiteConf) error { 488 if len(websitConf.Index) == 0 { 489 return errors.Wrap(cloudprovider.ErrNotSupported, "missing Index") 490 } 491 if len(websitConf.ErrorDocument) == 0 { 492 return errors.Wrap(cloudprovider.ErrNotSupported, "missing ErrorDocument") 493 } 494 osscli, err := b.region.GetOssClient() 495 if err != nil { 496 return errors.Wrap(err, "GetOssClient") 497 } 498 499 err = osscli.SetBucketWebsite(b.Name, websitConf.Index, websitConf.ErrorDocument) 500 if err != nil { 501 return errors.Wrapf(err, " osscli.SetBucketWebsite(%s,%s,%s)", b.Name, websitConf.Index, websitConf.ErrorDocument) 502 } 503 return nil 504 } 505 506 func (b *SBucket) GetWebsiteConf() (cloudprovider.SBucketWebsiteConf, error) { 507 result := cloudprovider.SBucketWebsiteConf{} 508 osscli, err := b.region.GetOssClient() 509 if err != nil { 510 return result, errors.Wrap(err, "GetOssClient") 511 } 512 websiteResult, err := osscli.GetBucketWebsite(b.Name) 513 if err != nil { 514 if strings.Contains(err.Error(), "NoSuchWebsiteConfiguration") { 515 return cloudprovider.SBucketWebsiteConf{}, nil 516 } 517 return result, errors.Wrapf(err, "osscli.GetBucketWebsite(%s)", b.Name) 518 } 519 result.Index = websiteResult.IndexDocument.Suffix 520 result.ErrorDocument = websiteResult.ErrorDocument.Key 521 return result, nil 522 } 523 524 func (b *SBucket) DeleteWebSiteConf() error { 525 osscli, err := b.region.GetOssClient() 526 if err != nil { 527 return errors.Wrap(err, "GetOssClient") 528 } 529 log.Infof("to be delete") 530 err = osscli.DeleteBucketWebsite(b.Name) 531 if err != nil { 532 return errors.Wrapf(err, "osscli.DeleteBucketWebsite(%s)", b.Name) 533 } 534 log.Infof("deleted") 535 return nil 536 } 537 538 func (b *SBucket) SetCORS(rules []cloudprovider.SBucketCORSRule) error { 539 if len(rules) == 0 { 540 return nil 541 } 542 osscli, err := b.region.GetOssClient() 543 if err != nil { 544 return errors.Wrap(err, "GetOssClient") 545 } 546 input := []oss.CORSRule{} 547 for i := range rules { 548 input = append(input, oss.CORSRule{ 549 AllowedOrigin: rules[i].AllowedOrigins, 550 AllowedMethod: rules[i].AllowedMethods, 551 AllowedHeader: rules[i].AllowedHeaders, 552 MaxAgeSeconds: rules[i].MaxAgeSeconds, 553 ExposeHeader: rules[i].ExposeHeaders, 554 }) 555 } 556 557 err = osscli.SetBucketCORS(b.Name, input) 558 if err != nil { 559 return errors.Wrapf(err, "osscli.SetBucketCORS(%s,%s)", b.Name, jsonutils.Marshal(input).String()) 560 } 561 return nil 562 } 563 564 func (b *SBucket) GetCORSRules() ([]cloudprovider.SBucketCORSRule, error) { 565 osscli, err := b.region.GetOssClient() 566 if err != nil { 567 return nil, errors.Wrap(err, "GetOssClient") 568 } 569 conf, err := osscli.GetBucketCORS(b.Name) 570 if err != nil { 571 if !strings.Contains(err.Error(), "NoSuchCORSConfiguration") { 572 return nil, errors.Wrapf(err, "osscli.GetBucketCORS(%s)", b.Name) 573 } 574 } 575 result := []cloudprovider.SBucketCORSRule{} 576 for i := range conf.CORSRules { 577 result = append(result, cloudprovider.SBucketCORSRule{ 578 AllowedOrigins: conf.CORSRules[i].AllowedOrigin, 579 AllowedMethods: conf.CORSRules[i].AllowedMethod, 580 AllowedHeaders: conf.CORSRules[i].AllowedHeader, 581 MaxAgeSeconds: conf.CORSRules[i].MaxAgeSeconds, 582 ExposeHeaders: conf.CORSRules[i].ExposeHeader, 583 Id: strconv.Itoa(i), 584 }) 585 } 586 return result, nil 587 } 588 589 func (b *SBucket) DeleteCORS() error { 590 osscli, err := b.region.GetOssClient() 591 if err != nil { 592 return errors.Wrap(err, "GetOssClient") 593 } 594 595 err = osscli.DeleteBucketCORS(b.Name) 596 if err != nil { 597 return errors.Wrapf(err, "osscli.DeleteBucketCORS(%s)", b.Name) 598 } 599 600 return nil 601 } 602 603 func (b *SBucket) SetReferer(conf cloudprovider.SBucketRefererConf) error { 604 osscli, err := b.region.GetOssClient() 605 if err != nil { 606 return errors.Wrap(err, "GetOssClient") 607 } 608 if !conf.Enabled { 609 return errors.Wrapf(cloudprovider.ErrNotSupported, "Disable Refer") 610 } 611 612 if conf.RefererType == "Black-List" { 613 return errors.Wrapf(cloudprovider.ErrNotSupported, "Black List") 614 } 615 616 err = osscli.SetBucketReferer(b.Name, conf.DomainList, conf.AllowEmptyRefer) 617 if err != nil { 618 return errors.Wrapf(err, "osscli.SetBucketReferer(%s,%s,%t)", b.Name, conf.DomainList, conf.AllowEmptyRefer) 619 } 620 return nil 621 } 622 623 func (b *SBucket) GetReferer() (cloudprovider.SBucketRefererConf, error) { 624 result := cloudprovider.SBucketRefererConf{} 625 osscli, err := b.region.GetOssClient() 626 if err != nil { 627 return result, errors.Wrap(err, "GetOssClient") 628 } 629 refererResult, err := osscli.GetBucketReferer(b.Name) 630 if err != nil { 631 return result, errors.Wrapf(err, "osscli.GetBucketReferer(%s)", b.Name) 632 } 633 result = cloudprovider.SBucketRefererConf{ 634 Enabled: true, 635 RefererType: "White-List", 636 DomainList: refererResult.RefererList, 637 AllowEmptyRefer: refererResult.AllowEmptyReferer, 638 } 639 return result, nil 640 } 641 642 func toAPICdnArea(area string) string { 643 switch area { 644 case "domestic": 645 return api.CDN_DOMAIN_AREA_MAINLAND 646 case "overseas": 647 return api.CDN_DOMAIN_AREA_OVERSEAS 648 case "global": 649 return api.CDN_DOMAIN_AREA_GLOBAL 650 default: 651 return "" 652 } 653 } 654 655 func toAPICdnStatus(status string) string { 656 switch status { 657 case "online": 658 return api.CDN_DOMAIN_STATUS_ONLINE 659 case "offline": 660 return api.CDN_DOMAIN_STATUS_OFFLINE 661 case "configuring", "checking", "stopping", "deleting": 662 return api.CDN_DOMAIN_STATUS_PROCESSING 663 case "check_failed", "configure_failed": 664 return api.CDN_DOMAIN_STATUS_REJECTED 665 default: 666 return "" 667 } 668 } 669 670 func (b *SBucket) GetCdnDomains() ([]cloudprovider.SCdnDomain, error) { 671 bucketExtUrl := fmt.Sprintf("%s.%s", b.Name, b.region.getOSSExternalDomain()) 672 cdnDomains, err := b.region.client.DescribeDomainsBySource(bucketExtUrl) 673 if err != nil { 674 return nil, errors.Wrapf(err, " b.region.client.DescribeDomainsBySource(%s)", bucketExtUrl) 675 } 676 result := []cloudprovider.SCdnDomain{} 677 for i := range cdnDomains.DomainsData { 678 if cdnDomains.DomainsData[i].Source == bucketExtUrl { 679 for j := range cdnDomains.DomainsData[i].Domains.DomainNames { 680 area := "" 681 domain, _ := b.region.client.GetCDNDomainByName(cdnDomains.DomainsData[i].Domains.DomainNames[j]) 682 if domain != nil { 683 area = domain.Coverage 684 } 685 result = append(result, cloudprovider.SCdnDomain{ 686 Domain: cdnDomains.DomainsData[i].Domains.DomainNames[j], 687 Status: toAPICdnStatus(cdnDomains.DomainsData[i].DomainInfos.DomainInfo[j].Status), 688 Cname: cdnDomains.DomainsData[i].DomainInfos.DomainInfo[j].DomainCname, 689 Area: toAPICdnArea(area), 690 Origin: bucketExtUrl, 691 OriginType: api.CDN_DOMAIN_ORIGIN_TYPE_BUCKET, 692 }) 693 } 694 } 695 } 696 return result, nil 697 } 698 699 func (b *SBucket) GetTags() (map[string]string, error) { 700 osscli, err := b.region.GetOssClient() 701 if err != nil { 702 return nil, errors.Wrap(err, "GetOssClient") 703 } 704 705 tagresult, err := osscli.GetBucketTagging(b.Name) 706 if err != nil { 707 return nil, errors.Wrapf(err, "GetBucketTagging %s", b.Name) 708 } 709 result := map[string]string{} 710 for _, tag := range tagresult.Tags { 711 result[tag.Key] = tag.Value 712 } 713 return result, nil 714 } 715 716 func (b *SBucket) SetTags(tags map[string]string, replace bool) error { 717 osscli, err := b.region.GetOssClient() 718 if err != nil { 719 return errors.Wrap(err, "GetOssClient") 720 } 721 722 err = osscli.DeleteBucketTagging(b.Name) 723 if err != nil { 724 return errors.Wrapf(err, "DeleteBucketTagging(%s)", b.Name) 725 } 726 727 if len(tags) == 0 { 728 return nil 729 } 730 731 input := []oss.Tag{} 732 for k, v := range tags { 733 input = append(input, oss.Tag{Key: k, Value: v}) 734 } 735 736 err = osscli.SetBucketTagging(b.Name, oss.Tagging{Tags: input}) 737 if err != nil { 738 return errors.Wrapf(err, "osscli.SetBucketTagging(%s)", jsonutils.Marshal(input)) 739 } 740 return nil 741 } 742 743 func (b *SBucket) ListMultipartUploads() ([]cloudprovider.SBucketMultipartUploads, error) { 744 osscli, err := b.region.GetOssClient() 745 if err != nil { 746 return nil, errors.Wrap(err, "GetOssClient") 747 } 748 result := []cloudprovider.SBucketMultipartUploads{} 749 750 ossBucket, err := osscli.Bucket(b.Name) 751 if err != nil { 752 return nil, errors.Wrap(err, "osscli.Bucket(b.Name)") 753 } 754 755 keyMarker := oss.KeyMarker("") 756 uploadIDMarker := oss.UploadIDMarker("") 757 for { 758 output, err := ossBucket.ListMultipartUploads(keyMarker, uploadIDMarker) 759 if err != nil { 760 return nil, errors.Wrap(err, " coscli.Bucket.ListMultipartUploads(context.Background(), &input)") 761 } 762 for i := range output.Uploads { 763 temp := cloudprovider.SBucketMultipartUploads{ 764 ObjectName: output.Uploads[i].Key, 765 UploadID: output.Uploads[i].UploadID, 766 Initiated: output.Uploads[i].Initiated, 767 } 768 result = append(result, temp) 769 } 770 keyMarker = oss.KeyMarker(output.NextKeyMarker) 771 uploadIDMarker = oss.UploadIDMarker(output.NextUploadIDMarker) 772 if !output.IsTruncated { 773 break 774 } 775 } 776 777 return result, nil 778 }