Skip to content

Commit

Permalink
Add support for bucket lifecycle policies (minio#1004)
Browse files Browse the repository at this point in the history
  • Loading branch information
mzdeb authored and nitisht committed Jul 16, 2018
1 parent 1336e63 commit c7d7f0e
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 2 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ The full API Reference is available here.
* [getbucketpolicy.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketpolicy.go)
* [listbucketpolicies.go](https://github.com/minio/minio-go/blob/master/examples/s3/listbucketpolicies.go)

### Full Examples : Bucket lifecycle Operations
* [setbucketlifecycle.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketlifecycle.go)
* [getbucketlifecycle.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketlifecycle.go)

### Full Examples : Bucket notification Operations
* [setbucketnotification.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketnotification.go)
* [getbucketnotification.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketnotification.go)
Expand Down
77 changes: 77 additions & 0 deletions api-get-lifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Minio Go Library for Amazon S3 Compatible Cloud Storage
* Copyright 2015-2017 Minio, Inc.
*
* 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 minio

import (
"context"
"io/ioutil"
"net/http"
"net/url"

"github.com/minio/minio-go/pkg/s3utils"
)

// GetBucketLifecycle - get bucket lifecycle.
func (c Client) GetBucketLifecycle(bucketName string) (string, error) {
// Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
return "", err
}
bucketLifecycle, err := c.getBucketLifecycle(bucketName)
if err != nil {
errResponse := ToErrorResponse(err)
if errResponse.Code == "NoSuchLifecycleConfiguration" {
return "", nil
}
return "", err
}
return bucketLifecycle, nil
}

// Request server for current bucket lifecycle.
func (c Client) getBucketLifecycle(bucketName string) (string, error) {
// Get resources properly escaped and lined up before
// using them in http request.
urlValues := make(url.Values)
urlValues.Set("lifecycle", "")

// Execute GET on bucket to get lifecycle.
resp, err := c.executeMethod(context.Background(), "GET", requestMetadata{
bucketName: bucketName,
queryValues: urlValues,
})

defer closeResponse(resp)
if err != nil {
return "", err
}

if resp != nil {
if resp.StatusCode != http.StatusOK {
return "", httpRespToErrorResponse(resp, bucketName, "")
}
}

bucketLifecycleBuf, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}

lifecycle := string(bucketLifecycleBuf)
return lifecycle, err
}
81 changes: 81 additions & 0 deletions api-put-bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,87 @@ func (c Client) removeBucketPolicy(bucketName string) error {
return nil
}

// SetBucketLifecycle set the lifecycle on an existing bucket.
func (c Client) SetBucketLifecycle(bucketName, lifecycle string) error {
// Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
return err
}

// If lifecycle is empty then delete it.
if lifecycle == "" {
return c.removeBucketLifecycle(bucketName)
}

// Save the updated lifecycle.
return c.putBucketLifecycle(bucketName, lifecycle)
}

// Saves a new bucket lifecycle.
func (c Client) putBucketLifecycle(bucketName, lifecycle string) error {
// Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
return err
}

// Get resources properly escaped and lined up before
// using them in http request.
urlValues := make(url.Values)
urlValues.Set("lifecycle", "")

// Content-length is mandatory for put lifecycle request
lifecycleReader := strings.NewReader(lifecycle)
b, err := ioutil.ReadAll(lifecycleReader)
if err != nil {
return err
}

reqMetadata := requestMetadata{
bucketName: bucketName,
queryValues: urlValues,
contentBody: lifecycleReader,
contentLength: int64(len(b)),
contentMD5Base64: sumMD5Base64(b),
}

// Execute PUT to upload a new bucket lifecycle.
resp, err := c.executeMethod(context.Background(), "PUT", reqMetadata)
defer closeResponse(resp)
if err != nil {
return err
}
if resp != nil {
if resp.StatusCode != http.StatusOK {
return httpRespToErrorResponse(resp, bucketName, "")
}
}
return nil
}

// Remove lifecycle from a bucket.
func (c Client) removeBucketLifecycle(bucketName string) error {
// Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
return err
}
// Get resources properly escaped and lined up before
// using them in http request.
urlValues := make(url.Values)
urlValues.Set("lifecycle", "")

// Execute DELETE on objectName.
resp, err := c.executeMethod(context.Background(), "DELETE", requestMetadata{
bucketName: bucketName,
queryValues: urlValues,
contentSHA256Hex: emptySHA256Hex,
})
defer closeResponse(resp)
if err != nil {
return err
}
return nil
}

// SetBucketNotification saves a new bucket notification.
func (c Client) SetBucketNotification(bucketName string, bucketNotification BucketNotification) error {
// Input validation.
Expand Down
70 changes: 68 additions & 2 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func main() {
| [`RemoveBucket`](#RemoveBucket) | [`StatObject`](#StatObject) | [`StatObject`](#StatObject) | | [`GetBucketNotification`](#GetBucketNotification) | [`TraceOff`](#TraceOff) |
| [`ListObjects`](#ListObjects) | [`RemoveObject`](#RemoveObject) | | | [`RemoveAllBucketNotification`](#RemoveAllBucketNotification) | [`SetS3TransferAccelerate`](#SetS3TransferAccelerate) |
| [`ListObjectsV2`](#ListObjectsV2) | [`RemoveObjects`](#RemoveObjects) | | | [`ListenBucketNotification`](#ListenBucketNotification) | |
| [`ListIncompleteUploads`](#ListIncompleteUploads) | [`RemoveIncompleteUpload`](#RemoveIncompleteUpload) | | | | |
| | [`FPutObject`](#FPutObject) | [`FPutObject`](#FPutObject) | | | |
| [`ListIncompleteUploads`](#ListIncompleteUploads) | [`RemoveIncompleteUpload`](#RemoveIncompleteUpload) | | | [`SetBucketLifecycle`](#SetBucketLifecycle) | |
| | [`FPutObject`](#FPutObject) | [`FPutObject`](#FPutObject) | | [`GetBucketLifecycle`](#GetBucketLifecycle) | |
| | [`FGetObject`](#FGetObject) | [`FGetObject`](#FGetObject) | | | |
| | [`ComposeObject`](#ComposeObject) | [`ComposeObject`](#ComposeObject) | | | |
| | [`NewSourceInfo`](#NewSourceInfo) | [`NewSourceInfo`](#NewSourceInfo) | | | |
Expand Down Expand Up @@ -1445,6 +1445,72 @@ for notificationInfo := range minioClient.ListenBucketNotification("mybucket", "
}
```

<a name="SetBucketLifecycle"></a>
### SetBucketLifecycle(bucketname, lifecycle string) error
Set lifecycle on bucket or an object prefix.

__Parameters__

|Param |Type |Description |
|:---|:---| :---|
|`bucketName` | _string_ |Name of the bucket|
|`lifecycle` | _string_ |Lifecycle to be set |

__Return Values__

|Param |Type |Description |
|:---|:---| :---|
|`err` | _error_ |Standard Error |

__Example__

```go
lifecycle := `<LifecycleConfiguration>
<Rule>
<ID>expire-bucket</ID>
<Prefix></Prefix>
<Status>Enabled</Status>
<Expiration>
<Days>365</Days>
</Expiration>
</Rule>
</LifecycleConfiguration>`

err = minioClient.SetBucketLifecycle("my-bucketname", lifecycle)
if err != nil {
fmt.Println(err)
return
}
```

<a name="GetBucketLifecycle"></a>
### GetBucketLifecycle(bucketName) (lifecycle string, error)
Get lifecycle on a bucket or a prefix.

__Parameters__


|Param |Type |Description |
|:---|:---| :---|
|`bucketName` | _string_ |Name of the bucket |

__Return Values__


|Param |Type |Description |
|:---|:---| :---|
|`lifecycle` | _string_ |Lifecycle returned from the server |
|`err` | _error_ |Standard Error |

__Example__

```go
lifecycle, err := minioClient.GetBucketLifecycle("my-bucketname")
if err != nil {
log.Fatalln(err)
}
```

## 7. Client custom settings

<a name="SetAppInfo"></a>
Expand Down
65 changes: 65 additions & 0 deletions examples/s3/getbucketlifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// +build ignore

/*
* Minio Go Library for Amazon S3 Compatible Cloud Storage
* Copyright 2015-2017 Minio, Inc.
*
* 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 main

import (
"io"
"log"
"os"
"strings"

"github.com/minio/minio-go"
)

func main() {
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.

// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
// This boolean value is the last argument for New().

// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
// determined based on the Endpoint value.
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
if err != nil {
log.Fatalln(err)
}

// s3Client.TraceOn(os.Stderr)

// Get bucket lifecycle from S3
lifecycle, err := s3Client.GetBucketLifecycle("my-bucketname")
if err != nil {
log.Fatalln(err)
}

// Create lifecycle file
localLifecycleFile, err := os.Create("lifecycle.json")
if err != nil {
log.Fatalln(err)
}
defer localLifecycleFile.Close()

lifecycleReader := strings.NewReader(lifecycle)

if _, err := io.Copy(localLifecycleFile, lifecycleReader); err != nil {
log.Fatalln(err)
}
}
50 changes: 50 additions & 0 deletions examples/s3/setbucketlifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// +build ignore

/*
* Minio Go Library for Amazon S3 Compatible Cloud Storage
* Copyright 2015-2017 Minio, Inc.
*
* 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 main

import (
"log"

"github.com/minio/minio-go"
)

func main() {
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.

// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
// This boolean value is the last argument for New().

// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
// determined based on the Endpoint value.
s3Client, err := minio.New("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true)
if err != nil {
log.Fatalln(err)
}

// s3Client.TraceOn(os.Stderr)

// Set lifecycle on a bucket
lifecycle := `<LifecycleConfiguration><Rule><ID>expire-bucket</ID><Prefix></Prefix><Status>Enabled</Status><Expiration><Days>365</Days></Expiration></Rule></LifecycleConfiguration>`
err = s3Client.SetBucketLifecycle("my-bucketname", lifecycle)
if err != nil {
log.Fatalln(err)
}
}

0 comments on commit c7d7f0e

Please sign in to comment.