aboutsummaryrefslogtreecommitdiff
path: root/vendor/cloud.google.com/go/storage/bucket.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/cloud.google.com/go/storage/bucket.go')
-rw-r--r--vendor/cloud.google.com/go/storage/bucket.go271
1 files changed, 250 insertions, 21 deletions
diff --git a/vendor/cloud.google.com/go/storage/bucket.go b/vendor/cloud.google.com/go/storage/bucket.go
index 07852a5..93473ce 100644
--- a/vendor/cloud.google.com/go/storage/bucket.go
+++ b/vendor/cloud.google.com/go/storage/bucket.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. LiveAndArchived Rights Reserved.
+// Copyright 2014 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import (
"time"
"cloud.google.com/go/internal/optional"
+ "cloud.google.com/go/internal/trace"
"golang.org/x/net/context"
"google.golang.org/api/googleapi"
"google.golang.org/api/iterator"
@@ -35,7 +36,7 @@ type BucketHandle struct {
acl ACLHandle
defaultObjectACL ACLHandle
conds *BucketConditions
- userProject string // project for requester-pays buckets
+ userProject string // project for Requester Pays buckets
}
// Bucket returns a BucketHandle, which provides operations on the named bucket.
@@ -63,7 +64,10 @@ func (c *Client) Bucket(name string) *BucketHandle {
// Create creates the Bucket in the project.
// If attrs is nil the API defaults will be used.
-func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *BucketAttrs) error {
+func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *BucketAttrs) (err error) {
+ ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Create")
+ defer func() { trace.EndSpan(ctx, err) }()
+
var bkt *raw.Bucket
if attrs != nil {
bkt = attrs.toRawBucket()
@@ -82,7 +86,10 @@ func (b *BucketHandle) Create(ctx context.Context, projectID string, attrs *Buck
}
// Delete deletes the Bucket.
-func (b *BucketHandle) Delete(ctx context.Context) error {
+func (b *BucketHandle) Delete(ctx context.Context) (err error) {
+ ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Delete")
+ defer func() { trace.EndSpan(ctx, err) }()
+
req, err := b.newDeleteCall()
if err != nil {
return err
@@ -139,7 +146,10 @@ func (b *BucketHandle) Object(name string) *ObjectHandle {
}
// Attrs returns the metadata for the bucket.
-func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) {
+func (b *BucketHandle) Attrs(ctx context.Context) (attrs *BucketAttrs, err error) {
+ ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Attrs")
+ defer func() { trace.EndSpan(ctx, err) }()
+
req, err := b.newGetCall()
if err != nil {
return nil, err
@@ -155,7 +165,7 @@ func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) {
if err != nil {
return nil, err
}
- return newBucket(resp), nil
+ return newBucket(resp)
}
func (b *BucketHandle) newGetCall() (*raw.BucketsGetCall, error) {
@@ -170,7 +180,10 @@ func (b *BucketHandle) newGetCall() (*raw.BucketsGetCall, error) {
return req, nil
}
-func (b *BucketHandle) Update(ctx context.Context, uattrs BucketAttrsToUpdate) (*BucketAttrs, error) {
+func (b *BucketHandle) Update(ctx context.Context, uattrs BucketAttrsToUpdate) (attrs *BucketAttrs, err error) {
+ ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Create")
+ defer func() { trace.EndSpan(ctx, err) }()
+
req, err := b.newPatchCall(&uattrs)
if err != nil {
return nil, err
@@ -180,7 +193,7 @@ func (b *BucketHandle) Update(ctx context.Context, uattrs BucketAttrsToUpdate) (
if err != nil {
return nil, err
}
- return newBucket(rb), nil
+ return newBucket(rb)
}
func (b *BucketHandle) newPatchCall(uattrs *BucketAttrsToUpdate) (*raw.BucketsPatchCall, error) {
@@ -237,9 +250,28 @@ type BucketAttrs struct {
Labels map[string]string
// RequesterPays reports whether the bucket is a Requester Pays bucket.
+ // Clients performing operations on Requester Pays buckets must provide
+ // a user project (see BucketHandle.UserProject), which will be billed
+ // for the operations.
RequesterPays bool
+
// Lifecycle is the lifecycle configuration for objects in the bucket.
Lifecycle Lifecycle
+
+ // Retention policy enforces a minimum retention time for all objects
+ // contained in the bucket. A RetentionPolicy of nil implies the bucket
+ // has no minimum data retention.
+ //
+ // This feature is in private alpha release. It is not currently available to
+ // most customers. It might be changed in backwards-incompatible ways and is not
+ // subject to any SLA or deprecation policy.
+ RetentionPolicy *RetentionPolicy
+
+ // The bucket's Cross-Origin Resource Sharing (CORS) configuration.
+ CORS []CORS
+
+ // The encryption configuration used by default for newly inserted objects.
+ Encryption *BucketEncryption
}
// Lifecycle is the lifecycle configuration for objects in the bucket.
@@ -247,12 +279,37 @@ type Lifecycle struct {
Rules []LifecycleRule
}
+// Retention policy enforces a minimum retention time for all objects
+// contained in the bucket.
+//
+// Any attempt to overwrite or delete objects younger than the retention
+// period will result in an error. An unlocked retention policy can be
+// modified or removed from the bucket via the Update method. A
+// locked retention policy cannot be removed or shortened in duration
+// for the lifetime of the bucket.
+//
+// This feature is in private alpha release. It is not currently available to
+// most customers. It might be changed in backwards-incompatible ways and is not
+// subject to any SLA or deprecation policy.
+type RetentionPolicy struct {
+ // RetentionPeriod specifies the duration that objects need to be
+ // retained. Retention duration must be greater than zero and less than
+ // 100 years. Note that enforcement of retention periods less than a day
+ // is not guaranteed. Such periods should only be used for testing
+ // purposes.
+ RetentionPeriod time.Duration
+
+ // EffectiveTime is the time from which the policy was enforced and
+ // effective. This field is read-only.
+ EffectiveTime time.Time
+}
+
const (
// RFC3339 date with only the date segment, used for CreatedBefore in LifecycleRule.
rfc3339Date = "2006-01-02"
// DeleteAction is a lifecycle action that deletes a live and/or archived
- // objects. Takes precendence over SetStorageClass actions.
+ // objects. Takes precedence over SetStorageClass actions.
DeleteAction = "Delete"
// SetStorageClassAction changes the storage class of live and/or archived
@@ -332,9 +389,13 @@ type LifecycleCondition struct {
NumNewerVersions int64
}
-func newBucket(b *raw.Bucket) *BucketAttrs {
+func newBucket(b *raw.Bucket) (*BucketAttrs, error) {
if b == nil {
- return nil
+ return nil, nil
+ }
+ rp, err := toRetentionPolicy(b.RetentionPolicy)
+ if err != nil {
+ return nil, err
}
bucket := &BucketAttrs{
Name: b.Name,
@@ -346,6 +407,9 @@ func newBucket(b *raw.Bucket) *BucketAttrs {
Labels: b.Labels,
RequesterPays: b.Billing != nil && b.Billing.RequesterPays,
Lifecycle: toLifecycle(b.Lifecycle),
+ RetentionPolicy: rp,
+ CORS: toCORS(b.Cors),
+ Encryption: toBucketEncryption(b.Encryption),
}
acl := make([]ACLRule, len(b.Acl))
for i, rule := range b.Acl {
@@ -363,7 +427,7 @@ func newBucket(b *raw.Bucket) *BucketAttrs {
}
}
bucket.DefaultObjectACL = objACL
- return bucket
+ return bucket, nil
}
// toRawBucket copies the editable attribute from b to the raw library's Bucket type.
@@ -408,16 +472,70 @@ func (b *BucketAttrs) toRawBucket() *raw.Bucket {
Labels: labels,
Billing: bb,
Lifecycle: toRawLifecycle(b.Lifecycle),
+ RetentionPolicy: b.RetentionPolicy.toRawRetentionPolicy(),
+ Cors: toRawCORS(b.CORS),
+ Encryption: b.Encryption.toRawBucketEncryption(),
}
}
+// CORS is the bucket's Cross-Origin Resource Sharing (CORS) configuration.
+type CORS struct {
+ // MaxAge is the value to return in the Access-Control-Max-Age
+ // header used in preflight responses.
+ MaxAge time.Duration
+
+ // Methods is the list of HTTP methods on which to include CORS response
+ // headers, (GET, OPTIONS, POST, etc) Note: "*" is permitted in the list
+ // of methods, and means "any method".
+ Methods []string
+
+ // Origins is the list of Origins eligible to receive CORS response
+ // headers. Note: "*" is permitted in the list of origins, and means
+ // "any Origin".
+ Origins []string
+
+ // ResponseHeaders is the list of HTTP headers other than the simple
+ // response headers to give permission for the user-agent to share
+ // across domains.
+ ResponseHeaders []string
+}
+
+// BucketEncryption is a bucket's encryption configuration.
+type BucketEncryption struct {
+ // A Cloud KMS key name, in the form
+ // projects/P/locations/L/keyRings/R/cryptoKeys/K, that will be used to encrypt
+ // objects inserted into this bucket, if no encryption method is specified.
+ // The key's location must be the same as the bucket's.
+ DefaultKMSKeyName string
+}
+
type BucketAttrsToUpdate struct {
- // VersioningEnabled, if set, updates whether the bucket uses versioning.
+ // If set, updates whether the bucket uses versioning.
VersioningEnabled optional.Bool
- // RequesterPays, if set, updates whether the bucket is a Requester Pays bucket.
+ // If set, updates whether the bucket is a Requester Pays bucket.
RequesterPays optional.Bool
+ // If set, updates the retention policy of the bucket. Using
+ // RetentionPolicy.RetentionPeriod = 0 will delete the existing policy.
+ //
+ // This feature is in private alpha release. It is not currently available to
+ // most customers. It might be changed in backwards-incompatible ways and is not
+ // subject to any SLA or deprecation policy.
+ RetentionPolicy *RetentionPolicy
+
+ // If set, replaces the CORS configuration with a new configuration.
+ // An empty (rather than nil) slice causes all CORS policies to be removed.
+ CORS []CORS
+
+ // If set, replaces the encryption configuration of the bucket. Using
+ // BucketEncryption.DefaultKMSKeyName = "" will delete the existing
+ // configuration.
+ Encryption *BucketEncryption
+
+ // If set, replaces the lifecycle configuration of the bucket.
+ Lifecycle *Lifecycle
+
setLabels map[string]string
deleteLabels map[string]bool
}
@@ -442,6 +560,18 @@ func (ua *BucketAttrsToUpdate) DeleteLabel(name string) {
func (ua *BucketAttrsToUpdate) toRawBucket() *raw.Bucket {
rb := &raw.Bucket{}
+ if ua.CORS != nil {
+ rb.Cors = toRawCORS(ua.CORS)
+ rb.ForceSendFields = append(rb.ForceSendFields, "Cors")
+ }
+ if ua.RetentionPolicy != nil {
+ if ua.RetentionPolicy.RetentionPeriod == 0 {
+ rb.NullFields = append(rb.NullFields, "RetentionPolicy")
+ rb.RetentionPolicy = nil
+ } else {
+ rb.RetentionPolicy = ua.RetentionPolicy.toRawRetentionPolicy()
+ }
+ }
if ua.VersioningEnabled != nil {
rb.Versioning = &raw.BucketVersioning{
Enabled: optional.ToBool(ua.VersioningEnabled),
@@ -454,6 +584,17 @@ func (ua *BucketAttrsToUpdate) toRawBucket() *raw.Bucket {
ForceSendFields: []string{"RequesterPays"},
}
}
+ if ua.Encryption != nil {
+ if ua.Encryption.DefaultKMSKeyName == "" {
+ rb.NullFields = append(rb.NullFields, "Encryption")
+ rb.Encryption = nil
+ } else {
+ rb.Encryption = ua.Encryption.toRawBucketEncryption()
+ }
+ }
+ if ua.Lifecycle != nil {
+ rb.Lifecycle = toRawLifecycle(*ua.Lifecycle)
+ }
if ua.setLabels != nil || ua.deleteLabels != nil {
rb.Labels = map[string]string{}
for k, v := range ua.setLabels {
@@ -506,8 +647,10 @@ func (c *BucketConditions) validate(method string) error {
}
// UserProject returns a new BucketHandle that passes the project ID as the user
-// project for all subsequent calls. A user project is required for all operations
-// on requester-pays buckets.
+// project for all subsequent calls. Calls with a user project will be billed to that
+// project rather than to the bucket's owning project.
+//
+// A user project is required for all operations on Requester Pays buckets.
func (b *BucketHandle) UserProject(projectID string) *BucketHandle {
b2 := *b
b2.userProject = projectID
@@ -516,6 +659,25 @@ func (b *BucketHandle) UserProject(projectID string) *BucketHandle {
return &b2
}
+// LockRetentionPolicy locks a bucket's retention policy until a previously-configured
+// RetentionPeriod past the EffectiveTime. Note that if RetentionPeriod is set to less
+// than a day, the retention policy is treated as a development configuration and locking
+// will have no effect. The BucketHandle must have a metageneration condition that
+// matches the bucket's metageneration. See BucketHandle.If.
+//
+// This feature is in private alpha release. It is not currently available to
+// most customers. It might be changed in backwards-incompatible ways and is not
+// subject to any SLA or deprecation policy.
+func (b *BucketHandle) LockRetentionPolicy(ctx context.Context) error {
+ var metageneration int64
+ if b.conds != nil {
+ metageneration = b.conds.MetagenerationMatch
+ }
+ req := b.c.raw.Buckets.LockRetentionPolicy(b.name, metageneration)
+ _, err := req.Context(ctx).Do()
+ return err
+}
+
// applyBucketConds modifies the provided call using the conditions in conds.
// call is something that quacks like a *raw.WhateverCall.
func applyBucketConds(method string, conds *BucketConditions, call interface{}) error {
@@ -539,6 +701,55 @@ func applyBucketConds(method string, conds *BucketConditions, call interface{})
return nil
}
+func (rp *RetentionPolicy) toRawRetentionPolicy() *raw.BucketRetentionPolicy {
+ if rp == nil {
+ return nil
+ }
+ return &raw.BucketRetentionPolicy{
+ RetentionPeriod: int64(rp.RetentionPeriod / time.Second),
+ }
+}
+
+func toRetentionPolicy(rp *raw.BucketRetentionPolicy) (*RetentionPolicy, error) {
+ if rp == nil {
+ return nil, nil
+ }
+ t, err := time.Parse(time.RFC3339, rp.EffectiveTime)
+ if err != nil {
+ return nil, err
+ }
+ return &RetentionPolicy{
+ RetentionPeriod: time.Duration(rp.RetentionPeriod) * time.Second,
+ EffectiveTime: t,
+ }, nil
+}
+
+func toRawCORS(c []CORS) []*raw.BucketCors {
+ var out []*raw.BucketCors
+ for _, v := range c {
+ out = append(out, &raw.BucketCors{
+ MaxAgeSeconds: int64(v.MaxAge / time.Second),
+ Method: v.Methods,
+ Origin: v.Origins,
+ ResponseHeader: v.ResponseHeaders,
+ })
+ }
+ return out
+}
+
+func toCORS(rc []*raw.BucketCors) []CORS {
+ var out []CORS
+ for _, v := range rc {
+ out = append(out, CORS{
+ MaxAge: time.Duration(v.MaxAgeSeconds) * time.Second,
+ Methods: v.Method,
+ Origins: v.Origin,
+ ResponseHeaders: v.ResponseHeader,
+ })
+ }
+ return out
+}
+
func toRawLifecycle(l Lifecycle) *raw.BucketLifecycle {
var rl raw.BucketLifecycle
if len(l.Rules) == 0 {
@@ -604,10 +815,27 @@ func toLifecycle(rl *raw.BucketLifecycle) Lifecycle {
if rr.Condition.CreatedBefore != "" {
r.Condition.CreatedBefore, _ = time.Parse(rfc3339Date, rr.Condition.CreatedBefore)
}
+ l.Rules = append(l.Rules, r)
}
return l
}
+func (e *BucketEncryption) toRawBucketEncryption() *raw.BucketEncryption {
+ if e == nil {
+ return nil
+ }
+ return &raw.BucketEncryption{
+ DefaultKmsKeyName: e.DefaultKMSKeyName,
+ }
+}
+
+func toBucketEncryption(e *raw.BucketEncryption) *BucketEncryption {
+ if e == nil {
+ return nil
+ }
+ return &BucketEncryption{DefaultKMSKeyName: e.DefaultKmsKeyName}
+}
+
// Objects returns an iterator over the objects in the bucket that match the Query q.
// If q is nil, no filtering is done.
func (b *BucketHandle) Objects(ctx context.Context, q *Query) *ObjectIterator {
@@ -689,8 +917,6 @@ func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error)
return resp.NextPageToken, nil
}
-// TODO(jbd): Add storage.buckets.update.
-
// Buckets returns an iterator over the buckets in the project. You may
// optionally set the iterator's Prefix field to restrict the list to buckets
// whose names begin with the prefix. By default, all buckets in the project
@@ -736,7 +962,7 @@ func (it *BucketIterator) Next() (*BucketAttrs, error) {
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *BucketIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }
-func (it *BucketIterator) fetch(pageSize int, pageToken string) (string, error) {
+func (it *BucketIterator) fetch(pageSize int, pageToken string) (token string, err error) {
req := it.client.raw.Buckets.List(it.projectID)
setClientHeader(req.Header())
req.Projection("full")
@@ -746,7 +972,6 @@ func (it *BucketIterator) fetch(pageSize int, pageToken string) (string, error)
req.MaxResults(int64(pageSize))
}
var resp *raw.Buckets
- var err error
err = runWithRetry(it.ctx, func() error {
resp, err = req.Context(it.ctx).Do()
return err
@@ -755,7 +980,11 @@ func (it *BucketIterator) fetch(pageSize int, pageToken string) (string, error)
return "", err
}
for _, item := range resp.Items {
- it.buckets = append(it.buckets, newBucket(item))
+ b, err := newBucket(item)
+ if err != nil {
+ return "", err
+ }
+ it.buckets = append(it.buckets, b)
}
return resp.NextPageToken, nil
}