aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/minio
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2020-10-16 07:06:27 +0200
committerGitHub <noreply@github.com>2020-10-16 01:06:27 -0400
commit12a1f914f443cc31af4bc54ab43802a75742cd57 (patch)
tree998e159281cf41de8b6d7bb1ab5075b3286ce5a9 /vendor/github.com/minio
parent91f2afdb546364195ff909186983b94a61ab3181 (diff)
downloadgitea-12a1f914f443cc31af4bc54ab43802a75742cd57.tar.gz
gitea-12a1f914f443cc31af4bc54ab43802a75742cd57.zip
Vendor Update Go Libs (#13166)
* update github.com/alecthomas/chroma v0.8.0 -> v0.8.1 * github.com/blevesearch/bleve v1.0.10 -> v1.0.12 * editorconfig-core-go v2.1.1 -> v2.3.7 * github.com/gliderlabs/ssh v0.2.2 -> v0.3.1 * migrate editorconfig.ParseBytes to Parse * github.com/shurcooL/vfsgen to 0d455de96546 * github.com/go-git/go-git/v5 v5.1.0 -> v5.2.0 * github.com/google/uuid v1.1.1 -> v1.1.2 * github.com/huandu/xstrings v1.3.0 -> v1.3.2 * github.com/klauspost/compress v1.10.11 -> v1.11.1 * github.com/markbates/goth v1.61.2 -> v1.65.0 * github.com/mattn/go-sqlite3 v1.14.0 -> v1.14.4 * github.com/mholt/archiver v3.3.0 -> v3.3.2 * github.com/microcosm-cc/bluemonday 4f7140c49acb -> v1.0.4 * github.com/minio/minio-go v7.0.4 -> v7.0.5 * github.com/olivere/elastic v7.0.9 -> v7.0.20 * github.com/urfave/cli v1.20.0 -> v1.22.4 * github.com/prometheus/client_golang v1.1.0 -> v1.8.0 * github.com/xanzy/go-gitlab v0.37.0 -> v0.38.1 * mvdan.cc/xurls v2.1.0 -> v2.2.0 Co-authored-by: Lauris BH <lauris@nix.lv>
Diffstat (limited to 'vendor/github.com/minio')
-rw-r--r--vendor/github.com/minio/minio-go/v7/README.md9
-rw-r--r--vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go4
-rw-r--r--vendor/github.com/minio/minio-go/v7/api-put-object.go4
-rw-r--r--vendor/github.com/minio/minio-go/v7/api.go18
-rw-r--r--vendor/github.com/minio/minio-go/v7/constants.go1
-rw-r--r--vendor/github.com/minio/minio-go/v7/go.mod2
-rw-r--r--vendor/github.com/minio/minio-go/v7/go.sum7
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go210
8 files changed, 183 insertions, 72 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/README.md b/vendor/github.com/minio/minio-go/v7/README.md
index 0c83e9efb1..d289f615af 100644
--- a/vendor/github.com/minio/minio-go/v7/README.md
+++ b/vendor/github.com/minio/minio-go/v7/README.md
@@ -45,7 +45,7 @@ func main() {
log.Fatalln(err)
}
- log.Printf("%#v\n", minioClient) // minioClient is now setup
+ log.Printf("%#v\n", minioClient) // minioClient is now set up
}
```
@@ -67,6 +67,7 @@ import (
)
func main() {
+ ctx := context.Background()
endpoint := "play.min.io"
accessKeyID := "Q3AM3UQ867SPQQA43P2F"
secretAccessKey := "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"
@@ -85,10 +86,10 @@ func main() {
bucketName := "mymusic"
location := "us-east-1"
- err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: location})
+ err = minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
if err != nil {
// Check to see if we already own this bucket (which happens if you run this twice)
- exists, errBucketExists := minioClient.BucketExists(bucketName)
+ exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
if errBucketExists == nil && exists {
log.Printf("We already own %s\n", bucketName)
} else {
@@ -104,7 +105,7 @@ func main() {
contentType := "application/zip"
// Upload the zip file with FPutObject
- n, err := minioClient.FPutObject(context.Background(), bucketName, objectName, filePath, minio.PutObjectOptions{ContentType: contentType})
+ n, err := minioClient.FPutObject(ctx, bucketName, objectName, filePath, minio.PutObjectOptions{ContentType: contentType})
if err != nil {
log.Fatalln(err)
}
diff --git a/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go b/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go
index 251fee9f84..cd29096323 100644
--- a/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go
+++ b/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go
@@ -457,8 +457,12 @@ func (c Client) putObjectDo(ctx context.Context, bucketName, objectName string,
}
urlValues := make(url.Values)
urlValues.Set("versionId", opts.ReplicationVersionID)
+ if opts.ReplicationETag != "" {
+ urlValues.Set("etag", opts.ReplicationETag)
+ }
reqMetadata.queryValues = urlValues
}
+
// Execute PUT an objectName.
resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata)
defer closeResponse(resp)
diff --git a/vendor/github.com/minio/minio-go/v7/api-put-object.go b/vendor/github.com/minio/minio-go/v7/api-put-object.go
index b0d5af466b..14a2c16a0e 100644
--- a/vendor/github.com/minio/minio-go/v7/api-put-object.go
+++ b/vendor/github.com/minio/minio-go/v7/api-put-object.go
@@ -73,6 +73,7 @@ type PutObjectOptions struct {
SendContentMd5 bool
DisableMultipart bool
ReplicationVersionID string
+ ReplicationETag string
ReplicationStatus ReplicationStatus
ReplicationMTime time.Time
}
@@ -142,6 +143,9 @@ func (opts PutObjectOptions) Header() (header http.Header) {
if !opts.ReplicationMTime.IsZero() {
header.Set(minIOBucketReplicationSourceMTime, opts.ReplicationMTime.Format(time.RFC3339))
}
+ if opts.ReplicationETag != "" {
+ header.Set(minIOBucketReplicationETag, opts.ReplicationETag)
+ }
if len(opts.UserTags) != 0 {
header.Set(amzTaggingHeader, s3utils.TagEncode(opts.UserTags))
}
diff --git a/vendor/github.com/minio/minio-go/v7/api.go b/vendor/github.com/minio/minio-go/v7/api.go
index 206e05dee2..e36c796603 100644
--- a/vendor/github.com/minio/minio-go/v7/api.go
+++ b/vendor/github.com/minio/minio-go/v7/api.go
@@ -108,7 +108,7 @@ type Options struct {
// Global constants.
const (
libraryName = "minio-go"
- libraryVersion = "v7.0.4"
+ libraryVersion = "v7.0.5"
)
// User Agent should always following the below style.
@@ -517,13 +517,6 @@ func (c Client) executeMethod(ctx context.Context, method string, metadata reque
var bodySeeker io.Seeker // Extracted seeker from io.Reader.
var reqRetry = MaxRetry // Indicates how many times we can retry the request
- defer func() {
- if err != nil {
- // close idle connections before returning, upon error.
- c.httpClient.CloseIdleConnections()
- }
- }()
-
if metadata.contentBody != nil {
// Check if body is seekable then it is retryable.
bodySeeker, retryable = metadata.contentBody.(io.Seeker)
@@ -578,15 +571,14 @@ func (c Client) executeMethod(ctx context.Context, method string, metadata reque
return nil, err
}
- // Add context to request
- req = req.WithContext(ctx)
-
// Initiate the request.
res, err = c.do(req)
if err != nil {
- if err == context.Canceled || err == context.DeadlineExceeded {
+ if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return nil, err
}
+
+ // Retry the request
continue
}
@@ -710,7 +702,7 @@ func (c Client) newRequest(ctx context.Context, method string, metadata requestM
}
// Initialize a new HTTP request for the method.
- req, err = http.NewRequest(method, targetURL.String(), nil)
+ req, err = http.NewRequestWithContext(ctx, method, targetURL.String(), nil)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/minio/minio-go/v7/constants.go b/vendor/github.com/minio/minio-go/v7/constants.go
index e1da72e79f..6a1b8d3dda 100644
--- a/vendor/github.com/minio/minio-go/v7/constants.go
+++ b/vendor/github.com/minio/minio-go/v7/constants.go
@@ -83,4 +83,5 @@ const (
amzBucketReplicationStatus = "X-Amz-Replication-Status"
// Minio specific Replication extension
minIOBucketReplicationSourceMTime = "X-Minio-Source-Mtime"
+ minIOBucketReplicationETag = "X-Minio-Source-Etag"
)
diff --git a/vendor/github.com/minio/minio-go/v7/go.mod b/vendor/github.com/minio/minio-go/v7/go.mod
index 670f6ea94c..448b4bbf17 100644
--- a/vendor/github.com/minio/minio-go/v7/go.mod
+++ b/vendor/github.com/minio/minio-go/v7/go.mod
@@ -3,7 +3,6 @@ module github.com/minio/minio-go/v7
go 1.12
require (
- github.com/dustin/go-humanize v1.0.0 // indirect
github.com/google/uuid v1.1.1
github.com/json-iterator/go v1.1.10
github.com/klauspost/cpuid v1.3.1 // indirect
@@ -14,7 +13,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/rs/xid v1.2.1
- github.com/sirupsen/logrus v1.6.0 // indirect
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
github.com/stretchr/testify v1.4.0 // indirect
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
diff --git a/vendor/github.com/minio/minio-go/v7/go.sum b/vendor/github.com/minio/minio-go/v7/go.sum
index 1dce33dd45..1858b6ff38 100644
--- a/vendor/github.com/minio/minio-go/v7/go.sum
+++ b/vendor/github.com/minio/minio-go/v7/go.sum
@@ -1,8 +1,6 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
-github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -16,7 +14,6 @@ github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -40,14 +37,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
-github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
@@ -63,7 +57,6 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go b/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go
index 57e63a08cd..fdd0afbc8d 100644
--- a/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go
+++ b/vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go
@@ -53,7 +53,10 @@ type Options struct {
Priority string
TagString string
StorageClass string
- Arn string
+ RoleArn string
+ DestBucket string
+ IsTagSet bool
+ IsSCSet bool
}
// Tags returns a slice of tags for a rule
@@ -89,6 +92,24 @@ func (c *Config) Empty() bool {
// AddRule adds a new rule to existing replication config. If a rule exists with the
// same ID, then the rule is replaced.
func (c *Config) AddRule(opts Options) error {
+ priority, err := strconv.Atoi(opts.Priority)
+ if err != nil {
+ return err
+ }
+ if opts.RoleArn != c.Role && c.Role != "" {
+ return fmt.Errorf("Role ARN does not match existing configuration")
+ }
+ var status Status
+ // toggle rule status for edit option
+ switch opts.RuleStatus {
+ case "enable":
+ status = Enabled
+ case "disable":
+ status = Disabled
+ default:
+ return fmt.Errorf("Rule state should be either [enable|disable]")
+ }
+
tags := opts.Tags()
andVal := And{
Tags: opts.Tags(),
@@ -103,32 +124,33 @@ func (c *Config) AddRule(opts Options) error {
filter.And = andVal
filter.And.Prefix = opts.Prefix
filter.Prefix = ""
+ filter.Tag = Tag{}
}
if opts.ID == "" {
opts.ID = xid.New().String()
}
- var status Status
- // toggle rule status for edit option
- switch opts.RuleStatus {
- case "enable":
- status = Enabled
- case "disable":
- status = Disabled
- }
- arnStr := opts.Arn
- if opts.Arn == "" {
+ arnStr := opts.RoleArn
+ if opts.RoleArn == "" {
arnStr = c.Role
}
+ if arnStr == "" {
+ return fmt.Errorf("Role ARN required")
+ }
tokens := strings.Split(arnStr, ":")
if len(tokens) != 6 {
return fmt.Errorf("invalid format for replication Arn")
}
- if c.Role == "" { // for new configurations
- c.Role = opts.Arn
+ if c.Role == "" {
+ c.Role = arnStr
}
- priority, err := strconv.Atoi(opts.Priority)
- if err != nil {
- return err
+ destBucket := opts.DestBucket
+ // ref https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-arn-format.html
+ if btokens := strings.Split(destBucket, ":"); len(btokens) != 6 {
+ if len(btokens) == 1 {
+ destBucket = fmt.Sprintf("arn:aws:s3:::%s", destBucket)
+ } else {
+ return fmt.Errorf("destination bucket needs to be in Arn format")
+ }
}
newRule := Rule{
ID: opts.ID,
@@ -136,56 +158,147 @@ func (c *Config) AddRule(opts Options) error {
Status: status,
Filter: filter,
Destination: Destination{
- Bucket: fmt.Sprintf("arn:aws:s3:::%s", tokens[5]),
+ Bucket: destBucket,
StorageClass: opts.StorageClass,
},
DeleteMarkerReplication: DeleteMarkerReplication{Status: Disabled},
}
- ruleFound := false
- for i, rule := range c.Rules {
- if rule.Priority == newRule.Priority && rule.ID != newRule.ID {
+ // validate rule after overlaying priority for pre-existing rule being disabled.
+ if err := newRule.Validate(); err != nil {
+ return err
+ }
+ for _, rule := range c.Rules {
+ if rule.Priority == newRule.Priority {
return fmt.Errorf("Priority must be unique. Replication configuration already has a rule with this priority")
}
if rule.Destination.Bucket != newRule.Destination.Bucket {
return fmt.Errorf("The destination bucket must be same for all rules")
}
- if rule.ID != newRule.ID {
- continue
+ if rule.ID == newRule.ID {
+ return fmt.Errorf("A rule exists with this ID")
}
- if opts.Priority == "" && rule.ID == newRule.ID {
- // inherit priority from existing rule, required field on server
- newRule.Priority = rule.Priority
+ }
+
+ c.Rules = append(c.Rules, newRule)
+ return nil
+}
+
+// EditRule modifies an existing rule in replication config
+func (c *Config) EditRule(opts Options) error {
+ if opts.ID == "" {
+ return fmt.Errorf("Rule ID missing")
+ }
+ rIdx := -1
+ var newRule Rule
+ for i, rule := range c.Rules {
+ if rule.ID == opts.ID {
+ rIdx = i
+ newRule = rule
+ break
+ }
+ }
+ if rIdx < 0 {
+ return fmt.Errorf("Rule with ID %s not found in replication configuration", opts.ID)
+ }
+ prefixChg := opts.Prefix != newRule.Prefix()
+ if opts.IsTagSet || prefixChg {
+ prefix := newRule.Prefix()
+ if prefix != opts.Prefix {
+ prefix = opts.Prefix
}
- if opts.RuleStatus == "" {
- newRule.Status = rule.Status
+ tags := []Tag{newRule.Filter.Tag}
+ if len(newRule.Filter.And.Tags) != 0 {
+ tags = newRule.Filter.And.Tags
}
- c.Rules[i] = newRule
- ruleFound = true
- break
+ if opts.IsTagSet {
+ tags = opts.Tags()
+ }
+ andVal := And{
+ Tags: tags,
+ }
+
+ filter := Filter{Prefix: prefix}
+ // only a single tag is set.
+ if prefix == "" && len(tags) == 1 {
+ filter.Tag = tags[0]
+ }
+ // both prefix and tag are present
+ if len(andVal.Tags) > 1 || prefix != "" {
+ filter.And = andVal
+ filter.And.Prefix = prefix
+ filter.Prefix = ""
+ filter.Tag = Tag{}
+ }
+ newRule.Filter = filter
}
- // validate rule after overlaying priority for pre-existing rule being disabled.
+
+ // toggle rule status for edit option
+ if opts.RuleStatus != "" {
+ switch opts.RuleStatus {
+ case "enable":
+ newRule.Status = Enabled
+ case "disable":
+ newRule.Status = Disabled
+ default:
+ return fmt.Errorf("Rule state should be either [enable|disable]")
+ }
+ }
+
+ if opts.IsSCSet {
+ newRule.Destination.StorageClass = opts.StorageClass
+ }
+ if opts.Priority != "" {
+ priority, err := strconv.Atoi(opts.Priority)
+ if err != nil {
+ return err
+ }
+ newRule.Priority = priority
+ }
+ if opts.DestBucket != "" {
+ destBucket := opts.DestBucket
+ // ref https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-arn-format.html
+ if btokens := strings.Split(opts.DestBucket, ":"); len(btokens) != 6 {
+ if len(btokens) == 1 {
+ destBucket = fmt.Sprintf("arn:aws:s3:::%s", destBucket)
+ } else {
+ return fmt.Errorf("destination bucket needs to be in Arn format")
+ }
+ }
+ newRule.Destination.Bucket = destBucket
+ }
+ // validate rule
if err := newRule.Validate(); err != nil {
return err
}
- if !ruleFound && opts.Op == SetOption {
- return fmt.Errorf("Rule with ID %s not found in replication configuration", opts.ID)
- }
- if !ruleFound {
- c.Rules = append(c.Rules, newRule)
+ // ensure priority and destination bucket restrictions are not violated
+ for idx, rule := range c.Rules {
+ if rule.Priority == newRule.Priority && rIdx != idx {
+ return fmt.Errorf("Priority must be unique. Replication configuration already has a rule with this priority")
+ }
+ if rule.Destination.Bucket != newRule.Destination.Bucket {
+ return fmt.Errorf("The destination bucket must be same for all rules")
+ }
}
+
+ c.Rules[rIdx] = newRule
return nil
}
// RemoveRule removes a rule from replication config.
func (c *Config) RemoveRule(opts Options) error {
var newRules []Rule
+ ruleFound := false
for _, rule := range c.Rules {
if rule.ID != opts.ID {
newRules = append(newRules, rule)
+ continue
}
+ ruleFound = true
+ }
+ if !ruleFound {
+ return fmt.Errorf("Rule with ID %s not found", opts.ID)
}
-
if len(newRules) == 0 {
return fmt.Errorf("Replication configuration should have at least one rule")
}
@@ -268,17 +381,19 @@ func (r Rule) Prefix() string {
// <filter><and></and></filter>. This method returns all the tags from the
// rule in the format tag1=value1&tag2=value2
func (r Rule) Tags() string {
+ ts := []Tag{r.Filter.Tag}
if len(r.Filter.And.Tags) != 0 {
- var buf bytes.Buffer
- for _, t := range r.Filter.And.Tags {
- if buf.Len() > 0 {
- buf.WriteString("&")
- }
- buf.WriteString(t.String())
+ ts = r.Filter.And.Tags
+ }
+
+ var buf bytes.Buffer
+ for _, t := range ts {
+ if buf.Len() > 0 {
+ buf.WriteString("&")
}
- return buf.String()
+ buf.WriteString(t.String())
}
- return ""
+ return buf.String()
}
// Filter - a filter for a replication configuration Rule.
@@ -321,6 +436,9 @@ type Tag struct {
}
func (tag Tag) String() string {
+ if tag.IsEmpty() {
+ return ""
+ }
return tag.Key + "=" + tag.Value
}
@@ -352,7 +470,7 @@ type Destination struct {
type And struct {
XMLName xml.Name `xml:"And,omitempty" json:"-"`
Prefix string `xml:"Prefix,omitempty" json:"Prefix,omitempty"`
- Tags []Tag `xml:"Tag,omitempty" json:"Tags,omitempty"`
+ Tags []Tag `xml:"Tags,omitempty" json:"Tags,omitempty"`
}
// isEmpty returns true if Tags field is null