aboutsummaryrefslogtreecommitdiff
path: root/vendor/cloud.google.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/cloud.google.com')
-rw-r--r--vendor/cloud.google.com/go/internal/retry.go55
-rw-r--r--vendor/cloud.google.com/go/storage/bucket.go3
-rw-r--r--vendor/cloud.google.com/go/storage/copy.go16
-rw-r--r--vendor/cloud.google.com/go/storage/doc.go2
-rw-r--r--vendor/cloud.google.com/go/storage/invoke.go19
-rw-r--r--vendor/cloud.google.com/go/storage/storage.go105
-rw-r--r--vendor/cloud.google.com/go/storage/writer.go6
7 files changed, 167 insertions, 39 deletions
diff --git a/vendor/cloud.google.com/go/internal/retry.go b/vendor/cloud.google.com/go/internal/retry.go
new file mode 100644
index 0000000..79995be
--- /dev/null
+++ b/vendor/cloud.google.com/go/internal/retry.go
@@ -0,0 +1,55 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// 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 internal
+
+import (
+ "fmt"
+ "time"
+
+ gax "github.com/googleapis/gax-go"
+
+ "golang.org/x/net/context"
+)
+
+// Retry calls the supplied function f repeatedly according to the provided
+// backoff parameters. It returns when one of the following occurs:
+// When f's first return value is true, Retry immediately returns with f's second
+// return value.
+// When the provided context is done, Retry returns with ctx.Err().
+func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error {
+ return retry(ctx, bo, f, gax.Sleep)
+}
+
+func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error),
+ sleep func(context.Context, time.Duration) error) error {
+ var lastErr error
+ for {
+ stop, err := f()
+ if stop {
+ return err
+ }
+ // Remember the last "real" error from f.
+ if err != nil && err != context.Canceled && err != context.DeadlineExceeded {
+ lastErr = err
+ }
+ p := bo.Pause()
+ if cerr := sleep(ctx, p); cerr != nil {
+ if lastErr != nil {
+ return fmt.Errorf("%v; last function err: %v", cerr, lastErr)
+ }
+ return cerr
+ }
+ }
+}
diff --git a/vendor/cloud.google.com/go/storage/bucket.go b/vendor/cloud.google.com/go/storage/bucket.go
index a2be0f4..f87fe33 100644
--- a/vendor/cloud.google.com/go/storage/bucket.go
+++ b/vendor/cloud.google.com/go/storage/bucket.go
@@ -246,6 +246,9 @@ func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error)
return err
})
if err != nil {
+ if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
+ err = ErrBucketNotExist
+ }
return "", err
}
for _, item := range resp.Items {
diff --git a/vendor/cloud.google.com/go/storage/copy.go b/vendor/cloud.google.com/go/storage/copy.go
index 6adb566..1f28455 100644
--- a/vendor/cloud.google.com/go/storage/copy.go
+++ b/vendor/cloud.google.com/go/storage/copy.go
@@ -110,6 +110,12 @@ func (c *Copier) callRewrite(ctx context.Context, src *ObjectHandle, rawObj *raw
if err := applySourceConds(c.src.gen, c.src.conds, call); err != nil {
return nil, err
}
+ if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil {
+ return nil, err
+ }
+ if err := setEncryptionHeaders(call.Header(), c.src.encryptionKey, true); err != nil {
+ return nil, err
+ }
var res *raw.RewriteResponse
var err error
err = runWithRetry(ctx, func() error { res, err = call.Do(); return err })
@@ -123,6 +129,10 @@ func (c *Copier) callRewrite(ctx context.Context, src *ObjectHandle, rawObj *raw
// ComposerFrom creates a Composer that can compose srcs into dst.
// You can immediately call Run on the returned Composer, or you can
// configure it first.
+//
+// The encryption key for the destination object will be used to decrypt all
+// source objects and encrypt the destination object. It is an error
+// to specify an encryption key for any of the source objects.
func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer {
return &Composer{dst: dst, srcs: srcs}
}
@@ -158,6 +168,9 @@ func (c *Composer) Run(ctx context.Context) (*ObjectAttrs, error) {
if src.bucket != c.dst.bucket {
return nil, fmt.Errorf("storage: all source objects must be in bucket %q, found %q", c.dst.bucket, src.bucket)
}
+ if src.encryptionKey != nil {
+ return nil, fmt.Errorf("storage: compose source %s.%s must not have encryption key", src.bucket, src.object)
+ }
srcObj := &raw.ComposeRequestSourceObjects{
Name: src.object,
}
@@ -171,6 +184,9 @@ func (c *Composer) Run(ctx context.Context) (*ObjectAttrs, error) {
if err := applyConds("ComposeFrom destination", c.dst.gen, c.dst.conds, call); err != nil {
return nil, err
}
+ if err := setEncryptionHeaders(call.Header(), c.dst.encryptionKey, false); err != nil {
+ return nil, err
+ }
var obj *raw.Object
var err error
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
diff --git a/vendor/cloud.google.com/go/storage/doc.go b/vendor/cloud.google.com/go/storage/doc.go
index c23f2c8..cf6496b 100644
--- a/vendor/cloud.google.com/go/storage/doc.go
+++ b/vendor/cloud.google.com/go/storage/doc.go
@@ -23,7 +23,7 @@ All of the methods of this package use exponential backoff to retry calls
that fail with certain errors, as described in
https://cloud.google.com/storage/docs/exponential-backoff.
-Note: This package is experimental and may make backwards-incompatible changes.
+Note: This package is in beta. Some backwards-incompatible changes may occur.
Creating a Client
diff --git a/vendor/cloud.google.com/go/storage/invoke.go b/vendor/cloud.google.com/go/storage/invoke.go
index 03b98f4..e8fc924 100644
--- a/vendor/cloud.google.com/go/storage/invoke.go
+++ b/vendor/cloud.google.com/go/storage/invoke.go
@@ -15,6 +15,7 @@
package storage
import (
+ "cloud.google.com/go/internal"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/googleapi"
@@ -23,24 +24,20 @@ import (
// runWithRetry calls the function until it returns nil or a non-retryable error, or
// the context is done.
func runWithRetry(ctx context.Context, call func() error) error {
- var backoff gax.Backoff // use defaults for gax exponential backoff
- for {
- err := call()
+ return internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) {
+ err = call()
if err == nil {
- return nil
+ return true, nil
}
e, ok := err.(*googleapi.Error)
if !ok {
- return err
+ return true, err
}
// Retry on 429 and 5xx, according to
// https://cloud.google.com/storage/docs/exponential-backoff.
if e.Code == 429 || (e.Code >= 500 && e.Code < 600) {
- if err := gax.Sleep(ctx, backoff.Pause()); err != nil {
- return err
- }
- continue
+ return false, nil
}
- return err
- }
+ return true, err
+ })
}
diff --git a/vendor/cloud.google.com/go/storage/storage.go b/vendor/cloud.google.com/go/storage/storage.go
index 9dccf5a..bafb136 100644
--- a/vendor/cloud.google.com/go/storage/storage.go
+++ b/vendor/cloud.google.com/go/storage/storage.go
@@ -272,12 +272,13 @@ func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) {
// ObjectHandle provides operations on an object in a Google Cloud Storage bucket.
// Use BucketHandle.Object to get a handle.
type ObjectHandle struct {
- c *Client
- bucket string
- object string
- acl ACLHandle
- gen int64 // a negative value indicates latest
- conds *Conditions
+ c *Client
+ bucket string
+ object string
+ acl ACLHandle
+ gen int64 // a negative value indicates latest
+ conds *Conditions
+ encryptionKey []byte // AES-256 key
}
// ACL provides access to the object's access control list.
@@ -309,6 +310,17 @@ func (o *ObjectHandle) If(conds Conditions) *ObjectHandle {
return &o2
}
+// Key returns a new ObjectHandle that uses the supplied encryption
+// key to encrypt and decrypt the object's contents.
+//
+// Encryption key must be a 32-byte AES-256 key.
+// See https://cloud.google.com/storage/docs/encryption for details.
+func (o *ObjectHandle) Key(encryptionKey []byte) *ObjectHandle {
+ o2 := *o
+ o2.encryptionKey = encryptionKey
+ return &o2
+}
+
// Attrs returns meta information about the object.
// ErrObjectNotExist will be returned if the object is not found.
func (o *ObjectHandle) Attrs(ctx context.Context) (*ObjectAttrs, error) {
@@ -319,6 +331,9 @@ func (o *ObjectHandle) Attrs(ctx context.Context) (*ObjectAttrs, error) {
if err := applyConds("Attrs", o.gen, o.conds, call); err != nil {
return nil, err
}
+ if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil {
+ return nil, err
+ }
var obj *raw.Object
var err error
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
@@ -389,6 +404,9 @@ func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsToUpdate) (
if err := applyConds("Update", o.gen, o.conds, call); err != nil {
return nil, err
}
+ if err := setEncryptionHeaders(call.Header(), o.encryptionKey, false); err != nil {
+ return nil, err
+ }
var obj *raw.Object
var err error
err = runWithRetry(ctx, func() error { obj, err = call.Do(); return err })
@@ -486,6 +504,9 @@ func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64)
} else if length > 0 {
req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+length-1))
}
+ if err := setEncryptionHeaders(req.Header, o.encryptionKey, false); err != nil {
+ return nil, err
+ }
var res *http.Response
err = runWithRetry(ctx, func() error { res, err = o.c.hc.Do(req); return err })
if err != nil {
@@ -616,7 +637,7 @@ func toRawObjectACL(oldACL []ACLRule) []*raw.ObjectAccessControl {
}
// toRawObject copies the editable attributes from o to the raw library's Object type.
-func (o ObjectAttrs) toRawObject(bucket string) *raw.Object {
+func (o *ObjectAttrs) toRawObject(bucket string) *raw.Object {
acl := toRawObjectACL(o.ACL)
return &raw.Object{
Bucket: bucket,
@@ -716,6 +737,13 @@ type ObjectAttrs struct {
// metadata does not change this property. This field is read-only.
Updated time.Time
+ // CustomerKeySHA256 is the base64-encoded SHA-256 hash of the
+ // customer-supplied encryption key for the object. It is empty if there is
+ // no customer-supplied encryption key.
+ // See // https://cloud.google.com/storage/docs/encryption for more about
+ // encryption in Google Cloud Storage.
+ CustomerKeySHA256 string
+
// Prefix is set only for ObjectAttrs which represent synthetic "directory
// entries" when iterating over buckets using Query.Delimiter. See
// ObjectIterator.Next. When set, no other fields in ObjectAttrs will be
@@ -754,26 +782,31 @@ func newObject(o *raw.Object) *ObjectAttrs {
if err == nil && len(d) == 4 {
crc32c = uint32(d[0])<<24 + uint32(d[1])<<16 + uint32(d[2])<<8 + uint32(d[3])
}
+ var sha256 string
+ if o.CustomerEncryption != nil {
+ sha256 = o.CustomerEncryption.KeySha256
+ }
return &ObjectAttrs{
- Bucket: o.Bucket,
- Name: o.Name,
- ContentType: o.ContentType,
- ContentLanguage: o.ContentLanguage,
- CacheControl: o.CacheControl,
- ACL: acl,
- Owner: owner,
- ContentEncoding: o.ContentEncoding,
- Size: int64(o.Size),
- MD5: md5,
- CRC32C: crc32c,
- MediaLink: o.MediaLink,
- Metadata: o.Metadata,
- Generation: o.Generation,
- MetaGeneration: o.Metageneration,
- StorageClass: o.StorageClass,
- Created: convertTime(o.TimeCreated),
- Deleted: convertTime(o.TimeDeleted),
- Updated: convertTime(o.Updated),
+ Bucket: o.Bucket,
+ Name: o.Name,
+ ContentType: o.ContentType,
+ ContentLanguage: o.ContentLanguage,
+ CacheControl: o.CacheControl,
+ ACL: acl,
+ Owner: owner,
+ ContentEncoding: o.ContentEncoding,
+ Size: int64(o.Size),
+ MD5: md5,
+ CRC32C: crc32c,
+ MediaLink: o.MediaLink,
+ Metadata: o.Metadata,
+ Generation: o.Generation,
+ MetaGeneration: o.Metageneration,
+ StorageClass: o.StorageClass,
+ CustomerKeySHA256: sha256,
+ Created: convertTime(o.TimeCreated),
+ Deleted: convertTime(o.TimeDeleted),
+ Updated: convertTime(o.Updated),
}
}
@@ -1018,4 +1051,24 @@ func (c composeSourceObj) IfGenerationMatch(gen int64) {
}
}
+func setEncryptionHeaders(headers http.Header, key []byte, copySource bool) error {
+ if key == nil {
+ return nil
+ }
+ // TODO(jbd): Ask the API team to return a more user-friendly error
+ // and avoid doing this check at the client level.
+ if len(key) != 32 {
+ return errors.New("storage: not a 32-byte AES-256 key")
+ }
+ var cs string
+ if copySource {
+ cs = "copy-source-"
+ }
+ headers.Set("x-goog-"+cs+"encryption-algorithm", "AES256")
+ headers.Set("x-goog-"+cs+"encryption-key", base64.StdEncoding.EncodeToString(key))
+ keyHash := sha256.Sum256(key)
+ headers.Set("x-goog-"+cs+"encryption-key-sha256", base64.StdEncoding.EncodeToString(keyHash[:]))
+ return nil
+}
+
// TODO(jbd): Add storage.objects.watch.
diff --git a/vendor/cloud.google.com/go/storage/writer.go b/vendor/cloud.google.com/go/storage/writer.go
index 8f98156..64d7543 100644
--- a/vendor/cloud.google.com/go/storage/writer.go
+++ b/vendor/cloud.google.com/go/storage/writer.go
@@ -85,7 +85,11 @@ func (w *Writer) open() error {
Media(pr, mediaOpts...).
Projection("full").
Context(w.ctx)
-
+ if err := setEncryptionHeaders(call.Header(), w.o.encryptionKey, false); err != nil {
+ w.err = err
+ pr.CloseWithError(w.err)
+ return
+ }
var resp *raw.Object
err := applyConds("NewWriter", w.o.gen, w.o.conds, call)
if err == nil {