api-bucket-lifecycle.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * MinIO Go Library for Amazon S3 Compatible Cloud Storage
  3. * Copyright 2020 MinIO, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package minio
  18. import (
  19. "bytes"
  20. "context"
  21. "encoding/xml"
  22. "io/ioutil"
  23. "net/http"
  24. "net/url"
  25. "github.com/minio/minio-go/v7/pkg/lifecycle"
  26. "github.com/minio/minio-go/v7/pkg/s3utils"
  27. )
  28. // SetBucketLifecycle set the lifecycle on an existing bucket.
  29. func (c Client) SetBucketLifecycle(ctx context.Context, bucketName string, config *lifecycle.Configuration) error {
  30. // Input validation.
  31. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  32. return err
  33. }
  34. // If lifecycle is empty then delete it.
  35. if config.Empty() {
  36. return c.removeBucketLifecycle(ctx, bucketName)
  37. }
  38. buf, err := xml.Marshal(config)
  39. if err != nil {
  40. return err
  41. }
  42. // Save the updated lifecycle.
  43. return c.putBucketLifecycle(ctx, bucketName, buf)
  44. }
  45. // Saves a new bucket lifecycle.
  46. func (c Client) putBucketLifecycle(ctx context.Context, bucketName string, buf []byte) error {
  47. // Get resources properly escaped and lined up before
  48. // using them in http request.
  49. urlValues := make(url.Values)
  50. urlValues.Set("lifecycle", "")
  51. // Content-length is mandatory for put lifecycle request
  52. reqMetadata := requestMetadata{
  53. bucketName: bucketName,
  54. queryValues: urlValues,
  55. contentBody: bytes.NewReader(buf),
  56. contentLength: int64(len(buf)),
  57. contentMD5Base64: sumMD5Base64(buf),
  58. }
  59. // Execute PUT to upload a new bucket lifecycle.
  60. resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata)
  61. defer closeResponse(resp)
  62. if err != nil {
  63. return err
  64. }
  65. if resp != nil {
  66. if resp.StatusCode != http.StatusOK {
  67. return httpRespToErrorResponse(resp, bucketName, "")
  68. }
  69. }
  70. return nil
  71. }
  72. // Remove lifecycle from a bucket.
  73. func (c Client) removeBucketLifecycle(ctx context.Context, bucketName string) error {
  74. // Get resources properly escaped and lined up before
  75. // using them in http request.
  76. urlValues := make(url.Values)
  77. urlValues.Set("lifecycle", "")
  78. // Execute DELETE on objectName.
  79. resp, err := c.executeMethod(ctx, http.MethodDelete, requestMetadata{
  80. bucketName: bucketName,
  81. queryValues: urlValues,
  82. contentSHA256Hex: emptySHA256Hex,
  83. })
  84. defer closeResponse(resp)
  85. if err != nil {
  86. return err
  87. }
  88. return nil
  89. }
  90. // GetBucketLifecycle fetch bucket lifecycle configuration
  91. func (c Client) GetBucketLifecycle(ctx context.Context, bucketName string) (*lifecycle.Configuration, error) {
  92. // Input validation.
  93. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  94. return nil, err
  95. }
  96. bucketLifecycle, err := c.getBucketLifecycle(ctx, bucketName)
  97. if err != nil {
  98. return nil, err
  99. }
  100. config := lifecycle.NewConfiguration()
  101. if err = xml.Unmarshal(bucketLifecycle, config); err != nil {
  102. return nil, err
  103. }
  104. return config, nil
  105. }
  106. // Request server for current bucket lifecycle.
  107. func (c Client) getBucketLifecycle(ctx context.Context, bucketName string) ([]byte, error) {
  108. // Get resources properly escaped and lined up before
  109. // using them in http request.
  110. urlValues := make(url.Values)
  111. urlValues.Set("lifecycle", "")
  112. // Execute GET on bucket to get lifecycle.
  113. resp, err := c.executeMethod(ctx, http.MethodGet, requestMetadata{
  114. bucketName: bucketName,
  115. queryValues: urlValues,
  116. })
  117. defer closeResponse(resp)
  118. if err != nil {
  119. return nil, err
  120. }
  121. if resp != nil {
  122. if resp.StatusCode != http.StatusOK {
  123. return nil, httpRespToErrorResponse(resp, bucketName, "")
  124. }
  125. }
  126. return ioutil.ReadAll(resp.Body)
  127. }