From baf7141d1dd0f99d561a2197a909c66dd389809d Mon Sep 17 00:00:00 2001 From: Niall Sheridan Date: Sat, 8 Oct 2016 16:02:50 -0500 Subject: Update dependencies --- .../go/compute/metadata/metadata.go | 2 +- vendor/cloud.google.com/go/storage/acl.go | 192 ++++ vendor/cloud.google.com/go/storage/bucket.go | 353 ++++++ vendor/cloud.google.com/go/storage/copy.go | 188 +++ vendor/cloud.google.com/go/storage/doc.go | 153 +++ vendor/cloud.google.com/go/storage/reader.go | 57 + vendor/cloud.google.com/go/storage/storage.go | 910 +++++++++++++++ vendor/cloud.google.com/go/storage/writer.go | 129 +++ .../aws/aws-sdk-go/aws/awsutil/path_value.go | 4 +- .../github.com/aws/aws-sdk-go/aws/client/client.go | 4 +- .../aws/aws-sdk-go/aws/corehandlers/handlers.go | 30 + .../aws/aws-sdk-go/aws/defaults/defaults.go | 1 + .../aws/aws-sdk-go/aws/ec2metadata/api.go | 22 + .../aws/aws-sdk-go/aws/request/http_request.go | 21 +- .../aws/aws-sdk-go/aws/request/http_request_1_4.go | 31 - .../aws/aws-sdk-go/aws/request/offset_reader.go | 19 +- .../aws/aws-sdk-go/aws/request/request.go | 50 +- .../aws/aws-sdk-go/aws/session/session.go | 7 +- .../github.com/aws/aws-sdk-go/aws/signer/v4/v4.go | 32 +- vendor/github.com/aws/aws-sdk-go/aws/version.go | 2 +- vendor/github.com/aws/aws-sdk-go/service/s3/api.go | 411 +++++-- .../aws/aws-sdk-go/service/s3/waiters.go | 16 + .../github.com/aws/aws-sdk-go/service/sts/api.go | 36 + vendor/github.com/davecgh/go-spew/spew/bypass.go | 7 +- .../github.com/davecgh/go-spew/spew/bypasssafe.go | 7 +- vendor/github.com/davecgh/go-spew/spew/config.go | 2 +- vendor/github.com/fsnotify/fsnotify/AUTHORS | 2 + vendor/github.com/fsnotify/fsnotify/CHANGELOG.md | 8 + .../github.com/fsnotify/fsnotify/CONTRIBUTING.md | 2 +- vendor/github.com/fsnotify/fsnotify/README.md | 2 +- vendor/github.com/fsnotify/fsnotify/fsnotify.go | 26 +- vendor/github.com/golang/protobuf/proto/encode.go | 14 +- .../google/go-github/github/activity_events.go | 4 + .../google/go-github/github/event_types.go | 34 + .../github.com/google/go-github/github/github.go | 7 +- .../github.com/google/go-github/github/messages.go | 71 ++ vendor/github.com/google/go-github/github/pulls.go | 1 + .../google/go-github/github/repos_forks.go | 2 +- .../google/go-github/github/repos_projects.go | 464 ++++++++ vendor/github.com/gorilla/csrf/README.md | 2 +- vendor/github.com/gorilla/csrf/csrf.go | 2 +- vendor/github.com/gorilla/mux/doc.go | 4 + .../gorilla/securecookie/securecookie.go | 8 +- vendor/github.com/gorilla/sessions/README.md | 2 +- vendor/github.com/gorilla/sessions/store.go | 25 + vendor/github.com/hashicorp/hcl/hcl/ast/ast.go | 3 +- .../github.com/hashicorp/hcl/hcl/parser/parser.go | 6 + .../github.com/hashicorp/hcl/json/parser/parser.go | 9 + vendor/github.com/mattn/go-sqlite3/doc.go | 2 + vendor/github.com/mattn/go-sqlite3/sqlite3.go | 129 +-- .../github.com/mattn/go-sqlite3/tracecallback.go | 415 +++++++ .../mattn/go-sqlite3/tracecallback_noimpl.go | 9 + .../mitchellh/mapstructure/mapstructure.go | 6 +- vendor/github.com/pelletier/go-toml/keysparsing.go | 16 +- vendor/github.com/pelletier/go-toml/toml.go | 3 - .../pelletier/go-toml/tomltree_conversions.go | 54 +- vendor/github.com/pkg/errors/errors.go | 37 +- vendor/github.com/pkg/sftp/client.go | 7 +- vendor/github.com/pkg/sftp/server_statvfs_linux.go | 5 +- vendor/github.com/spf13/afero/mem/file.go | 8 +- vendor/github.com/spf13/cast/cast.go | 5 + vendor/github.com/spf13/cast/caste.go | 70 +- vendor/github.com/spf13/pflag/bool.go | 7 +- vendor/github.com/spf13/pflag/count.go | 7 +- vendor/github.com/spf13/pflag/flag.go | 16 +- vendor/github.com/spf13/pflag/float32.go | 7 +- vendor/github.com/spf13/pflag/float64.go | 7 +- vendor/github.com/spf13/pflag/int.go | 7 +- vendor/github.com/spf13/pflag/int32.go | 7 +- vendor/github.com/spf13/pflag/int64.go | 7 +- vendor/github.com/spf13/pflag/int8.go | 7 +- vendor/github.com/spf13/pflag/string.go | 4 +- vendor/github.com/spf13/pflag/string_array.go | 110 ++ vendor/github.com/spf13/pflag/string_slice.go | 20 +- vendor/github.com/spf13/pflag/uint.go | 7 +- vendor/github.com/spf13/pflag/uint16.go | 9 +- vendor/github.com/spf13/pflag/uint32.go | 11 +- vendor/github.com/spf13/pflag/uint64.go | 7 +- vendor/github.com/spf13/pflag/uint8.go | 7 +- vendor/github.com/spf13/viper/README.md | 19 +- vendor/github.com/spf13/viper/util.go | 75 +- vendor/github.com/spf13/viper/viper.go | 643 +++++++---- .../stretchr/testify/assert/assertion_forward.go | 167 +-- .../stretchr/testify/assert/assertions.go | 101 +- .../stretchr/testify/assert/http_assertions.go | 2 +- vendor/go4.org/wkfs/gcs/gcs.go | 15 +- vendor/golang.org/x/crypto/ssh/agent/keyring.go | 53 +- vendor/golang.org/x/crypto/ssh/handshake.go | 11 +- vendor/golang.org/x/crypto/ssh/keys.go | 34 + vendor/golang.org/x/net/http2/frame.go | 2 +- vendor/golang.org/x/net/http2/go17.go | 12 + vendor/golang.org/x/net/http2/hpack/hpack.go | 2 +- vendor/golang.org/x/net/http2/http2.go | 11 +- vendor/golang.org/x/net/http2/not_go17.go | 12 +- vendor/golang.org/x/net/http2/server.go | 13 + vendor/golang.org/x/net/http2/transport.go | 124 +- vendor/golang.org/x/net/idna/idna.go | 68 ++ vendor/golang.org/x/net/idna/punycode.go | 200 ++++ vendor/golang.org/x/net/lex/httplex/httplex.go | 39 + vendor/golang.org/x/net/trace/trace.go | 26 +- .../golang.org/x/sys/unix/syscall_linux_arm64.go | 2 - .../golang.org/x/sys/unix/syscall_linux_mips64x.go | 7 - vendor/golang.org/x/sys/unix/syscall_solaris.go | 46 +- vendor/golang.org/x/sys/unix/types_solaris.go | 2 + .../x/sys/unix/zsyscall_solaris_amd64.go | 40 + .../golang.org/x/sys/unix/ztypes_solaris_amd64.go | 3 +- vendor/golang.org/x/text/internal/gen/code.go | 1 + vendor/golang.org/x/text/internal/gen/gen.go | 92 +- vendor/golang.org/x/text/internal/ucd/ucd.go | 19 +- vendor/golang.org/x/text/transform/transform.go | 52 +- vendor/golang.org/x/text/unicode/norm/normalize.go | 36 +- vendor/google.golang.org/api/gensupport/json.go | 28 +- vendor/google.golang.org/api/internal/settings.go | 15 +- vendor/google.golang.org/api/iterator/iterator.go | 231 ++++ .../google.golang.org/api/oauth2/v2/oauth2-gen.go | 40 +- vendor/google.golang.org/api/option/option.go | 15 + .../api/storage/v1/storage-api.json | 54 +- .../api/storage/v1/storage-gen.go | 344 ++++-- vendor/google.golang.org/api/transport/dial.go | 27 + vendor/google.golang.org/appengine/README.md | 4 +- vendor/google.golang.org/appengine/internal/api.go | 28 +- vendor/google.golang.org/cloud/AUTHORS | 15 - vendor/google.golang.org/cloud/CONTRIBUTING.md | 115 -- vendor/google.golang.org/cloud/CONTRIBUTORS | 31 - vendor/google.golang.org/cloud/LICENSE | 202 ---- vendor/google.golang.org/cloud/README.md | 202 ---- vendor/google.golang.org/cloud/cloud.go | 56 - .../cloud/compute/metadata/metadata.go | 438 ------- vendor/google.golang.org/cloud/internal/cloud.go | 128 --- .../cloud/internal/transport/dial.go | 61 - vendor/google.golang.org/cloud/key.json.enc | Bin 1248 -> 0 bytes vendor/google.golang.org/cloud/option.go | 88 -- vendor/google.golang.org/cloud/storage/acl.go | 198 ---- vendor/google.golang.org/cloud/storage/reader.go | 55 - vendor/google.golang.org/cloud/storage/storage.go | 1204 -------------------- vendor/google.golang.org/cloud/storage/writer.go | 129 --- vendor/google.golang.org/grpc/balancer.go | 20 +- vendor/google.golang.org/grpc/clientconn.go | 61 +- .../grpc/credentials/credentials.go | 42 +- vendor/google.golang.org/grpc/metadata/metadata.go | 13 +- vendor/google.golang.org/grpc/server.go | 13 +- vendor/google.golang.org/grpc/stream.go | 4 +- .../grpc/transport/http2_client.go | 27 +- .../google.golang.org/grpc/transport/http_util.go | 5 +- .../google.golang.org/grpc/transport/transport.go | 15 +- vendor/gopkg.in/yaml.v2/README.md | 2 +- vendor/gopkg.in/yaml.v2/decode.go | 2 +- vendor/vendor.json | 638 +++++------ 148 files changed, 6414 insertions(+), 4462 deletions(-) create mode 100644 vendor/cloud.google.com/go/storage/acl.go create mode 100644 vendor/cloud.google.com/go/storage/bucket.go create mode 100644 vendor/cloud.google.com/go/storage/copy.go create mode 100644 vendor/cloud.google.com/go/storage/doc.go create mode 100644 vendor/cloud.google.com/go/storage/reader.go create mode 100644 vendor/cloud.google.com/go/storage/storage.go create mode 100644 vendor/cloud.google.com/go/storage/writer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go create mode 100644 vendor/github.com/google/go-github/github/repos_projects.go create mode 100644 vendor/github.com/mattn/go-sqlite3/tracecallback.go create mode 100644 vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go create mode 100644 vendor/github.com/spf13/pflag/string_array.go create mode 100644 vendor/golang.org/x/net/idna/idna.go create mode 100644 vendor/golang.org/x/net/idna/punycode.go create mode 100644 vendor/google.golang.org/api/iterator/iterator.go delete mode 100644 vendor/google.golang.org/cloud/AUTHORS delete mode 100644 vendor/google.golang.org/cloud/CONTRIBUTING.md delete mode 100644 vendor/google.golang.org/cloud/CONTRIBUTORS delete mode 100644 vendor/google.golang.org/cloud/LICENSE delete mode 100644 vendor/google.golang.org/cloud/README.md delete mode 100644 vendor/google.golang.org/cloud/cloud.go delete mode 100644 vendor/google.golang.org/cloud/compute/metadata/metadata.go delete mode 100644 vendor/google.golang.org/cloud/internal/cloud.go delete mode 100644 vendor/google.golang.org/cloud/internal/transport/dial.go delete mode 100644 vendor/google.golang.org/cloud/key.json.enc delete mode 100644 vendor/google.golang.org/cloud/option.go delete mode 100644 vendor/google.golang.org/cloud/storage/acl.go delete mode 100644 vendor/google.golang.org/cloud/storage/reader.go delete mode 100644 vendor/google.golang.org/cloud/storage/storage.go delete mode 100644 vendor/google.golang.org/cloud/storage/writer.go diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go index b5d6091..f9d2bef 100644 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -200,7 +200,7 @@ func testOnGCE() bool { resc := make(chan bool, 2) // Try two strategies in parallel. - // See https://github.com/GoogleCloudPlatform/gcloud-golang/issues/194 + // See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/194 go func() { res, err := ctxhttp.Get(ctx, metaClient, "http://"+metadataIP) if err != nil { diff --git a/vendor/cloud.google.com/go/storage/acl.go b/vendor/cloud.google.com/go/storage/acl.go new file mode 100644 index 0000000..e0cb948 --- /dev/null +++ b/vendor/cloud.google.com/go/storage/acl.go @@ -0,0 +1,192 @@ +// Copyright 2014 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 storage + +import ( + "fmt" + + "golang.org/x/net/context" + raw "google.golang.org/api/storage/v1" +) + +// ACLRole is the level of access to grant. +type ACLRole string + +const ( + RoleOwner ACLRole = "OWNER" + RoleReader ACLRole = "READER" +) + +// ACLEntity refers to a user or group. +// They are sometimes referred to as grantees. +// +// It could be in the form of: +// "user-", "user-", "group-", "group-", +// "domain-" and "project-team-". +// +// Or one of the predefined constants: AllUsers, AllAuthenticatedUsers. +type ACLEntity string + +const ( + AllUsers ACLEntity = "allUsers" + AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers" +) + +// ACLRule represents a grant for a role to an entity (user, group or team) for a Google Cloud Storage object or bucket. +type ACLRule struct { + Entity ACLEntity + Role ACLRole +} + +// ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object. +type ACLHandle struct { + c *Client + bucket string + object string + isDefault bool +} + +// Delete permanently deletes the ACL entry for the given entity. +func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) error { + if a.object != "" { + return a.objectDelete(ctx, entity) + } + if a.isDefault { + return a.bucketDefaultDelete(ctx, entity) + } + return a.bucketDelete(ctx, entity) +} + +// Set sets the permission level for the given entity. +func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) error { + if a.object != "" { + return a.objectSet(ctx, entity, role) + } + if a.isDefault { + return a.bucketDefaultSet(ctx, entity, role) + } + return a.bucketSet(ctx, entity, role) +} + +// List retrieves ACL entries. +func (a *ACLHandle) List(ctx context.Context) ([]ACLRule, error) { + if a.object != "" { + return a.objectList(ctx) + } + if a.isDefault { + return a.bucketDefaultList(ctx) + } + return a.bucketList(ctx) +} + +func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) { + acls, err := a.c.raw.DefaultObjectAccessControls.List(a.bucket).Context(ctx).Do() + if err != nil { + return nil, fmt.Errorf("storage: error listing default object ACL for bucket %q: %v", a.bucket, err) + } + return toACLRules(acls.Items), nil +} + +func (a *ACLHandle) bucketDefaultSet(ctx context.Context, entity ACLEntity, role ACLRole) error { + acl := &raw.ObjectAccessControl{ + Bucket: a.bucket, + Entity: string(entity), + Role: string(role), + } + _, err := a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl).Context(ctx).Do() + if err != nil { + return fmt.Errorf("storage: error updating default ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) + } + return nil +} + +func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error { + err := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity)).Context(ctx).Do() + if err != nil { + return fmt.Errorf("storage: error deleting default ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) + } + return nil +} + +func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) { + acls, err := a.c.raw.BucketAccessControls.List(a.bucket).Context(ctx).Do() + if err != nil { + return nil, fmt.Errorf("storage: error listing bucket ACL for bucket %q: %v", a.bucket, err) + } + r := make([]ACLRule, len(acls.Items)) + for i, v := range acls.Items { + r[i].Entity = ACLEntity(v.Entity) + r[i].Role = ACLRole(v.Role) + } + return r, nil +} + +func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error { + acl := &raw.BucketAccessControl{ + Bucket: a.bucket, + Entity: string(entity), + Role: string(role), + } + _, err := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl).Context(ctx).Do() + if err != nil { + return fmt.Errorf("storage: error updating bucket ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) + } + return nil +} + +func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error { + err := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity)).Context(ctx).Do() + if err != nil { + return fmt.Errorf("storage: error deleting bucket ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) + } + return nil +} + +func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) { + acls, err := a.c.raw.ObjectAccessControls.List(a.bucket, a.object).Context(ctx).Do() + if err != nil { + return nil, fmt.Errorf("storage: error listing object ACL for bucket %q, file %q: %v", a.bucket, a.object, err) + } + return toACLRules(acls.Items), nil +} + +func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole) error { + acl := &raw.ObjectAccessControl{ + Bucket: a.bucket, + Entity: string(entity), + Role: string(role), + } + _, err := a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl).Context(ctx).Do() + if err != nil { + return fmt.Errorf("storage: error updating object ACL entry for bucket %q, file %q, entity %q: %v", a.bucket, a.object, entity, err) + } + return nil +} + +func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error { + err := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity)).Context(ctx).Do() + if err != nil { + return fmt.Errorf("storage: error deleting object ACL entry for bucket %q, file %q, entity %q: %v", a.bucket, a.object, entity, err) + } + return nil +} + +func toACLRules(items []*raw.ObjectAccessControl) []ACLRule { + r := make([]ACLRule, 0, len(items)) + for _, item := range items { + r = append(r, ACLRule{Entity: ACLEntity(item.Entity), Role: ACLRole(item.Role)}) + } + return r +} diff --git a/vendor/cloud.google.com/go/storage/bucket.go b/vendor/cloud.google.com/go/storage/bucket.go new file mode 100644 index 0000000..0875f7d --- /dev/null +++ b/vendor/cloud.google.com/go/storage/bucket.go @@ -0,0 +1,353 @@ +// Copyright 2014 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 storage + +import ( + "net/http" + "time" + + "golang.org/x/net/context" + "google.golang.org/api/googleapi" + "google.golang.org/api/iterator" + raw "google.golang.org/api/storage/v1" +) + +// 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 { + var bkt *raw.Bucket + if attrs != nil { + bkt = attrs.toRawBucket() + } else { + bkt = &raw.Bucket{} + } + bkt.Name = b.name + req := b.c.raw.Buckets.Insert(projectID, bkt) + _, err := req.Context(ctx).Do() + return err +} + +// Delete deletes the Bucket. +func (b *BucketHandle) Delete(ctx context.Context) error { + req := b.c.raw.Buckets.Delete(b.name) + return req.Context(ctx).Do() +} + +// ACL returns an ACLHandle, which provides access to the bucket's access control list. +// This controls who can list, create or overwrite the objects in a bucket. +// This call does not perform any network operations. +func (b *BucketHandle) ACL() *ACLHandle { + return &b.acl +} + +// DefaultObjectACL returns an ACLHandle, which provides access to the bucket's default object ACLs. +// These ACLs are applied to newly created objects in this bucket that do not have a defined ACL. +// This call does not perform any network operations. +func (b *BucketHandle) DefaultObjectACL() *ACLHandle { + return &b.defaultObjectACL +} + +// Object returns an ObjectHandle, which provides operations on the named object. +// This call does not perform any network operations. +// +// name must consist entirely of valid UTF-8-encoded runes. The full specification +// for valid object names can be found at: +// https://cloud.google.com/storage/docs/bucket-naming +func (b *BucketHandle) Object(name string) *ObjectHandle { + return &ObjectHandle{ + c: b.c, + bucket: b.name, + object: name, + acl: ACLHandle{ + c: b.c, + bucket: b.name, + object: name, + }, + } +} + +// Attrs returns the metadata for the bucket. +func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) { + resp, err := b.c.raw.Buckets.Get(b.name).Projection("full").Context(ctx).Do() + if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { + return nil, ErrBucketNotExist + } + if err != nil { + return nil, err + } + return newBucket(resp), nil +} + +// BucketAttrs represents the metadata for a Google Cloud Storage bucket. +type BucketAttrs struct { + // Name is the name of the bucket. + Name string + + // ACL is the list of access control rules on the bucket. + ACL []ACLRule + + // DefaultObjectACL is the list of access controls to + // apply to new objects when no object ACL is provided. + DefaultObjectACL []ACLRule + + // Location is the location of the bucket. It defaults to "US". + Location string + + // MetaGeneration is the metadata generation of the bucket. + MetaGeneration int64 + + // StorageClass is the storage class of the bucket. This defines + // how objects in the bucket are stored and determines the SLA + // and the cost of storage. Typical values are "STANDARD" and + // "DURABLE_REDUCED_AVAILABILITY". Defaults to "STANDARD". + StorageClass string + + // Created is the creation time of the bucket. + Created time.Time + + // VersioningEnabled reports whether this bucket has versioning enabled. + // This field is read-only. + VersioningEnabled bool +} + +func newBucket(b *raw.Bucket) *BucketAttrs { + if b == nil { + return nil + } + bucket := &BucketAttrs{ + Name: b.Name, + Location: b.Location, + MetaGeneration: b.Metageneration, + StorageClass: b.StorageClass, + Created: convertTime(b.TimeCreated), + VersioningEnabled: b.Versioning != nil && b.Versioning.Enabled, + } + acl := make([]ACLRule, len(b.Acl)) + for i, rule := range b.Acl { + acl[i] = ACLRule{ + Entity: ACLEntity(rule.Entity), + Role: ACLRole(rule.Role), + } + } + bucket.ACL = acl + objACL := make([]ACLRule, len(b.DefaultObjectAcl)) + for i, rule := range b.DefaultObjectAcl { + objACL[i] = ACLRule{ + Entity: ACLEntity(rule.Entity), + Role: ACLRole(rule.Role), + } + } + bucket.DefaultObjectACL = objACL + return bucket +} + +// toRawBucket copies the editable attribute from b to the raw library's Bucket type. +func (b *BucketAttrs) toRawBucket() *raw.Bucket { + var acl []*raw.BucketAccessControl + if len(b.ACL) > 0 { + acl = make([]*raw.BucketAccessControl, len(b.ACL)) + for i, rule := range b.ACL { + acl[i] = &raw.BucketAccessControl{ + Entity: string(rule.Entity), + Role: string(rule.Role), + } + } + } + dACL := toRawObjectACL(b.DefaultObjectACL) + return &raw.Bucket{ + Name: b.Name, + DefaultObjectAcl: dACL, + Location: b.Location, + StorageClass: b.StorageClass, + Acl: acl, + } +} + +// ObjectList represents a list of objects returned from a bucket List call. +type ObjectList struct { + // Results represent a list of object results. + Results []*ObjectAttrs + + // Next is the continuation query to retrieve more + // results with the same filtering criteria. If there + // are no more results to retrieve, it is nil. + Next *Query + + // Prefixes represents prefixes of objects + // matching-but-not-listed up to and including + // the requested delimiter. + Prefixes []string +} + +// List lists objects from the bucket. You can specify a query +// to filter the results. If q is nil, no filtering is applied. +// +// Deprecated. Use BucketHandle.Objects instead. +func (b *BucketHandle) List(ctx context.Context, q *Query) (*ObjectList, error) { + it := b.Objects(ctx, q) + nextToken, err := it.fetch(it.pageInfo.MaxSize, it.pageInfo.Token) + if err != nil { + return nil, err + } + list := &ObjectList{} + for _, item := range it.items { + if item.Prefix != "" { + list.Prefixes = append(list.Prefixes, item.Prefix) + } else { + list.Results = append(list.Results, item) + } + } + if nextToken != "" { + it.query.Cursor = nextToken + list.Next = &it.query + } + return list, nil +} + +// 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 { + it := &ObjectIterator{ + ctx: ctx, + bucket: b, + } + it.pageInfo, it.nextFunc = iterator.NewPageInfo( + it.fetch, + func() int { return len(it.items) }, + func() interface{} { b := it.items; it.items = nil; return b }) + if q != nil { + it.query = *q + it.pageInfo.MaxSize = q.MaxResults + it.pageInfo.Token = q.Cursor + } + return it +} + +// An ObjectIterator is an iterator over ObjectAttrs. +type ObjectIterator struct { + ctx context.Context + bucket *BucketHandle + query Query + pageInfo *iterator.PageInfo + nextFunc func() error + items []*ObjectAttrs +} + +// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. +func (it *ObjectIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } + +// Next returns the next result. Its second return value is Done if there are +// no more results. Once Next returns Done, all subsequent calls will return +// Done. +// +// If Query.Delimiter is non-empty, some of the ObjectAttrs returned by Next will +// have a non-empty Prefix field, and a zero value for all other fields. These +// represent prefixes. +func (it *ObjectIterator) Next() (*ObjectAttrs, error) { + if err := it.nextFunc(); err != nil { + return nil, err + } + item := it.items[0] + it.items = it.items[1:] + return item, nil +} + +func (it *ObjectIterator) fetch(pageSize int, pageToken string) (string, error) { + req := it.bucket.c.raw.Objects.List(it.bucket.name) + req.Projection("full") + req.Delimiter(it.query.Delimiter) + req.Prefix(it.query.Prefix) + req.Versions(it.query.Versions) + req.PageToken(pageToken) + if pageSize > 0 { + req.MaxResults(int64(pageSize)) + } + resp, err := req.Context(it.ctx).Do() + if err != nil { + return "", err + } + for _, item := range resp.Items { + it.items = append(it.items, newObject(item)) + } + for _, prefix := range resp.Prefixes { + it.items = append(it.items, &ObjectAttrs{Prefix: prefix}) + } + 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 +// are returned. +func (c *Client) Buckets(ctx context.Context, projectID string) *BucketIterator { + it := &BucketIterator{ + ctx: ctx, + client: c, + projectID: projectID, + } + it.pageInfo, it.nextFunc = iterator.NewPageInfo( + it.fetch, + func() int { return len(it.buckets) }, + func() interface{} { b := it.buckets; it.buckets = nil; return b }) + return it +} + +// A BucketIterator is an iterator over BucketAttrs. +type BucketIterator struct { + // Prefix restricts the iterator to buckets whose names begin with it. + Prefix string + + ctx context.Context + client *Client + projectID string + buckets []*BucketAttrs + pageInfo *iterator.PageInfo + nextFunc func() error +} + +// Next returns the next result. Its second return value is Done if there are +// no more results. Once Next returns Done, all subsequent calls will return +// Done. +func (it *BucketIterator) Next() (*BucketAttrs, error) { + if err := it.nextFunc(); err != nil { + return nil, err + } + b := it.buckets[0] + it.buckets = it.buckets[1:] + return b, nil +} + +// 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) { + req := it.client.raw.Buckets.List(it.projectID) + req.Projection("full") + req.Prefix(it.Prefix) + req.PageToken(pageToken) + if pageSize > 0 { + req.MaxResults(int64(pageSize)) + } + resp, err := req.Context(it.ctx).Do() + if err != nil { + return "", err + } + for _, item := range resp.Items { + it.buckets = append(it.buckets, newBucket(item)) + } + return resp.NextPageToken, nil +} diff --git a/vendor/cloud.google.com/go/storage/copy.go b/vendor/cloud.google.com/go/storage/copy.go new file mode 100644 index 0000000..c0e4041 --- /dev/null +++ b/vendor/cloud.google.com/go/storage/copy.go @@ -0,0 +1,188 @@ +// 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 storage contains a Google Cloud Storage client. +// +// This package is experimental and may make backwards-incompatible changes. +package storage + +import ( + "errors" + "fmt" + "reflect" + "unicode/utf8" + + "golang.org/x/net/context" + raw "google.golang.org/api/storage/v1" +) + +// CopierFrom creates a Copier that can copy src to dst. +// You can immediately call Run on the returned Copier, or +// you can configure it first. +func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier { + return &Copier{dst: dst, src: src} +} + +// A Copier copies a source object to a destination. +type Copier struct { + // ObjectAttrs are optional attributes to set on the destination object. + // Any attributes must be initialized before any calls on the Copier. Nil + // or zero-valued attributes are ignored. + ObjectAttrs + + // RewriteToken can be set before calling Run to resume a copy + // operation. After Run returns a non-nil error, RewriteToken will + // have been updated to contain the value needed to resume the copy. + RewriteToken string + + // ProgressFunc can be used to monitor the progress of a multi-RPC copy + // operation. If ProgressFunc is not nil and CopyFrom requires multiple + // calls to the underlying service (see + // https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then + // ProgressFunc will be invoked after each call with the number of bytes of + // content copied so far and the total size in bytes of the source object. + // + // ProgressFunc is intended to make upload progress available to the + // application. For example, the implementation of ProgressFunc may update + // a progress bar in the application's UI, or log the result of + // float64(copiedBytes)/float64(totalBytes). + // + // ProgressFunc should return quickly without blocking. + ProgressFunc func(copiedBytes, totalBytes uint64) + + dst, src *ObjectHandle +} + +// Run performs the copy. +func (c *Copier) Run(ctx context.Context) (*ObjectAttrs, error) { + // TODO(jba): add ObjectHandle.validate to do these checks. + if c.src.bucket == "" || c.dst.bucket == "" { + return nil, errors.New("storage: the source and destination bucket names must both be non-empty") + } + if c.src.object == "" || c.dst.object == "" { + return nil, errors.New("storage: the source and destination object names must both be non-empty") + } + if !utf8.ValidString(c.src.object) { + return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", c.src.object) + } + if !utf8.ValidString(c.dst.object) { + return nil, fmt.Errorf("storage: dst name %q is not valid UTF-8", c.dst.object) + } + var rawObject *raw.Object + // If any attribute was set, then we make sure the name matches the destination + // name, and we check that ContentType is non-empty so we can provide a better + // error message than the service. + if !reflect.DeepEqual(c.ObjectAttrs, ObjectAttrs{}) { + c.ObjectAttrs.Name = c.dst.object + if c.ObjectAttrs.ContentType == "" { + return nil, errors.New("storage: Copier.ContentType must be non-empty") + } + rawObject = c.ObjectAttrs.toRawObject(c.dst.bucket) + } + for { + res, err := c.callRewrite(ctx, c.src, rawObject) + if err != nil { + return nil, err + } + if c.ProgressFunc != nil { + c.ProgressFunc(res.TotalBytesRewritten, res.ObjectSize) + } + if res.Done { // Finished successfully. + return newObject(res.Resource), nil + } + } + return nil, nil +} + +func (c *Copier) callRewrite(ctx context.Context, src *ObjectHandle, rawObj *raw.Object) (*raw.RewriteResponse, error) { + call := c.dst.c.raw.Objects.Rewrite(src.bucket, src.object, c.dst.bucket, c.dst.object, rawObj) + + call.Context(ctx).Projection("full") + if c.RewriteToken != "" { + call.RewriteToken(c.RewriteToken) + } + if err := applyConds("Copy destination", c.dst.conds, call); err != nil { + return nil, err + } + if err := applyConds("Copy source", toSourceConds(c.src.conds), call); err != nil { + return nil, err + } + res, err := call.Do() + if err != nil { + return nil, err + } + c.RewriteToken = res.RewriteToken + return res, nil +} + +// 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. +func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer { + return &Composer{dst: dst, srcs: srcs} +} + +// A Composer composes source objects into a destination object. +type Composer struct { + // ObjectAttrs are optional attributes to set on the destination object. + // Any attributes must be initialized before any calls on the Composer. Nil + // or zero-valued attributes are ignored. + ObjectAttrs + + dst *ObjectHandle + srcs []*ObjectHandle +} + +// Run performs the compose operation. +func (c *Composer) Run(ctx context.Context) (*ObjectAttrs, error) { + if c.dst.bucket == "" || c.dst.object == "" { + return nil, errors.New("storage: the destination bucket and object names must be non-empty") + } + if len(c.srcs) == 0 { + return nil, errors.New("storage: at least one source object must be specified") + } + + req := &raw.ComposeRequest{} + if !reflect.DeepEqual(c.ObjectAttrs, ObjectAttrs{}) { + req.Destination = c.ObjectAttrs.toRawObject(c.dst.bucket) + req.Destination.Name = c.dst.object + } + + for _, src := range c.srcs { + 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.object == "" { + return nil, errors.New("storage: all source object names must be non-empty") + } + srcObj := &raw.ComposeRequestSourceObjects{ + Name: src.object, + } + if err := applyConds("ComposeFrom source", src.conds, composeSourceObj{srcObj}); err != nil { + return nil, err + } + req.SourceObjects = append(req.SourceObjects, srcObj) + } + + call := c.dst.c.raw.Objects.Compose(c.dst.bucket, c.dst.object, req).Context(ctx) + if err := applyConds("ComposeFrom destination", c.dst.conds, call); err != nil { + return nil, err + } + + obj, err := call.Do() + if err != nil { + return nil, err + } + return newObject(obj), nil +} diff --git a/vendor/cloud.google.com/go/storage/doc.go b/vendor/cloud.google.com/go/storage/doc.go new file mode 100644 index 0000000..39d54df --- /dev/null +++ b/vendor/cloud.google.com/go/storage/doc.go @@ -0,0 +1,153 @@ +// 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 storage provides an easy way to work with Google Cloud Storage. +Google Cloud Storage stores data in named objects, which are grouped into buckets. + +More information about Google Cloud Storage is available at +https://cloud.google.com/storage/docs. + +Note: This package is experimental and may make backwards-incompatible changes. + + +Creating a Client + +To start working with this package, create a client: + + ctx := context.Background() + client, err := storage.NewClient(ctx) + if err != nil { + // TODO: Handle error. + } + +Buckets + +A Google Cloud Storage bucket is a collection of objects. To work with a +bucket, make a bucket handle: + + bkt := client.Bucket(bucketName) + +A handle is a reference to a bucket. You can have a handle even if the +bucket doesn't exist yet. To create a bucket in Google Cloud Storage, +call Create on the handle: + + if err := bkt.Create(ctx, projectID, nil); err != nil { + // TODO: Handle error. + } + +Note that although buckets are associated with projects, bucket names are +global across all projects. + +Each bucket has associated metadata, represented in this package by +BucketAttrs. The third argument to BucketHandle.Create allows you to set +the intial BucketAttrs of a bucket. To retrieve a bucket's attributes, use +Attrs: + + attrs, err := bkt.Attrs(ctx) + if err != nil { + // TODO: Handle error. + } + fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n", + attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass) + +Objects + +An object holds arbitrary data as a sequence of bytes, like a file. You +refer to objects using a handle, just as with buckets. You can use the +standard Go io.Reader and io.Writer interfaces to read and write +object data: + + obj := bkt.Object("data") + // Write something to obj. + // w implements io.Writer. + w := obj.NewWriter(ctx) + // Write some text to obj. This will overwrite whatever is there. + if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil { + // TODO: Handle error. + } + // Close, just like writing a file. + if err := w.Close(); err != nil { + // TODO: Handle error. + } + + // Read it back. + r, err := obj.NewReader(ctx) + if err != nil { + // TODO: Handle error. + } + defer r.Close() + if _, err := io.Copy(os.Stdout, r); err != nil { + // TODO: Handle error. + } + // Prints "This object contains text." + +Objects also have attributes, which you can fetch with Attrs: + + objAttrs, err := obj.Attrs(ctx) + if err != nil { + // TODO: Handle error. + } + fmt.Printf("object %s has size %d and can be read using %s\n", + objAttrs.Name, objAttrs.Size, objAttrs.MediaLink) + +ACLs + +Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of +ACLRules, each of which specifies the role of a user, group or project. ACLs +are suitable for fine-grained control, but you may prefer using IAM to control +access at the project level (see +https://cloud.google.com/storage/docs/access-control/iam). + +To list the ACLs of a bucket or object, obtain an ACLHandle and call its List method: + + acls, err := obj.ACL().List(ctx) + if err != nil { + // TODO: Handle error. + } + for _, rule := range acls { + fmt.Printf("%s has role %s\n", rule.Entity, rule.Role) + } + +You can also set and delete ACLs. + +Conditions + +Every object has a generation and a metageneration. The generation changes +whenever the content changes, and the metageneration changes whenever the +metadata changes. Conditions let you check these values before an operation; +the operation only executes if the conditions match. You can use conditions to +prevent race conditions in read-modify-write operations. + +For example, say you've read an object's metadata into objAttrs. Now +you want to write to that object, but only if its contents haven't changed +since you read it. Here is how to express that: + + cond := storage.IfGenerationMatch(objAttrs.Generation) + w = obj.WithConditions(cond).NewWriter(ctx) + // Proceed with writing as above. + +Signed URLs + +You can obtain a URL that lets anyone read or write an object for a limited time. +You don't need to create a client to do this. See the documentation of +SignedURL for details. + + url, err := storage.SignedURL(bucketName, "shared-object", opts) + if err != nil { + // TODO: Handle error. + } + fmt.Println(url) +*/ +package storage // import "cloud.google.com/go/storage" diff --git a/vendor/cloud.google.com/go/storage/reader.go b/vendor/cloud.google.com/go/storage/reader.go new file mode 100644 index 0000000..329a5f3 --- /dev/null +++ b/vendor/cloud.google.com/go/storage/reader.go @@ -0,0 +1,57 @@ +// 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 storage + +import ( + "io" +) + +// Reader reads a Cloud Storage object. +// It implements io.Reader. +type Reader struct { + body io.ReadCloser + remain, size int64 + contentType string +} + +// Close closes the Reader. It must be called when done reading. +func (r *Reader) Close() error { + return r.body.Close() +} + +func (r *Reader) Read(p []byte) (int, error) { + n, err := r.body.Read(p) + if r.remain != -1 { + r.remain -= int64(n) + } + return n, err +} + +// Size returns the size of the object in bytes. +// The returned value is always the same and is not affected by +// calls to Read or Close. +func (r *Reader) Size() int64 { + return r.size +} + +// Remain returns the number of bytes left to read, or -1 if unknown. +func (r *Reader) Remain() int64 { + return r.remain +} + +// ContentType returns the content type of the object. +func (r *Reader) ContentType() string { + return r.contentType +} diff --git a/vendor/cloud.google.com/go/storage/storage.go b/vendor/cloud.google.com/go/storage/storage.go new file mode 100644 index 0000000..3707ea9 --- /dev/null +++ b/vendor/cloud.google.com/go/storage/storage.go @@ -0,0 +1,910 @@ +// Copyright 2014 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 storage + +import ( + "bytes" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "strconv" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/api/iterator" + "google.golang.org/api/option" + "google.golang.org/api/transport" + + "golang.org/x/net/context" + "google.golang.org/api/googleapi" + raw "google.golang.org/api/storage/v1" +) + +var ( + ErrBucketNotExist = errors.New("storage: bucket doesn't exist") + ErrObjectNotExist = errors.New("storage: object doesn't exist") + + // Done is returned by iterators in this package when they have no more items. + Done = iterator.Done +) + +const userAgent = "gcloud-golang-storage/20151204" + +const ( + // ScopeFullControl grants permissions to manage your + // data and permissions in Google Cloud Storage. + ScopeFullControl = raw.DevstorageFullControlScope + + // ScopeReadOnly grants permissions to + // view your data in Google Cloud Storage. + ScopeReadOnly = raw.DevstorageReadOnlyScope + + // ScopeReadWrite grants permissions to manage your + // data in Google Cloud Storage. + ScopeReadWrite = raw.DevstorageReadWriteScope +) + +// AdminClient is a client type for performing admin operations on a project's +// buckets. +// +// Deprecated: Client has all of AdminClient's methods. +type AdminClient struct { + c *Client + projectID string +} + +// NewAdminClient creates a new AdminClient for a given project. +// +// Deprecated: use NewClient instead. +func NewAdminClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*AdminClient, error) { + c, err := NewClient(ctx, opts...) + if err != nil { + return nil, err + } + return &AdminClient{ + c: c, + projectID: projectID, + }, nil +} + +// Close closes the AdminClient. +func (c *AdminClient) Close() error { + return c.c.Close() +} + +// Create creates a Bucket in the project. +// If attrs is nil the API defaults will be used. +// +// Deprecated: use BucketHandle.Create instead. +func (c *AdminClient) CreateBucket(ctx context.Context, bucketName string, attrs *BucketAttrs) error { + return c.c.Bucket(bucketName).Create(ctx, c.projectID, attrs) +} + +// Delete deletes a Bucket in the project. +// +// Deprecated: use BucketHandle.Delete instead. +func (c *AdminClient) DeleteBucket(ctx context.Context, bucketName string) error { + return c.c.Bucket(bucketName).Delete(ctx) +} + +// Client is a client for interacting with Google Cloud Storage. +// +// Clients should be reused instead of created as needed. +// The methods of Client are safe for concurrent use by multiple goroutines. +type Client struct { + hc *http.Client + raw *raw.Service +} + +// NewClient creates a new Google Cloud Storage client. +// The default scope is ScopeFullControl. To use a different scope, like ScopeReadOnly, use option.WithScopes. +func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { + o := []option.ClientOption{ + option.WithScopes(ScopeFullControl), + option.WithUserAgent(userAgent), + } + opts = append(o, opts...) + hc, _, err := transport.NewHTTPClient(ctx, opts...) + if err != nil { + return nil, fmt.Errorf("dialing: %v", err) + } + rawService, err := raw.New(hc) + if err != nil { + return nil, fmt.Errorf("storage client: %v", err) + } + return &Client{ + hc: hc, + raw: rawService, + }, nil +} + +// Close closes the Client. +// +// Close need not be called at program exit. +func (c *Client) Close() error { + c.hc = nil + return nil +} + +// BucketHandle provides operations on a Google Cloud Storage bucket. +// Use Client.Bucket to get a handle. +type BucketHandle struct { + acl ACLHandle + defaultObjectACL ACLHandle + + c *Client + name string +} + +// Bucket returns a BucketHandle, which provides operations on the named bucket. +// This call does not perform any network operations. +// +// The supplied name must contain only lowercase letters, numbers, dashes, +// underscores, and dots. The full specification for valid bucket names can be +// found at: +// https://cloud.google.com/storage/docs/bucket-naming +func (c *Client) Bucket(name string) *BucketHandle { + return &BucketHandle{ + c: c, + name: name, + acl: ACLHandle{ + c: c, + bucket: name, + }, + defaultObjectACL: ACLHandle{ + c: c, + bucket: name, + isDefault: true, + }, + } +} + +// SignedURLOptions allows you to restrict the access to the signed URL. +type SignedURLOptions struct { + // GoogleAccessID represents the authorizer of the signed URL generation. + // It is typically the Google service account client email address from + // the Google Developers Console in the form of "xxx@developer.gserviceaccount.com". + // Required. + GoogleAccessID string + + // PrivateKey is the Google service account private key. It is obtainable + // from the Google Developers Console. + // At https://console.developers.google.com/project//apiui/credential, + // create a service account client ID or reuse one of your existing service account + // credentials. Click on the "Generate new P12 key" to generate and download + // a new private key. Once you download the P12 file, use the following command + // to convert it into a PEM file. + // + // $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes + // + // Provide the contents of the PEM file as a byte slice. + // Exactly one of PrivateKey or SignBytes must be non-nil. + PrivateKey []byte + + // SignBytes is a function for implementing custom signing. + // If your application is running on Google App Engine, you can use appengine's internal signing function: + // ctx := appengine.NewContext(request) + // acc, _ := appengine.ServiceAccount(ctx) + // url, err := SignedURL("bucket", "object", &SignedURLOptions{ + // GoogleAccessID: acc, + // SignBytes: func(b []byte) ([]byte, error) { + // _, signedBytes, err := appengine.SignBytes(ctx, b) + // return signedBytes, err + // }, + // // etc. + // }) + // + // Exactly one of PrivateKey or SignBytes must be non-nil. + SignBytes func([]byte) ([]byte, error) + + // Method is the HTTP method to be used with the signed URL. + // Signed URLs can be used with GET, HEAD, PUT, and DELETE requests. + // Required. + Method string + + // Expires is the expiration time on the signed URL. It must be + // a datetime in the future. + // Required. + Expires time.Time + + // ContentType is the content type header the client must provide + // to use the generated signed URL. + // Optional. + ContentType string + + // Headers is a list of extention headers the client must provide + // in order to use the generated signed URL. + // Optional. + Headers []string + + // MD5 is the base64 encoded MD5 checksum of the file. + // If provided, the client should provide the exact value on the request + // header in order to use the signed URL. + // Optional. + MD5 []byte +} + +// SignedURL returns a URL for the specified object. Signed URLs allow +// the users access to a restricted resource for a limited time without having a +// Google account or signing in. For more information about the signed +// URLs, see https://cloud.google.com/storage/docs/accesscontrol#Signed-URLs. +func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) { + if opts == nil { + return "", errors.New("storage: missing required SignedURLOptions") + } + if opts.GoogleAccessID == "" { + return "", errors.New("storage: missing required GoogleAccessID") + } + if (opts.PrivateKey == nil) == (opts.SignBytes == nil) { + return "", errors.New("storage: exactly one of PrivateKey or SignedBytes must be set") + } + if opts.Method == "" { + return "", errors.New("storage: missing required method option") + } + if opts.Expires.IsZero() { + return "", errors.New("storage: missing required expires option") + } + + signBytes := opts.SignBytes + if opts.PrivateKey != nil { + key, err := parseKey(opts.PrivateKey) + if err != nil { + return "", err + } + signBytes = func(b []byte) ([]byte, error) { + sum := sha256.Sum256(b) + return rsa.SignPKCS1v15( + rand.Reader, + key, + crypto.SHA256, + sum[:], + ) + } + } else { + signBytes = opts.SignBytes + } + + u := &url.URL{ + Path: fmt.Sprintf("/%s/%s", bucket, name), + } + + buf := &bytes.Buffer{} + fmt.Fprintf(buf, "%s\n", opts.Method) + fmt.Fprintf(buf, "%s\n", opts.MD5) + fmt.Fprintf(buf, "%s\n", opts.ContentType) + fmt.Fprintf(buf, "%d\n", opts.Expires.Unix()) + fmt.Fprintf(buf, "%s", strings.Join(opts.Headers, "\n")) + fmt.Fprintf(buf, "%s", u.String()) + + b, err := signBytes(buf.Bytes()) + if err != nil { + return "", err + } + encoded := base64.StdEncoding.EncodeToString(b) + u.Scheme = "https" + u.Host = "storage.googleapis.com" + q := u.Query() + q.Set("GoogleAccessId", opts.GoogleAccessID) + q.Set("Expires", fmt.Sprintf("%d", opts.Expires.Unix())) + q.Set("Signature", string(encoded)) + u.RawQuery = q.Encode() + return u.String(), nil +} + +// 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 + conds []Condition +} + +// ACL provides access to the object's access control list. +// This controls who can read and write this object. +// This call does not perform any network operations. +func (o *ObjectHandle) ACL() *ACLHandle { + return &o.acl +} + +// WithConditions returns a copy of o using the provided conditions. +func (o *ObjectHandle) WithConditions(conds ...Condition) *ObjectHandle { + o2 := *o + o2.conds = conds + 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) { + if !utf8.ValidString(o.object) { + return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) + } + call := o.c.raw.Objects.Get(o.bucket, o.object).Projection("full").Context(ctx) + if err := applyConds("Attrs", o.conds, call); err != nil { + return nil, err + } + obj, err := call.Do() + if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { + return nil, ErrObjectNotExist + } + if err != nil { + return nil, err + } + return newObject(obj), nil +} + +// Update updates an object with the provided attributes. +// All zero-value attributes are ignored. +// ErrObjectNotExist will be returned if the object is not found. +func (o *ObjectHandle) Update(ctx context.Context, attrs ObjectAttrs) (*ObjectAttrs, error) { + if !utf8.ValidString(o.object) { + return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) + } + call := o.c.raw.Objects.Patch(o.bucket, o.object, attrs.toRawObject(o.bucket)).Projection("full").Context(ctx) + if err := applyConds("Update", o.conds, call); err != nil { + return nil, err + } + obj, err := call.Do() + if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { + return nil, ErrObjectNotExist + } + if err != nil { + return nil, err + } + return newObject(obj), nil +} + +// Delete deletes the single specified object. +func (o *ObjectHandle) Delete(ctx context.Context) error { + if !utf8.ValidString(o.object) { + return fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) + } + call := o.c.raw.Objects.Delete(o.bucket, o.object).Context(ctx) + if err := applyConds("Delete", o.conds, call); err != nil { + return err + } + err := call.Do() + switch e := err.(type) { + case nil: + return nil + case *googleapi.Error: + if e.Code == http.StatusNotFound { + return ErrObjectNotExist + } + } + return err +} + +// CopyTo copies the object to the given dst. +// The copied object's attributes are overwritten by attrs if non-nil. +// +// Deprecated: use ObjectHandle.CopierFrom instead. +func (o *ObjectHandle) CopyTo(ctx context.Context, dst *ObjectHandle, attrs *ObjectAttrs) (*ObjectAttrs, error) { + c := dst.CopierFrom(o) + if attrs != nil { + c.ObjectAttrs = *attrs + } + return c.Run(ctx) +} + +// ComposeFrom concatenates the provided slice of source objects into a new +// object whose destination is the receiver. The provided attrs, if not nil, +// are used to set the attributes on the newly-created object. All source +// objects must reside within the same bucket as the destination. +// +// Deprecated: use ObjectHandle.ComposerFrom instead. +func (o *ObjectHandle) ComposeFrom(ctx context.Context, srcs []*ObjectHandle, attrs *ObjectAttrs) (*ObjectAttrs, error) { + c := o.ComposerFrom(srcs...) + if attrs != nil { + c.ObjectAttrs = *attrs + } + return c.Run(ctx) +} + +// NewReader creates a new Reader to read the contents of the +// object. +// ErrObjectNotExist will be returned if the object is not found. +// +// The caller must call Close on the returned Reader when done reading. +func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) { + return o.NewRangeReader(ctx, 0, -1) +} + +// NewRangeReader reads part of an object, reading at most length bytes +// starting at the given offset. If length is negative, the object is read +// until the end. +func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64) (*Reader, error) { + if !utf8.ValidString(o.object) { + return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) + } + if offset < 0 { + return nil, fmt.Errorf("storage: invalid offset %d < 0", offset) + } + u := &url.URL{ + Scheme: "https", + Host: "storage.googleapis.com", + Path: fmt.Sprintf("/%s/%s", o.bucket, o.object), + } + verb := "GET" + if length == 0 { + verb = "HEAD" + } + req, err := http.NewRequest(verb, u.String(), nil) + if err != nil { + return nil, err + } + if err := applyConds("NewReader", o.conds, objectsGetCall{req}); err != nil { + return nil, err + } + if length < 0 && offset > 0 { + req.Header.Set("Range", fmt.Sprintf("bytes=%d-", offset)) + } else if length > 0 { + req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+length-1)) + } + res, err := o.c.hc.Do(req) + if err != nil { + return nil, err + } + if res.StatusCode == http.StatusNotFound { + res.Body.Close() + return nil, ErrObjectNotExist + } + if res.StatusCode < 200 || res.StatusCode > 299 { + body, _ := ioutil.ReadAll(res.Body) + res.Body.Close() + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + Body: string(body), + } + } + if offset > 0 && length != 0 && res.StatusCode != http.StatusPartialContent { + res.Body.Close() + return nil, errors.New("storage: partial request not satisfied") + } + + var size int64 // total size of object, even if a range was requested. + if res.StatusCode == http.StatusPartialContent { + cr := strings.TrimSpace(res.Header.Get("Content-Range")) + if !strings.HasPrefix(cr, "bytes ") || !strings.Contains(cr, "/") { + return nil, fmt.Errorf("storage: invalid Content-Range %q", cr) + } + size, err = strconv.ParseInt(cr[strings.LastIndex(cr, "/")+1:], 10, 64) + if err != nil { + return nil, fmt.Errorf("storage: invalid Content-Range %q", cr) + } + } else { + size = res.ContentLength + } + + remain := res.ContentLength + body := res.Body + if length == 0 { + remain = 0 + body.Close() + body = emptyBody + } + + return &Reader{ + body: body, + size: size, + remain: remain, + contentType: res.Header.Get("Content-Type"), + }, nil +} + +var emptyBody = ioutil.NopCloser(strings.NewReader("")) + +// NewWriter returns a storage Writer that writes to the GCS object +// associated with this ObjectHandle. +// +// A new object will be created unless an object with this name already exists. +// Otherwise any previous object with the same name will be replaced. +// The object will not be available (and any previous object will remain) +// until Close has been called. +// +// Attributes can be set on the object by modifying the returned Writer's +// ObjectAttrs field before the first call to Write. If no ContentType +// attribute is specified, the content type will be automatically sniffed +// using net/http.DetectContentType. +// +// It is the caller's responsibility to call Close when writing is done. +func (o *ObjectHandle) NewWriter(ctx context.Context) *Writer { + return &Writer{ + ctx: ctx, + o: o, + donec: make(chan struct{}), + ObjectAttrs: ObjectAttrs{Name: o.object}, + } +} + +// parseKey converts the binary contents of a private key file +// to an *rsa.PrivateKey. It detects whether the private key is in a +// PEM container or not. If so, it extracts the the private key +// from PEM container before conversion. It only supports PEM +// containers with no passphrase. +func parseKey(key []byte) (*rsa.PrivateKey, error) { + if block, _ := pem.Decode(key); block != nil { + key = block.Bytes + } + parsedKey, err := x509.ParsePKCS8PrivateKey(key) + if err != nil { + parsedKey, err = x509.ParsePKCS1PrivateKey(key) + if err != nil { + return nil, err + } + } + parsed, ok := parsedKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("oauth2: private key is invalid") + } + return parsed, nil +} + +func toRawObjectACL(oldACL []ACLRule) []*raw.ObjectAccessControl { + var acl []*raw.ObjectAccessControl + if len(oldACL) > 0 { + acl = make([]*raw.ObjectAccessControl, len(oldACL)) + for i, rule := range oldACL { + acl[i] = &raw.ObjectAccessControl{ + Entity: string(rule.Entity), + Role: string(rule.Role), + } + } + } + return acl +} + +// toRawObject copies the editable attributes from o to the raw library's Object type. +func (o ObjectAttrs) toRawObject(bucket string) *raw.Object { + acl := toRawObjectACL(o.ACL) + return &raw.Object{ + Bucket: bucket, + Name: o.Name, + ContentType: o.ContentType, + ContentEncoding: o.ContentEncoding, + ContentLanguage: o.ContentLanguage, + CacheControl: o.CacheControl, + ContentDisposition: o.ContentDisposition, + Acl: acl, + Metadata: o.Metadata, + } +} + +// ObjectAttrs represents the metadata for a Google Cloud Storage (GCS) object. +type ObjectAttrs struct { + // Bucket is the name of the bucket containing this GCS object. + // This field is read-only. + Bucket string + + // Name is the name of the object within the bucket. + // This field is read-only. + Name string + + // ContentType is the MIME type of the object's content. + ContentType string + + // ContentLanguage is the content language of the object's content. + ContentLanguage string + + // CacheControl is the Cache-Control header to be sent in the response + // headers when serving the object data. + CacheControl string + + // ACL is the list of access control rules for the object. + ACL []ACLRule + + // Owner is the owner of the object. This field is read-only. + // + // If non-zero, it is in the form of "user-". + Owner string + + // Size is the length of the object's content. This field is read-only. + Size int64 + + // ContentEncoding is the encoding of the object's content. + ContentEncoding string + + // ContentDisposition is the optional Content-Disposition header of the object + // sent in the response headers. + ContentDisposition string + + // MD5 is the MD5 hash of the object's content. This field is read-only. + MD5 []byte + + // CRC32C is the CRC32 checksum of the object's content using + // the Castagnoli93 polynomial. This field is read-only. + CRC32C uint32 + + // MediaLink is an URL to the object's content. This field is read-only. + MediaLink string + + // Metadata represents user-provided metadata, in key/value pairs. + // It can be nil if no metadata is provided. + Metadata map[string]string + + // Generation is the generation number of the object's content. + // This field is read-only. + Generation int64 + + // MetaGeneration is the version of the metadata for this + // object at this generation. This field is used for preconditions + // and for detecting changes in metadata. A metageneration number + // is only meaningful in the context of a particular generation + // of a particular object. This field is read-only. + MetaGeneration int64 + + // StorageClass is the storage class of the bucket. + // This value defines how objects in the bucket are stored and + // determines the SLA and the cost of storage. Typical values are + // "STANDARD" and "DURABLE_REDUCED_AVAILABILITY". + // It defaults to "STANDARD". This field is read-only. + StorageClass string + + // Created is the time the object was created. This field is read-only. + Created time.Time + + // Deleted is the time the object was deleted. + // If not deleted, it is the zero value. This field is read-only. + Deleted time.Time + + // Updated is the creation or modification time of the object. + // For buckets with versioning enabled, changing an object's + // metadata does not change this property. This field is read-only. + Updated time.Time + + // 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 + // populated. + Prefix string +} + +// convertTime converts a time in RFC3339 format to time.Time. +// If any error occurs in parsing, the zero-value time.Time is silently returned. +func convertTime(t string) time.Time { + var r time.Time + if t != "" { + r, _ = time.Parse(time.RFC3339, t) + } + return r +} + +func newObject(o *raw.Object) *ObjectAttrs { + if o == nil { + return nil + } + acl := make([]ACLRule, len(o.Acl)) + for i, rule := range o.Acl { + acl[i] = ACLRule{ + Entity: ACLEntity(rule.Entity), + Role: ACLRole(rule.Role), + } + } + owner := "" + if o.Owner != nil { + owner = o.Owner.Entity + } + md5, _ := base64.StdEncoding.DecodeString(o.Md5Hash) + var crc32c uint32 + d, err := base64.StdEncoding.DecodeString(o.Crc32c) + if err == nil && len(d) == 4 { + crc32c = uint32(d[0])<<24 + uint32(d[1])<<16 + uint32(d[2])<<8 + uint32(d[3]) + } + 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), + } +} + +// Query represents a query to filter objects from a bucket. +type Query struct { + // Delimiter returns results in a directory-like fashion. + // Results will contain only objects whose names, aside from the + // prefix, do not contain delimiter. Objects whose names, + // aside from the prefix, contain delimiter will have their name, + // truncated after the delimiter, returned in prefixes. + // Duplicate prefixes are omitted. + // Optional. + Delimiter string + + // Prefix is the prefix filter to query objects + // whose names begin with this prefix. + // Optional. + Prefix string + + // Versions indicates whether multiple versions of the same + // object will be included in the results. + Versions bool + + // Cursor is a previously-returned page token + // representing part of the larger set of results to view. + // Optional. + // + // Deprecated: Use ObjectIterator.PageInfo().Token instead. + Cursor string + + // MaxResults is the maximum number of items plus prefixes + // to return. As duplicate prefixes are omitted, + // fewer total results may be returned than requested. + // The default page limit is used if it is negative or zero. + // + // Deprecated: Use ObjectIterator.PageInfo().MaxSize instead. + MaxResults int +} + +// contentTyper implements ContentTyper to enable an +// io.ReadCloser to specify its MIME type. +type contentTyper struct { + io.Reader + t string +} + +func (c *contentTyper) ContentType() string { + return c.t +} + +// A Condition constrains methods to act on specific generations of +// resources. +// +// Not all conditions or combinations of conditions are applicable to +// all methods. +type Condition interface { + // method is the high-level ObjectHandle method name, for + // error messages. call is the call object to modify. + modifyCall(method string, call interface{}) error +} + +// applyConds modifies the provided call using the conditions in conds. +// call is something that quacks like a *raw.WhateverCall. +func applyConds(method string, conds []Condition, call interface{}) error { + for _, cond := range conds { + if err := cond.modifyCall(method, call); err != nil { + return err + } + } + return nil +} + +// toSourceConds returns a slice of Conditions derived from Conds that instead +// function on the equivalent Source methods of a call. +func toSourceConds(conds []Condition) []Condition { + out := make([]Condition, 0, len(conds)) + for _, c := range conds { + switch c := c.(type) { + case genCond: + var m string + if strings.HasPrefix(c.method, "If") { + m = "IfSource" + c.method[2:] + } else { + m = "Source" + c.method + } + out = append(out, genCond{method: m, val: c.val}) + default: + // NOTE(djd): If the message from unsupportedCond becomes + // confusing, we'll need to find a way for Conditions to + // identify themselves. + out = append(out, unsupportedCond{}) + } + } + return out +} + +func Generation(gen int64) Condition { return genCond{"Generation", gen} } +func IfGenerationMatch(gen int64) Condition { return genCond{"IfGenerationMatch", gen} } +func IfGenerationNotMatch(gen int64) Condition { return genCond{"IfGenerationNotMatch", gen} } +func IfMetaGenerationMatch(gen int64) Condition { return genCond{"IfMetagenerationMatch", gen} } +func IfMetaGenerationNotMatch(gen int64) Condition { return genCond{"IfMetagenerationNotMatch", gen} } + +type genCond struct { + method string + val int64 +} + +func (g genCond) modifyCall(srcMethod string, call interface{}) error { + rv := reflect.ValueOf(call) + meth := rv.MethodByName(g.method) + if !meth.IsValid() { + return fmt.Errorf("%s: condition %s not supported", srcMethod, g.method) + } + meth.Call([]reflect.Value{reflect.ValueOf(g.val)}) + return nil +} + +type unsupportedCond struct{} + +func (unsupportedCond) modifyCall(srcMethod string, call interface{}) error { + return fmt.Errorf("%s: condition not supported", srcMethod) +} + +func appendParam(req *http.Request, k, v string) { + sep := "" + if req.URL.RawQuery != "" { + sep = "&" + } + req.URL.RawQuery += sep + url.QueryEscape(k) + "=" + url.QueryEscape(v) +} + +// objectsGetCall wraps an *http.Request for an object fetch call, but adds the methods +// that modifyCall searches for by name. (the same names as the raw, auto-generated API) +type objectsGetCall struct{ req *http.Request } + +func (c objectsGetCall) Generation(gen int64) { + appendParam(c.req, "generation", fmt.Sprint(gen)) +} +func (c objectsGetCall) IfGenerationMatch(gen int64) { + appendParam(c.req, "ifGenerationMatch", fmt.Sprint(gen)) +} +func (c objectsGetCall) IfGenerationNotMatch(gen int64) { + appendParam(c.req, "ifGenerationNotMatch", fmt.Sprint(gen)) +} +func (c objectsGetCall) IfMetagenerationMatch(gen int64) { + appendParam(c.req, "ifMetagenerationMatch", fmt.Sprint(gen)) +} +func (c objectsGetCall) IfMetagenerationNotMatch(gen int64) { + appendParam(c.req, "ifMetagenerationNotMatch", fmt.Sprint(gen)) +} + +// composeSourceObj wraps a *raw.ComposeRequestSourceObjects, but adds the methods +// that modifyCall searches for by name. +type composeSourceObj struct { + src *raw.ComposeRequestSourceObjects +} + +func (c composeSourceObj) Generation(gen int64) { + c.src.Generation = gen +} + +func (c composeSourceObj) IfGenerationMatch(gen int64) { + // It's safe to overwrite ObjectPreconditions, since its only field is + // IfGenerationMatch. + c.src.ObjectPreconditions = &raw.ComposeRequestSourceObjectsObjectPreconditions{ + IfGenerationMatch: gen, + } +} + +// 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 new file mode 100644 index 0000000..79ab791 --- /dev/null +++ b/vendor/cloud.google.com/go/storage/writer.go @@ -0,0 +1,129 @@ +// Copyright 2014 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 storage + +import ( + "fmt" + "io" + "unicode/utf8" + + "golang.org/x/net/context" + "google.golang.org/api/googleapi" + raw "google.golang.org/api/storage/v1" +) + +// A Writer writes a Cloud Storage object. +type Writer struct { + // ObjectAttrs are optional attributes to set on the object. Any attributes + // must be initialized before the first Write call. Nil or zero-valued + // attributes are ignored. + ObjectAttrs + + ctx context.Context + o *ObjectHandle + + opened bool + pw *io.PipeWriter + + donec chan struct{} // closed after err and obj are set. + err error + obj *ObjectAttrs +} + +func (w *Writer) open() error { + attrs := w.ObjectAttrs + // Check the developer didn't change the object Name (this is unfortunate, but + // we don't want to store an object under the wrong name). + if attrs.Name != w.o.object { + return fmt.Errorf("storage: Writer.Name %q does not match object name %q", attrs.Name, w.o.object) + } + if !utf8.ValidString(attrs.Name) { + return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name) + } + pr, pw := io.Pipe() + w.pw = pw + w.opened = true + + var mediaOpts []googleapi.MediaOption + if c := attrs.ContentType; c != "" { + mediaOpts = append(mediaOpts, googleapi.ContentType(c)) + } + + go func() { + defer close(w.donec) + + call := w.o.c.raw.Objects.Insert(w.o.bucket, attrs.toRawObject(w.o.bucket)). + Media(pr, mediaOpts...). + Projection("full"). + Context(w.ctx) + + var resp *raw.Object + err := applyConds("NewWriter", w.o.conds, call) + if err == nil { + resp, err = call.Do() + } + if err != nil { + w.err = err + pr.CloseWithError(w.err) + return + } + w.obj = newObject(resp) + }() + return nil +} + +// Write appends to w. It implements the io.Writer interface. +func (w *Writer) Write(p []byte) (n int, err error) { + if w.err != nil { + return 0, w.err + } + if !w.opened { + if err := w.open(); err != nil { + return 0, err + } + } + return w.pw.Write(p) +} + +// Close completes the write operation and flushes any buffered data. +// If Close doesn't return an error, metadata about the written object +// can be retrieved by calling Object. +func (w *Writer) Close() error { + if !w.opened { + if err := w.open(); err != nil { + return err + } + } + if err := w.pw.Close(); err != nil { + return err + } + <-w.donec + return w.err +} + +// CloseWithError aborts the write operation with the provided error. +// CloseWithError always returns nil. +func (w *Writer) CloseWithError(err error) error { + if !w.opened { + return nil + } + return w.pw.CloseWithError(err) +} + +// Attrs returns metadata about a successfully-written object. +// It's only valid to call it after Close returns nil. +func (w *Writer) Attrs() *ObjectAttrs { + return w.obj +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go index 4d2a01e..11c52c3 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go @@ -106,8 +106,8 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer if indexStar || index != nil { nextvals = []reflect.Value{} - for _, value := range values { - value := reflect.Indirect(value) + for _, valItem := range values { + value := reflect.Indirect(valItem) if value.Kind() != reflect.Slice { continue } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go index 4003c04..7c0e7d9 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go @@ -2,7 +2,6 @@ package client import ( "fmt" - "io/ioutil" "net/http/httputil" "github.com/aws/aws-sdk-go/aws" @@ -104,8 +103,7 @@ func logRequest(r *request.Request) { // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's // Body as a NoOpCloser and will not be reset after read by the HTTP // client reader. - r.Body.Seek(r.BodyStart, 0) - r.HTTPRequest.Body = ioutil.NopCloser(r.Body) + r.ResetBody() } r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody))) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go index 8456e29..8e12f82 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go @@ -10,9 +10,11 @@ import ( "regexp" "runtime" "strconv" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/request" ) @@ -67,6 +69,34 @@ var SDKVersionUserAgentHandler = request.NamedHandler{ var reStatusCode = regexp.MustCompile(`^(\d{3})`) +// ValidateReqSigHandler is a request handler to ensure that the request's +// signature doesn't expire before it is sent. This can happen when a request +// is built and signed signficantly before it is sent. Or signficant delays +// occur whne retrying requests that would cause the signature to expire. +var ValidateReqSigHandler = request.NamedHandler{ + Name: "core.ValidateReqSigHandler", + Fn: func(r *request.Request) { + // Unsigned requests are not signed + if r.Config.Credentials == credentials.AnonymousCredentials { + return + } + + signedTime := r.Time + if !r.LastSignedAt.IsZero() { + signedTime = r.LastSignedAt + } + + // 10 minutes to allow for some clock skew/delays in transmission. + // Would be improved with aws/aws-sdk-go#423 + if signedTime.Add(10 * time.Minute).After(time.Now()) { + return + } + + fmt.Println("request expired, resigning") + r.Sign() + }, +} + // SendHandler is a request handler to send service request using HTTP client. var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) { var err error diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go index 10b7d86..8dbbf67 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -72,6 +72,7 @@ func Handlers() request.Handlers { handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) handlers.Build.AfterEachFn = request.HandlerListStopOnError handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) + handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler) handlers.Send.PushBackNamed(corehandlers.SendHandler) handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go index 669c813..e5755d1 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go @@ -3,6 +3,7 @@ package ec2metadata import ( "encoding/json" "fmt" + "net/http" "path" "strings" "time" @@ -27,6 +28,27 @@ func (c *EC2Metadata) GetMetadata(p string) (string, error) { return output.Content, req.Send() } +// GetUserData returns the userdata that was configured for the service. If +// there is no user-data setup for the EC2 instance a "NotFoundError" error +// code will be returned. +func (c *EC2Metadata) GetUserData() (string, error) { + op := &request.Operation{ + Name: "GetUserData", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "user-data"), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + req.Handlers.UnmarshalError.PushBack(func(r *request.Request) { + if r.HTTPResponse.StatusCode == http.StatusNotFound { + r.Error = awserr.New("NotFoundError", "user-data not found", r.Error) + } + }) + + return output.Content, req.Send() +} + // GetDynamicData uses the path provided to request information from the EC2 // instance metadata service for dynamic data. The content will be returned // as a string, or error if the request failed. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go index a4087f2..79f7960 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go @@ -1,5 +1,3 @@ -// +build go1.5 - package request import ( @@ -9,20 +7,13 @@ import ( ) func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { - req := &http.Request{ - URL: &url.URL{}, - Header: http.Header{}, - Close: r.Close, - Body: body, - Host: r.Host, - Method: r.Method, - Proto: r.Proto, - ContentLength: r.ContentLength, - // Cancel will be deprecated in 1.7 and will be replaced with Context - Cancel: r.Cancel, - } - + req := new(http.Request) + *req = *r + req.URL = &url.URL{} *req.URL = *r.URL + req.Body = body + + req.Header = http.Header{} for k, v := range r.Header { for _, vv := range v { req.Header.Add(k, vv) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go deleted file mode 100644 index 75da021..0000000 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build !go1.5 - -package request - -import ( - "io" - "net/http" - "net/url" -) - -func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { - req := &http.Request{ - URL: &url.URL{}, - Header: http.Header{}, - Close: r.Close, - Body: body, - Host: r.Host, - Method: r.Method, - Proto: r.Proto, - ContentLength: r.ContentLength, - } - - *req.URL = *r.URL - for k, v := range r.Header { - for _, vv := range v { - req.Header.Add(k, vv) - } - } - - return req -} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go index da6396d..02f07f4 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go @@ -9,7 +9,7 @@ import ( // with retrying requests type offsetReader struct { buf io.ReadSeeker - lock sync.RWMutex + lock sync.Mutex closed bool } @@ -21,7 +21,8 @@ func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader { return reader } -// Close is a thread-safe close. Uses the write lock. +// Close will close the instance of the offset reader's access to +// the underlying io.ReadSeeker. func (o *offsetReader) Close() error { o.lock.Lock() defer o.lock.Unlock() @@ -29,10 +30,10 @@ func (o *offsetReader) Close() error { return nil } -// Read is a thread-safe read using a read lock. +// Read is a thread-safe read of the underlying io.ReadSeeker func (o *offsetReader) Read(p []byte) (int, error) { - o.lock.RLock() - defer o.lock.RUnlock() + o.lock.Lock() + defer o.lock.Unlock() if o.closed { return 0, io.EOF @@ -41,6 +42,14 @@ func (o *offsetReader) Read(p []byte) (int, error) { return o.buf.Read(p) } +// Seek is a thread-safe seeking operation. +func (o *offsetReader) Seek(offset int64, whence int) (int64, error) { + o.lock.Lock() + defer o.lock.Unlock() + + return o.buf.Seek(offset, whence) +} + // CloseAndCopy will return a new offsetReader with a copy of the old buffer // and close the old buffer. func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader { diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go index 2832aaa..8ef9715 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net/http" "net/url" "reflect" @@ -42,6 +41,12 @@ type Request struct { LastSignedAt time.Time built bool + + // Need to persist an intermideant body betweend the input Body and HTTP + // request body because the HTTP Client's transport can maintain a reference + // to the HTTP request's body after the client has returned. This value is + // safe to use concurrently and rewraps the input Body for each HTTP request. + safeBody *offsetReader } // An Operation is the service API operation to be made. @@ -135,8 +140,8 @@ func (r *Request) SetStringBody(s string) { // SetReaderBody will set the request's body reader. func (r *Request) SetReaderBody(reader io.ReadSeeker) { - r.HTTPRequest.Body = newOffsetReader(reader, 0) r.Body = reader + r.ResetBody() } // Presign returns the request's signed URL. Error will be returned @@ -220,6 +225,24 @@ func (r *Request) Sign() error { return r.Error } +// ResetBody rewinds the request body backto its starting position, and +// set's the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +func (r *Request) ResetBody() { + if r.safeBody != nil { + r.safeBody.Close() + } + + r.safeBody = newOffsetReader(r.Body, r.BodyStart) + r.HTTPRequest.Body = r.safeBody +} + +// GetBody will return an io.ReadSeeker of the Request's underlying +// input body with a concurrency safe wrapper. +func (r *Request) GetBody() io.ReadSeeker { + return r.safeBody +} + // Send will send the request returning error if errors are encountered. // // Send will sign the request prior to sending. All Send Handlers will @@ -231,6 +254,8 @@ func (r *Request) Sign() error { // // readLoop() and getConn(req *Request, cm connectMethod) // https://github.com/golang/go/blob/master/src/net/http/transport.go +// +// Send will not close the request.Request's body. func (r *Request) Send() error { for { if aws.BoolValue(r.Retryable) { @@ -239,21 +264,15 @@ func (r *Request) Send() error { r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount)) } - var body io.ReadCloser - if reader, ok := r.HTTPRequest.Body.(*offsetReader); ok { - body = reader.CloseAndCopy(r.BodyStart) - } else { - if r.Config.Logger != nil { - r.Config.Logger.Log("Request body type has been overwritten. May cause race conditions") - } - r.Body.Seek(r.BodyStart, 0) - body = ioutil.NopCloser(r.Body) - } + // The previous http.Request will have a reference to the r.Body + // and the HTTP Client's Transport may still be reading from + // the request's body even though the Client's Do returned. + r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil) + r.ResetBody() - r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, body) + // Closing response body to ensure that no response body is leaked + // between retry attempts. if r.HTTPResponse != nil && r.HTTPResponse.Body != nil { - // Closing response body. Since we are setting a new request to send off, this - // response will get squashed and leaked. r.HTTPResponse.Body.Close() } } @@ -281,7 +300,6 @@ func (r *Request) Send() error { debugLogReqError(r, "Send Request", true, err) continue } - r.Handlers.UnmarshalMeta.Run(r) r.Handlers.ValidateResponse.Run(r) if r.Error != nil { diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go index 2374b1f..602f4e1 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go @@ -179,7 +179,12 @@ type Options struct { // SharedConfigState: SharedConfigEnable, // }) func NewSessionWithOptions(opts Options) (*Session, error) { - envCfg := loadEnvConfig() + var envCfg envConfig + if opts.SharedConfigState == SharedConfigEnable { + envCfg = loadSharedEnvConfig() + } else { + envCfg = loadEnvConfig() + } if len(opts.Profile) > 0 { envCfg.Profile = opts.Profile diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go index 7d99f54..eb79ded 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -11,6 +11,7 @@ import ( "encoding/hex" "fmt" "io" + "io/ioutil" "net/http" "net/url" "sort" @@ -175,6 +176,12 @@ type signingCtx struct { // is not needed as the full request context will be captured by the http.Request // value. It is included for reference though. // +// Sign will set the request's Body to be the `body` parameter passed in. If +// the body is not already an io.ReadCloser, it will be wrapped within one. If +// a `nil` body parameter passed to Sign, the request's Body field will be +// also set to nil. Its important to note that this functionality will not +// change the request's ContentLength of the request. +// // Sign differs from Presign in that it will sign the request using HTTP // header values. This type of signing is intended for http.Request values that // will not be shared, or are shared in a way the header values on the request @@ -240,11 +247,6 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi } if ctx.isRequestSigned() { - if !v4.Credentials.IsExpired() && currentTimeFn().Before(ctx.Time.Add(10*time.Minute)) { - // If the request is already signed, and the credentials have not - // expired, and the request is not too old ignore the signing request. - return ctx.SignedHeaderVals, nil - } ctx.Time = currentTimeFn() ctx.handlePresignRemoval() } @@ -258,6 +260,20 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi ctx.assignAmzQueryValues() ctx.build(v4.DisableHeaderHoisting) + // If the request is not presigned the body should be attached to it. This + // prevents the confusion of wanting to send a signed request without + // the body the request was signed for attached. + if !ctx.isPresign { + var reader io.ReadCloser + if body != nil { + var ok bool + if reader, ok = body.(io.ReadCloser); !ok { + reader = ioutil.NopCloser(body) + } + } + r.Body = reader + } + if v4.Debug.Matches(aws.LogDebugWithSigning) { v4.logSigningInfo(ctx) } @@ -345,7 +361,9 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time signingTime = req.LastSignedAt } - signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.Body, name, region, req.ExpireTime, signingTime) + signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), + name, region, req.ExpireTime, signingTime, + ) if err != nil { req.Error = err req.SignedHeaderVals = nil @@ -356,7 +374,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time req.LastSignedAt = curTimeFn() } -const logSignInfoMsg = `DEBUG: Request Signiture: +const logSignInfoMsg = `DEBUG: Request Signature: ---[ CANONICAL STRING ]----------------------------- %s ---[ STRING TO SIGN ]-------------------------------- diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index c87a0c2..472f38c 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.4.6" +const SDKVersion = "1.4.14" diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go index 553b0e4..c71b6eb 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go @@ -3120,8 +3120,10 @@ func (s AbortIncompleteMultipartUpload) GoString() string { type AbortMultipartUploadInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -3130,6 +3132,7 @@ type AbortMultipartUploadInput struct { // at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` + // UploadId is a required field UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"` } @@ -3262,6 +3265,7 @@ func (s Bucket) GoString() string { type BucketLifecycleConfiguration struct { _ struct{} `type:"structure"` + // Rules is a required field Rules []*LifecycleRule `locationName:"Rule" type:"list" flattened:"true" required:"true"` } @@ -3332,6 +3336,7 @@ func (s *BucketLoggingStatus) Validate() error { type CORSConfiguration struct { _ struct{} `type:"structure"` + // CORSRules is a required field CORSRules []*CORSRule `locationName:"CORSRule" type:"list" flattened:"true" required:"true"` } @@ -3376,9 +3381,13 @@ type CORSRule struct { // Identifies HTTP methods that the domain/origin specified in the rule is allowed // to execute. + // + // AllowedMethods is a required field AllowedMethods []*string `locationName:"AllowedMethod" type:"list" flattened:"true" required:"true"` // One or more origins you want customers to be able to access the bucket from. + // + // AllowedOrigins is a required field AllowedOrigins []*string `locationName:"AllowedOrigin" type:"list" flattened:"true" required:"true"` // One or more headers in the response that you want customers to be able to @@ -3463,8 +3472,10 @@ func (s CommonPrefix) GoString() string { type CompleteMultipartUploadInput struct { _ struct{} `type:"structure" payload:"MultipartUpload"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` MultipartUpload *CompletedMultipartUpload `locationName:"CompleteMultipartUpload" type:"structure"` @@ -3475,6 +3486,7 @@ type CompleteMultipartUploadInput struct { // at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` + // UploadId is a required field UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"` } @@ -3625,6 +3637,7 @@ type CopyObjectInput struct { // The canned ACL to apply to the object. ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Specifies caching behavior along the request/reply chain. @@ -3646,6 +3659,8 @@ type CopyObjectInput struct { // The name of the source bucket and key name of the source object, separated // by a slash (/). Must be URL-encoded. + // + // CopySource is a required field CopySource *string `location:"header" locationName:"x-amz-copy-source" type:"string" required:"true"` // Copies the object if its entity tag (ETag) matches the specified tag. @@ -3689,6 +3704,7 @@ type CopyObjectInput struct { // Allows grantee to write the ACL for the applicable object. GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // A map of metadata to store with the object in S3. @@ -3878,6 +3894,7 @@ type CreateBucketInput struct { // The canned ACL to apply to the bucket. ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` CreateBucketConfiguration *CreateBucketConfiguration `locationName:"CreateBucketConfiguration" type:"structure"` @@ -3944,6 +3961,7 @@ type CreateMultipartUploadInput struct { // The canned ACL to apply to the object. ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Specifies caching behavior along the request/reply chain. @@ -3978,6 +3996,7 @@ type CreateMultipartUploadInput struct { // Allows grantee to write the ACL for the applicable object. GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // A map of metadata to store with the object in S3. @@ -4107,6 +4126,7 @@ func (s CreateMultipartUploadOutput) GoString() string { type Delete struct { _ struct{} `type:"structure"` + // Objects is a required field Objects []*ObjectIdentifier `locationName:"Object" type:"list" flattened:"true" required:"true"` // Element to enable quiet mode for the request. When you add this element, @@ -4150,6 +4170,7 @@ func (s *Delete) Validate() error { type DeleteBucketCorsInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4193,6 +4214,7 @@ func (s DeleteBucketCorsOutput) GoString() string { type DeleteBucketInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4222,6 +4244,7 @@ func (s *DeleteBucketInput) Validate() error { type DeleteBucketLifecycleInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4279,6 +4302,7 @@ func (s DeleteBucketOutput) GoString() string { type DeleteBucketPolicyInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4322,6 +4346,7 @@ func (s DeleteBucketPolicyOutput) GoString() string { type DeleteBucketReplicationInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4365,6 +4390,7 @@ func (s DeleteBucketReplicationOutput) GoString() string { type DeleteBucketTaggingInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4408,6 +4434,7 @@ func (s DeleteBucketTaggingOutput) GoString() string { type DeleteBucketWebsiteInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4480,8 +4507,10 @@ func (s DeleteMarkerEntry) GoString() string { type DeleteObjectInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // The concatenation of the authentication device's serial number, a space, @@ -4556,8 +4585,10 @@ func (s DeleteObjectOutput) GoString() string { type DeleteObjectsInput struct { _ struct{} `type:"structure" payload:"Delete"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Delete is a required field Delete *Delete `locationName:"Delete" type:"structure" required:"true"` // The concatenation of the authentication device's serial number, a space, @@ -4651,6 +4682,8 @@ type Destination struct { // Amazon resource name (ARN) of the bucket where you want Amazon S3 to store // replicas of the object identified by the rule. + // + // Bucket is a required field Bucket *string `type:"string" required:"true"` // The class of storage used to store the object. @@ -4706,6 +4739,8 @@ type ErrorDocument struct { _ struct{} `type:"structure"` // The object key name to use when a 4XX class error occurs. + // + // Key is a required field Key *string `min:"1" type:"string" required:"true"` } @@ -4763,6 +4798,8 @@ type GetBucketAccelerateConfigurationInput struct { _ struct{} `type:"structure"` // Name of the bucket for which the accelerate configuration is retrieved. + // + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4809,6 +4846,7 @@ func (s GetBucketAccelerateConfigurationOutput) GoString() string { type GetBucketAclInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4857,6 +4895,7 @@ func (s GetBucketAclOutput) GoString() string { type GetBucketCorsInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4902,6 +4941,7 @@ func (s GetBucketCorsOutput) GoString() string { type GetBucketLifecycleConfigurationInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4947,6 +4987,7 @@ func (s GetBucketLifecycleConfigurationOutput) GoString() string { type GetBucketLifecycleInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -4992,6 +5033,7 @@ func (s GetBucketLifecycleOutput) GoString() string { type GetBucketLocationInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5037,6 +5079,7 @@ func (s GetBucketLocationOutput) GoString() string { type GetBucketLoggingInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5083,6 +5126,8 @@ type GetBucketNotificationConfigurationRequest struct { _ struct{} `type:"structure"` // Name of the bucket to get the notification configuration for. + // + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5112,6 +5157,7 @@ func (s *GetBucketNotificationConfigurationRequest) Validate() error { type GetBucketPolicyInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5158,6 +5204,7 @@ func (s GetBucketPolicyOutput) GoString() string { type GetBucketReplicationInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5205,6 +5252,7 @@ func (s GetBucketReplicationOutput) GoString() string { type GetBucketRequestPaymentInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5251,6 +5299,7 @@ func (s GetBucketRequestPaymentOutput) GoString() string { type GetBucketTaggingInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5280,6 +5329,7 @@ func (s *GetBucketTaggingInput) Validate() error { type GetBucketTaggingOutput struct { _ struct{} `type:"structure"` + // TagSet is a required field TagSet []*Tag `locationNameList:"Tag" type:"list" required:"true"` } @@ -5296,6 +5346,7 @@ func (s GetBucketTaggingOutput) GoString() string { type GetBucketVersioningInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5347,6 +5398,7 @@ func (s GetBucketVersioningOutput) GoString() string { type GetBucketWebsiteInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5398,8 +5450,10 @@ func (s GetBucketWebsiteOutput) GoString() string { type GetObjectAclInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -5467,6 +5521,7 @@ func (s GetObjectAclOutput) GoString() string { type GetObjectInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Return the object only if its entity tag (ETag) is the same as the one specified, @@ -5485,8 +5540,14 @@ type GetObjectInput struct { // otherwise return a 412 (precondition failed). IfUnmodifiedSince *time.Time `location:"header" locationName:"If-Unmodified-Since" type:"timestamp" timestampFormat:"rfc822"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` + // Part number of the object being read. This is a positive integer between + // 1 and 10,000. Effectively performs a 'ranged' GET request for the part specified. + // Useful for downloading just a part of an object. + PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer"` + // Downloads the specified range bytes of an object. For more information about // the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35. Range *string `location:"header" locationName:"Range" type:"string"` @@ -5623,6 +5684,9 @@ type GetObjectOutput struct { // you can create metadata whose values are not legal HTTP headers. MissingMeta *int64 `location:"header" locationName:"x-amz-missing-meta" type:"integer"` + // The count of parts this object has. + PartsCount *int64 `location:"header" locationName:"x-amz-mp-parts-count" type:"integer"` + ReplicationStatus *string `location:"header" locationName:"x-amz-replication-status" type:"string" enum:"ReplicationStatus"` // If present, indicates that the requester was successfully charged for the @@ -5675,8 +5739,10 @@ func (s GetObjectOutput) GoString() string { type GetObjectTorrentInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -5782,6 +5848,8 @@ type Grantee struct { ID *string `type:"string"` // Type of grantee + // + // Type is a required field Type *string `locationName:"xsi:type" type:"string" xmlAttribute:"true" required:"true" enum:"Type"` // URI of the grantee group. @@ -5814,6 +5882,7 @@ func (s *Grantee) Validate() error { type HeadBucketInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -5857,6 +5926,7 @@ func (s HeadBucketOutput) GoString() string { type HeadObjectInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Return the object only if its entity tag (ETag) is the same as the one specified, @@ -5875,8 +5945,15 @@ type HeadObjectInput struct { // otherwise return a 412 (precondition failed). IfUnmodifiedSince *time.Time `location:"header" locationName:"If-Unmodified-Since" type:"timestamp" timestampFormat:"rfc822"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` + // Part number of the object being read. This is a positive integer between + // 1 and 10,000. Effectively performs a 'ranged' HEAD request for the part specified. + // Useful querying about the size of the part and the number of parts in this + // object. + PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer"` + // Downloads the specified range bytes of an object. For more information about // the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35. Range *string `location:"header" locationName:"Range" type:"string"` @@ -5989,6 +6066,9 @@ type HeadObjectOutput struct { // you can create metadata whose values are not legal HTTP headers. MissingMeta *int64 `location:"header" locationName:"x-amz-missing-meta" type:"integer"` + // The count of parts this object has. + PartsCount *int64 `location:"header" locationName:"x-amz-mp-parts-count" type:"integer"` + ReplicationStatus *string `location:"header" locationName:"x-amz-replication-status" type:"string" enum:"ReplicationStatus"` // If present, indicates that the requester was successfully charged for the @@ -6045,6 +6125,8 @@ type IndexDocument struct { // endpoint (e.g. if the suffix is index.html and you make a request to samplebucket/images/ // the data that is returned will be for the object with the key name images/index.html) // The suffix must not be empty and must not include a slash character. + // + // Suffix is a required field Suffix *string `type:"string" required:"true"` } @@ -6115,6 +6197,7 @@ func (s KeyFilter) GoString() string { type LambdaFunctionConfiguration struct { _ struct{} `type:"structure"` + // Events is a required field Events []*string `locationName:"Event" type:"list" flattened:"true" required:"true"` // Container for object key name filtering rules. For information about key @@ -6128,6 +6211,8 @@ type LambdaFunctionConfiguration struct { // Lambda cloud function ARN that Amazon S3 can invoke when it detects events // of the specified type. + // + // LambdaFunctionArn is a required field LambdaFunctionArn *string `locationName:"CloudFunction" type:"string" required:"true"` } @@ -6160,6 +6245,7 @@ func (s *LambdaFunctionConfiguration) Validate() error { type LifecycleConfiguration struct { _ struct{} `type:"structure"` + // Rules is a required field Rules []*Rule `locationName:"Rule" type:"list" flattened:"true" required:"true"` } @@ -6246,10 +6332,14 @@ type LifecycleRule struct { NoncurrentVersionTransitions []*NoncurrentVersionTransition `locationName:"NoncurrentVersionTransition" type:"list" flattened:"true"` // Prefix identifying one or more objects to which the rule applies. + // + // Prefix is a required field Prefix *string `type:"string" required:"true"` // If 'Enabled', the rule is currently being applied. If 'Disabled', the rule // is not currently being applied. + // + // Status is a required field Status *string `type:"string" required:"true" enum:"ExpirationStatus"` Transitions []*Transition `locationName:"Transition" type:"list" flattened:"true"` @@ -6316,6 +6406,7 @@ func (s ListBucketsOutput) GoString() string { type ListMultipartUploadsInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Character you use to group keys. @@ -6428,6 +6519,7 @@ func (s ListMultipartUploadsOutput) GoString() string { type ListObjectVersionsInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // A delimiter is a character you use to group keys. @@ -6530,6 +6622,7 @@ func (s ListObjectVersionsOutput) GoString() string { type ListObjectsInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // A delimiter is a character you use to group keys. @@ -6552,6 +6645,11 @@ type ListObjectsInput struct { // Limits the response to keys that begin with the specified prefix. Prefix *string `location:"querystring" locationName:"prefix" type:"string"` + + // Confirms that the requester knows that she or he will be charged for the + // list objects request. Bucket owners need not specify this parameter in their + // requests. + RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` } // String returns the string representation @@ -6625,6 +6723,8 @@ type ListObjectsV2Input struct { _ struct{} `type:"structure"` // Name of the bucket to list. + // + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // ContinuationToken indicates Amazon S3 that the list is being continued on @@ -6650,6 +6750,11 @@ type ListObjectsV2Input struct { // Limits the response to keys that begin with the specified prefix. Prefix *string `location:"querystring" locationName:"prefix" type:"string"` + // Confirms that the requester knows that she or he will be charged for the + // list objects request in V2 style. Bucket owners need not specify this parameter + // in their requests. + RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` + // StartAfter is where you want Amazon S3 to start listing from. Amazon S3 starts // listing after this specified key. StartAfter can be any key in the bucket StartAfter *string `location:"querystring" locationName:"start-after" type:"string"` @@ -6742,8 +6847,10 @@ func (s ListObjectsV2Output) GoString() string { type ListPartsInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Sets the maximum number of parts to return. @@ -6760,6 +6867,8 @@ type ListPartsInput struct { RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` // Upload ID identifying the multipart upload whose parts are being listed. + // + // UploadId is a required field UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"` } @@ -7120,6 +7229,8 @@ type ObjectIdentifier struct { _ struct{} `type:"structure"` // Key name of the object to delete. + // + // Key is a required field Key *string `min:"1" type:"string" required:"true"` // VersionId for the specific version of the object to delete. @@ -7238,9 +7349,13 @@ type PutBucketAccelerateConfigurationInput struct { _ struct{} `type:"structure" payload:"AccelerateConfiguration"` // Specifies the Accelerate Configuration you want to set for the bucket. + // + // AccelerateConfiguration is a required field AccelerateConfiguration *AccelerateConfiguration `locationName:"AccelerateConfiguration" type:"structure" required:"true"` // Name of the bucket for which the accelerate configuration is set. + // + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` } @@ -7292,6 +7407,7 @@ type PutBucketAclInput struct { AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Allows grantee the read, write, read ACP, and write ACP permissions on the @@ -7356,8 +7472,10 @@ func (s PutBucketAclOutput) GoString() string { type PutBucketCorsInput struct { _ struct{} `type:"structure" payload:"CORSConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // CORSConfiguration is a required field CORSConfiguration *CORSConfiguration `locationName:"CORSConfiguration" type:"structure" required:"true"` } @@ -7409,6 +7527,7 @@ func (s PutBucketCorsOutput) GoString() string { type PutBucketLifecycleConfigurationInput struct { _ struct{} `type:"structure" payload:"LifecycleConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` LifecycleConfiguration *BucketLifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure"` @@ -7459,6 +7578,7 @@ func (s PutBucketLifecycleConfigurationOutput) GoString() string { type PutBucketLifecycleInput struct { _ struct{} `type:"structure" payload:"LifecycleConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` LifecycleConfiguration *LifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure"` @@ -7509,8 +7629,10 @@ func (s PutBucketLifecycleOutput) GoString() string { type PutBucketLoggingInput struct { _ struct{} `type:"structure" payload:"BucketLoggingStatus"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // BucketLoggingStatus is a required field BucketLoggingStatus *BucketLoggingStatus `locationName:"BucketLoggingStatus" type:"structure" required:"true"` } @@ -7562,10 +7684,13 @@ func (s PutBucketLoggingOutput) GoString() string { type PutBucketNotificationConfigurationInput struct { _ struct{} `type:"structure" payload:"NotificationConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Container for specifying the notification configuration of the bucket. If // this element is empty, notifications are turned off on the bucket. + // + // NotificationConfiguration is a required field NotificationConfiguration *NotificationConfiguration `locationName:"NotificationConfiguration" type:"structure" required:"true"` } @@ -7617,8 +7742,10 @@ func (s PutBucketNotificationConfigurationOutput) GoString() string { type PutBucketNotificationInput struct { _ struct{} `type:"structure" payload:"NotificationConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // NotificationConfiguration is a required field NotificationConfiguration *NotificationConfigurationDeprecated `locationName:"NotificationConfiguration" type:"structure" required:"true"` } @@ -7665,9 +7792,12 @@ func (s PutBucketNotificationOutput) GoString() string { type PutBucketPolicyInput struct { _ struct{} `type:"structure" payload:"Policy"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // The bucket policy as a JSON document. + // + // Policy is a required field Policy *string `type:"string" required:"true"` } @@ -7714,10 +7844,13 @@ func (s PutBucketPolicyOutput) GoString() string { type PutBucketReplicationInput struct { _ struct{} `type:"structure" payload:"ReplicationConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Container for replication rules. You can add as many as 1,000 rules. Total // replication configuration size can be up to 2 MB. + // + // ReplicationConfiguration is a required field ReplicationConfiguration *ReplicationConfiguration `locationName:"ReplicationConfiguration" type:"structure" required:"true"` } @@ -7769,8 +7902,10 @@ func (s PutBucketReplicationOutput) GoString() string { type PutBucketRequestPaymentInput struct { _ struct{} `type:"structure" payload:"RequestPaymentConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // RequestPaymentConfiguration is a required field RequestPaymentConfiguration *RequestPaymentConfiguration `locationName:"RequestPaymentConfiguration" type:"structure" required:"true"` } @@ -7822,8 +7957,10 @@ func (s PutBucketRequestPaymentOutput) GoString() string { type PutBucketTaggingInput struct { _ struct{} `type:"structure" payload:"Tagging"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Tagging is a required field Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true"` } @@ -7875,12 +8012,14 @@ func (s PutBucketTaggingOutput) GoString() string { type PutBucketVersioningInput struct { _ struct{} `type:"structure" payload:"VersioningConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // The concatenation of the authentication device's serial number, a space, // and the value that is displayed on your authentication device. MFA *string `location:"header" locationName:"x-amz-mfa" type:"string"` + // VersioningConfiguration is a required field VersioningConfiguration *VersioningConfiguration `locationName:"VersioningConfiguration" type:"structure" required:"true"` } @@ -7927,8 +8066,10 @@ func (s PutBucketVersioningOutput) GoString() string { type PutBucketWebsiteInput struct { _ struct{} `type:"structure" payload:"WebsiteConfiguration"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // WebsiteConfiguration is a required field WebsiteConfiguration *WebsiteConfiguration `locationName:"WebsiteConfiguration" type:"structure" required:"true"` } @@ -7985,6 +8126,7 @@ type PutObjectAclInput struct { AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Allows grantee the read, write, read ACP, and write ACP permissions on the @@ -8003,6 +8145,7 @@ type PutObjectAclInput struct { // Allows grantee to write the ACL for the applicable bucket. GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -8077,6 +8220,8 @@ type PutObjectInput struct { Body io.ReadSeeker `type:"blob"` // Name of the bucket to which the PUT operation was initiated. + // + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Specifies caching behavior along the request/reply chain. @@ -8116,6 +8261,8 @@ type PutObjectInput struct { GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"` // Object key for which the PUT operation was initiated. + // + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // A map of metadata to store with the object in S3. @@ -8241,6 +8388,7 @@ func (s PutObjectOutput) GoString() string { type QueueConfiguration struct { _ struct{} `type:"structure"` + // Events is a required field Events []*string `locationName:"Event" type:"list" flattened:"true" required:"true"` // Container for object key name filtering rules. For information about key @@ -8254,6 +8402,8 @@ type QueueConfiguration struct { // Amazon SQS queue ARN to which Amazon S3 will publish a message when it detects // events of specified type. + // + // QueueArn is a required field QueueArn *string `locationName:"Queue" type:"string" required:"true"` } @@ -8350,6 +8500,8 @@ type RedirectAllRequestsTo struct { _ struct{} `type:"structure"` // Name of the host where requests will be redirected. + // + // HostName is a required field HostName *string `type:"string" required:"true"` // Protocol to use (http, https) when redirecting requests. The default is the @@ -8387,10 +8539,14 @@ type ReplicationConfiguration struct { // Amazon Resource Name (ARN) of an IAM role for Amazon S3 to assume when replicating // the objects. + // + // Role is a required field Role *string `type:"string" required:"true"` // Container for information about a particular replication rule. Replication // configuration must have at least one rule and can contain up to 1,000 rules. + // + // Rules is a required field Rules []*ReplicationRule `locationName:"Rule" type:"list" flattened:"true" required:"true"` } @@ -8433,6 +8589,7 @@ func (s *ReplicationConfiguration) Validate() error { type ReplicationRule struct { _ struct{} `type:"structure"` + // Destination is a required field Destination *Destination `type:"structure" required:"true"` // Unique identifier for the rule. The value cannot be longer than 255 characters. @@ -8441,9 +8598,13 @@ type ReplicationRule struct { // Object keyname prefix identifying one or more objects to which the rule applies. // Maximum prefix length can be up to 1,024 characters. Overlapping prefixes // are not supported. + // + // Prefix is a required field Prefix *string `type:"string" required:"true"` // The rule is ignored if status is not Enabled. + // + // Status is a required field Status *string `type:"string" required:"true" enum:"ReplicationRuleStatus"` } @@ -8485,6 +8646,8 @@ type RequestPaymentConfiguration struct { _ struct{} `type:"structure"` // Specifies who pays for the download and request fees. + // + // Payer is a required field Payer *string `type:"string" required:"true" enum:"Payer"` } @@ -8514,8 +8677,10 @@ func (s *RequestPaymentConfiguration) Validate() error { type RestoreObjectInput struct { _ struct{} `type:"structure" payload:"RestoreRequest"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -8585,6 +8750,8 @@ type RestoreRequest struct { _ struct{} `type:"structure"` // Lifetime of the active copy in days + // + // Days is a required field Days *int64 `type:"integer" required:"true"` } @@ -8623,6 +8790,8 @@ type RoutingRule struct { // Container for redirect information. You can redirect requests to another // host, to another page, or with another protocol. In the event of an error, // you can can specify a different error code to return. + // + // Redirect is a required field Redirect *Redirect `type:"structure" required:"true"` } @@ -8676,10 +8845,14 @@ type Rule struct { NoncurrentVersionTransition *NoncurrentVersionTransition `type:"structure"` // Prefix identifying one or more objects to which the rule applies. + // + // Prefix is a required field Prefix *string `type:"string" required:"true"` // If 'Enabled', the rule is currently being applied. If 'Disabled', the rule // is not currently being applied. + // + // Status is a required field Status *string `type:"string" required:"true" enum:"ExpirationStatus"` Transition *Transition `type:"structure"` @@ -8715,9 +8888,13 @@ type Tag struct { _ struct{} `type:"structure"` // Name of the tag. + // + // Key is a required field Key *string `min:"1" type:"string" required:"true"` // Value of the tag. + // + // Value is a required field Value *string `type:"string" required:"true"` } @@ -8753,6 +8930,7 @@ func (s *Tag) Validate() error { type Tagging struct { _ struct{} `type:"structure"` + // TagSet is a required field TagSet []*Tag `locationNameList:"Tag" type:"list" required:"true"` } @@ -8828,6 +9006,7 @@ func (s *TargetGrant) Validate() error { type TopicConfiguration struct { _ struct{} `type:"structure"` + // Events is a required field Events []*string `locationName:"Event" type:"list" flattened:"true" required:"true"` // Container for object key name filtering rules. For information about key @@ -8841,6 +9020,8 @@ type TopicConfiguration struct { // Amazon SNS topic ARN to which Amazon S3 will publish a message when it detects // events of specified type. + // + // TopicArn is a required field TopicArn *string `locationName:"Topic" type:"string" required:"true"` } @@ -8925,10 +9106,13 @@ func (s Transition) GoString() string { type UploadPartCopyInput struct { _ struct{} `type:"structure"` + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // The name of the source bucket and key name of the source object, separated // by a slash (/). Must be URL-encoded. + // + // CopySource is a required field CopySource *string `location:"header" locationName:"x-amz-copy-source" type:"string" required:"true"` // Copies the object if its entity tag (ETag) matches the specified tag. @@ -8964,10 +9148,13 @@ type UploadPartCopyInput struct { // key was transmitted without error. CopySourceSSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key-MD5" type:"string"` + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Part number of part being copied. This is a positive integer between 1 and // 10,000. + // + // PartNumber is a required field PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -8993,6 +9180,8 @@ type UploadPartCopyInput struct { SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"` // Upload ID identifying the multipart upload whose part is being copied. + // + // UploadId is a required field UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"` } @@ -9083,6 +9272,8 @@ type UploadPartInput struct { Body io.ReadSeeker `type:"blob"` // Name of the bucket to which the multipart upload was initiated. + // + // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Size of the body in bytes. This parameter is useful when the size of the @@ -9090,10 +9281,14 @@ type UploadPartInput struct { ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"` // Object key for which the multipart upload was initiated. + // + // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Part number of part being uploaded. This is a positive integer between 1 // and 10,000. + // + // PartNumber is a required field PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer" required:"true"` // Confirms that the requester knows that she or he will be charged for the @@ -9119,6 +9314,8 @@ type UploadPartInput struct { SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"` // Upload ID identifying the multipart upload whose part is being uploaded. + // + // UploadId is a required field UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"` } @@ -9276,61 +9473,78 @@ func (s *WebsiteConfiguration) Validate() error { } const ( - // @enum BucketAccelerateStatus + // BucketAccelerateStatusEnabled is a BucketAccelerateStatus enum value BucketAccelerateStatusEnabled = "Enabled" - // @enum BucketAccelerateStatus + + // BucketAccelerateStatusSuspended is a BucketAccelerateStatus enum value BucketAccelerateStatusSuspended = "Suspended" ) const ( - // @enum BucketCannedACL + // BucketCannedACLPrivate is a BucketCannedACL enum value BucketCannedACLPrivate = "private" - // @enum BucketCannedACL + + // BucketCannedACLPublicRead is a BucketCannedACL enum value BucketCannedACLPublicRead = "public-read" - // @enum BucketCannedACL + + // BucketCannedACLPublicReadWrite is a BucketCannedACL enum value BucketCannedACLPublicReadWrite = "public-read-write" - // @enum BucketCannedACL + + // BucketCannedACLAuthenticatedRead is a BucketCannedACL enum value BucketCannedACLAuthenticatedRead = "authenticated-read" ) const ( - // @enum BucketLocationConstraint + // BucketLocationConstraintEu is a BucketLocationConstraint enum value BucketLocationConstraintEu = "EU" - // @enum BucketLocationConstraint + + // BucketLocationConstraintEuWest1 is a BucketLocationConstraint enum value BucketLocationConstraintEuWest1 = "eu-west-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintUsWest1 is a BucketLocationConstraint enum value BucketLocationConstraintUsWest1 = "us-west-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintUsWest2 is a BucketLocationConstraint enum value BucketLocationConstraintUsWest2 = "us-west-2" - // @enum BucketLocationConstraint + + // BucketLocationConstraintApSouth1 is a BucketLocationConstraint enum value BucketLocationConstraintApSouth1 = "ap-south-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintApSoutheast1 is a BucketLocationConstraint enum value BucketLocationConstraintApSoutheast1 = "ap-southeast-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintApSoutheast2 is a BucketLocationConstraint enum value BucketLocationConstraintApSoutheast2 = "ap-southeast-2" - // @enum BucketLocationConstraint + + // BucketLocationConstraintApNortheast1 is a BucketLocationConstraint enum value BucketLocationConstraintApNortheast1 = "ap-northeast-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintSaEast1 is a BucketLocationConstraint enum value BucketLocationConstraintSaEast1 = "sa-east-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintCnNorth1 is a BucketLocationConstraint enum value BucketLocationConstraintCnNorth1 = "cn-north-1" - // @enum BucketLocationConstraint + + // BucketLocationConstraintEuCentral1 is a BucketLocationConstraint enum value BucketLocationConstraintEuCentral1 = "eu-central-1" ) const ( - // @enum BucketLogsPermission + // BucketLogsPermissionFullControl is a BucketLogsPermission enum value BucketLogsPermissionFullControl = "FULL_CONTROL" - // @enum BucketLogsPermission + + // BucketLogsPermissionRead is a BucketLogsPermission enum value BucketLogsPermissionRead = "READ" - // @enum BucketLogsPermission + + // BucketLogsPermissionWrite is a BucketLogsPermission enum value BucketLogsPermissionWrite = "WRITE" ) const ( - // @enum BucketVersioningStatus + // BucketVersioningStatusEnabled is a BucketVersioningStatus enum value BucketVersioningStatusEnabled = "Enabled" - // @enum BucketVersioningStatus + + // BucketVersioningStatusSuspended is a BucketVersioningStatus enum value BucketVersioningStatusSuspended = "Suspended" ) @@ -9341,147 +9555,178 @@ const ( // XML 1.0, you can add this parameter to request that Amazon S3 encode the // keys in the response. const ( - // @enum EncodingType + // EncodingTypeUrl is a EncodingType enum value EncodingTypeUrl = "url" ) // Bucket event for which to send notifications. const ( - // @enum Event + // EventS3ReducedRedundancyLostObject is a Event enum value EventS3ReducedRedundancyLostObject = "s3:ReducedRedundancyLostObject" - // @enum Event + + // EventS3ObjectCreated is a Event enum value EventS3ObjectCreated = "s3:ObjectCreated:*" - // @enum Event + + // EventS3ObjectCreatedPut is a Event enum value EventS3ObjectCreatedPut = "s3:ObjectCreated:Put" - // @enum Event + + // EventS3ObjectCreatedPost is a Event enum value EventS3ObjectCreatedPost = "s3:ObjectCreated:Post" - // @enum Event + + // EventS3ObjectCreatedCopy is a Event enum value EventS3ObjectCreatedCopy = "s3:ObjectCreated:Copy" - // @enum Event + + // EventS3ObjectCreatedCompleteMultipartUpload is a Event enum value EventS3ObjectCreatedCompleteMultipartUpload = "s3:ObjectCreated:CompleteMultipartUpload" - // @enum Event + + // EventS3ObjectRemoved is a Event enum value EventS3ObjectRemoved = "s3:ObjectRemoved:*" - // @enum Event + + // EventS3ObjectRemovedDelete is a Event enum value EventS3ObjectRemovedDelete = "s3:ObjectRemoved:Delete" - // @enum Event + + // EventS3ObjectRemovedDeleteMarkerCreated is a Event enum value EventS3ObjectRemovedDeleteMarkerCreated = "s3:ObjectRemoved:DeleteMarkerCreated" ) const ( - // @enum ExpirationStatus + // ExpirationStatusEnabled is a ExpirationStatus enum value ExpirationStatusEnabled = "Enabled" - // @enum ExpirationStatus + + // ExpirationStatusDisabled is a ExpirationStatus enum value ExpirationStatusDisabled = "Disabled" ) const ( - // @enum FilterRuleName + // FilterRuleNamePrefix is a FilterRuleName enum value FilterRuleNamePrefix = "prefix" - // @enum FilterRuleName + + // FilterRuleNameSuffix is a FilterRuleName enum value FilterRuleNameSuffix = "suffix" ) const ( - // @enum MFADelete + // MFADeleteEnabled is a MFADelete enum value MFADeleteEnabled = "Enabled" - // @enum MFADelete + + // MFADeleteDisabled is a MFADelete enum value MFADeleteDisabled = "Disabled" ) const ( - // @enum MFADeleteStatus + // MFADeleteStatusEnabled is a MFADeleteStatus enum value MFADeleteStatusEnabled = "Enabled" - // @enum MFADeleteStatus + + // MFADeleteStatusDisabled is a MFADeleteStatus enum value MFADeleteStatusDisabled = "Disabled" ) const ( - // @enum MetadataDirective + // MetadataDirectiveCopy is a MetadataDirective enum value MetadataDirectiveCopy = "COPY" - // @enum MetadataDirective + + // MetadataDirectiveReplace is a MetadataDirective enum value MetadataDirectiveReplace = "REPLACE" ) const ( - // @enum ObjectCannedACL + // ObjectCannedACLPrivate is a ObjectCannedACL enum value ObjectCannedACLPrivate = "private" - // @enum ObjectCannedACL + + // ObjectCannedACLPublicRead is a ObjectCannedACL enum value ObjectCannedACLPublicRead = "public-read" - // @enum ObjectCannedACL + + // ObjectCannedACLPublicReadWrite is a ObjectCannedACL enum value ObjectCannedACLPublicReadWrite = "public-read-write" - // @enum ObjectCannedACL + + // ObjectCannedACLAuthenticatedRead is a ObjectCannedACL enum value ObjectCannedACLAuthenticatedRead = "authenticated-read" - // @enum ObjectCannedACL + + // ObjectCannedACLAwsExecRead is a ObjectCannedACL enum value ObjectCannedACLAwsExecRead = "aws-exec-read" - // @enum ObjectCannedACL + + // ObjectCannedACLBucketOwnerRead is a ObjectCannedACL enum value ObjectCannedACLBucketOwnerRead = "bucket-owner-read" - // @enum ObjectCannedACL + + // ObjectCannedACLBucketOwnerFullControl is a ObjectCannedACL enum value ObjectCannedACLBucketOwnerFullControl = "bucket-owner-full-control" ) const ( - // @enum ObjectStorageClass + // ObjectStorageClassStandard is a ObjectStorageClass enum value ObjectStorageClassStandard = "STANDARD" - // @enum ObjectStorageClass + + // ObjectStorageClassReducedRedundancy is a ObjectStorageClass enum value ObjectStorageClassReducedRedundancy = "REDUCED_REDUNDANCY" - // @enum ObjectStorageClass + + // ObjectStorageClassGlacier is a ObjectStorageClass enum value ObjectStorageClassGlacier = "GLACIER" ) const ( - // @enum ObjectVersionStorageClass + // ObjectVersionStorageClassStandard is a ObjectVersionStorageClass enum value ObjectVersionStorageClassStandard = "STANDARD" ) const ( - // @enum Payer + // PayerRequester is a Payer enum value PayerRequester = "Requester" - // @enum Payer + + // PayerBucketOwner is a Payer enum value PayerBucketOwner = "BucketOwner" ) const ( - // @enum Permission + // PermissionFullControl is a Permission enum value PermissionFullControl = "FULL_CONTROL" - // @enum Permission + + // PermissionWrite is a Permission enum value PermissionWrite = "WRITE" - // @enum Permission + + // PermissionWriteAcp is a Permission enum value PermissionWriteAcp = "WRITE_ACP" - // @enum Permission + + // PermissionRead is a Permission enum value PermissionRead = "READ" - // @enum Permission + + // PermissionReadAcp is a Permission enum value PermissionReadAcp = "READ_ACP" ) const ( - // @enum Protocol + // ProtocolHttp is a Protocol enum value ProtocolHttp = "http" - // @enum Protocol + + // ProtocolHttps is a Protocol enum value ProtocolHttps = "https" ) const ( - // @enum ReplicationRuleStatus + // ReplicationRuleStatusEnabled is a ReplicationRuleStatus enum value ReplicationRuleStatusEnabled = "Enabled" - // @enum ReplicationRuleStatus + + // ReplicationRuleStatusDisabled is a ReplicationRuleStatus enum value ReplicationRuleStatusDisabled = "Disabled" ) const ( - // @enum ReplicationStatus + // ReplicationStatusComplete is a ReplicationStatus enum value ReplicationStatusComplete = "COMPLETE" - // @enum ReplicationStatus + + // ReplicationStatusPending is a ReplicationStatus enum value ReplicationStatusPending = "PENDING" - // @enum ReplicationStatus + + // ReplicationStatusFailed is a ReplicationStatus enum value ReplicationStatusFailed = "FAILED" - // @enum ReplicationStatus + + // ReplicationStatusReplica is a ReplicationStatus enum value ReplicationStatusReplica = "REPLICA" ) // If present, indicates that the requester was successfully charged for the // request. const ( - // @enum RequestCharged + // RequestChargedRequester is a RequestCharged enum value RequestChargedRequester = "requester" ) @@ -9490,38 +9735,44 @@ const ( // Documentation on downloading objects from requester pays buckets can be found // at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html const ( - // @enum RequestPayer + // RequestPayerRequester is a RequestPayer enum value RequestPayerRequester = "requester" ) const ( - // @enum ServerSideEncryption + // ServerSideEncryptionAes256 is a ServerSideEncryption enum value ServerSideEncryptionAes256 = "AES256" - // @enum ServerSideEncryption + + // ServerSideEncryptionAwsKms is a ServerSideEncryption enum value ServerSideEncryptionAwsKms = "aws:kms" ) const ( - // @enum StorageClass + // StorageClassStandard is a StorageClass enum value StorageClassStandard = "STANDARD" - // @enum StorageClass + + // StorageClassReducedRedundancy is a StorageClass enum value StorageClassReducedRedundancy = "REDUCED_REDUNDANCY" - // @enum StorageClass + + // StorageClassStandardIa is a StorageClass enum value StorageClassStandardIa = "STANDARD_IA" ) const ( - // @enum TransitionStorageClass + // TransitionStorageClassGlacier is a TransitionStorageClass enum value TransitionStorageClassGlacier = "GLACIER" - // @enum TransitionStorageClass + + // TransitionStorageClassStandardIa is a TransitionStorageClass enum value TransitionStorageClassStandardIa = "STANDARD_IA" ) const ( - // @enum Type + // TypeCanonicalUser is a Type enum value TypeCanonicalUser = "CanonicalUser" - // @enum Type + + // TypeAmazonCustomerByEmail is a Type enum value TypeAmazonCustomerByEmail = "AmazonCustomerByEmail" - // @enum Type + + // TypeGroup is a Type enum value TypeGroup = "Group" ) diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go index cbd3d31..5e16be4 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go @@ -6,6 +6,10 @@ import ( "github.com/aws/aws-sdk-go/private/waiter" ) +// WaitUntilBucketExists uses the Amazon S3 API operation +// HeadBucket to wait for a condition to be met before returning. +// If the condition is not meet within the max attempt window an error will +// be returned. func (c *S3) WaitUntilBucketExists(input *HeadBucketInput) error { waiterCfg := waiter.Config{ Operation: "HeadBucket", @@ -47,6 +51,10 @@ func (c *S3) WaitUntilBucketExists(input *HeadBucketInput) error { return w.Wait() } +// WaitUntilBucketNotExists uses the Amazon S3 API operation +// HeadBucket to wait for a condition to be met before returning. +// If the condition is not meet within the max attempt window an error will +// be returned. func (c *S3) WaitUntilBucketNotExists(input *HeadBucketInput) error { waiterCfg := waiter.Config{ Operation: "HeadBucket", @@ -70,6 +78,10 @@ func (c *S3) WaitUntilBucketNotExists(input *HeadBucketInput) error { return w.Wait() } +// WaitUntilObjectExists uses the Amazon S3 API operation +// HeadObject to wait for a condition to be met before returning. +// If the condition is not meet within the max attempt window an error will +// be returned. func (c *S3) WaitUntilObjectExists(input *HeadObjectInput) error { waiterCfg := waiter.Config{ Operation: "HeadObject", @@ -99,6 +111,10 @@ func (c *S3) WaitUntilObjectExists(input *HeadObjectInput) error { return w.Wait() } +// WaitUntilObjectNotExists uses the Amazon S3 API operation +// HeadObject to wait for a condition to be met before returning. +// If the condition is not meet within the max attempt window an error will +// be returned. func (c *S3) WaitUntilObjectNotExists(input *HeadObjectInput) error { waiterCfg := waiter.Config{ Operation: "HeadObject", diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go index f11e867..d183fab 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -797,6 +797,8 @@ type AssumeRoleInput struct { Policy *string `min:"1" type:"string"` // The Amazon Resource Name (ARN) of the role to assume. + // + // RoleArn is a required field RoleArn *string `min:"20" type:"string" required:"true"` // An identifier for the assumed role session. @@ -813,6 +815,8 @@ type AssumeRoleInput struct { // of characters consisting of upper- and lower-case alphanumeric characters // with no spaces. You can also include underscores or any of the following // characters: =,.@- + // + // RoleSessionName is a required field RoleSessionName *string `min:"2" type:"string" required:"true"` // The identification number of the MFA device that is associated with the user @@ -967,9 +971,13 @@ type AssumeRoleWithSAMLInput struct { // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes // the IdP. + // + // PrincipalArn is a required field PrincipalArn *string `min:"20" type:"string" required:"true"` // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field RoleArn *string `min:"20" type:"string" required:"true"` // The base-64 encoded SAML authentication response provided by the IdP. @@ -977,6 +985,8 @@ type AssumeRoleWithSAMLInput struct { // For more information, see Configuring a Relying Party and Adding Claims // (http://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html) // in the Using IAM guide. + // + // SAMLAssertion is a required field SAMLAssertion *string `min:"4" type:"string" required:"true"` } @@ -1140,6 +1150,8 @@ type AssumeRoleWithWebIdentityInput struct { ProviderId *string `min:"4" type:"string"` // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field RoleArn *string `min:"20" type:"string" required:"true"` // An identifier for the assumed role session. Typically, you pass the name @@ -1152,12 +1164,16 @@ type AssumeRoleWithWebIdentityInput struct { // of characters consisting of upper- and lower-case alphanumeric characters // with no spaces. You can also include underscores or any of the following // characters: =,.@- + // + // RoleSessionName is a required field RoleSessionName *string `min:"2" type:"string" required:"true"` // The OAuth 2.0 access token or OpenID Connect ID token that is provided by // the identity provider. Your application must get this token by authenticating // the user who is using your application with a web identity provider before // the application makes an AssumeRoleWithWebIdentity call. + // + // WebIdentityToken is a required field WebIdentityToken *string `min:"4" type:"string" required:"true"` } @@ -1273,11 +1289,15 @@ type AssumedRoleUser struct { // AssumeRole action. For more information about ARNs and how to use them in // policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) // in Using IAM. + // + // Arn is a required field Arn *string `min:"20" type:"string" required:"true"` // A unique identifier that contains the role ID and the role session name of // the role that is being assumed. The role ID is generated by AWS when the // role is created. + // + // AssumedRoleId is a required field AssumedRoleId *string `min:"2" type:"string" required:"true"` } @@ -1296,15 +1316,23 @@ type Credentials struct { _ struct{} `type:"structure"` // The access key ID that identifies the temporary security credentials. + // + // AccessKeyId is a required field AccessKeyId *string `min:"16" type:"string" required:"true"` // The date on which the current credentials expire. + // + // Expiration is a required field Expiration *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` // The secret access key that can be used to sign requests. + // + // SecretAccessKey is a required field SecretAccessKey *string `type:"string" required:"true"` // The token that users must pass to the service API to use the temporary credentials. + // + // SessionToken is a required field SessionToken *string `type:"string" required:"true"` } @@ -1322,6 +1350,8 @@ type DecodeAuthorizationMessageInput struct { _ struct{} `type:"structure"` // The encoded message that was returned with the response. + // + // EncodedMessage is a required field EncodedMessage *string `min:"1" type:"string" required:"true"` } @@ -1379,10 +1409,14 @@ type FederatedUser struct { // For more information about ARNs and how to use them in policies, see IAM // Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) // in Using IAM. + // + // Arn is a required field Arn *string `min:"20" type:"string" required:"true"` // The string that identifies the federated user associated with the credentials, // similar to the unique ID of an IAM user. + // + // FederatedUserId is a required field FederatedUserId *string `min:"2" type:"string" required:"true"` } @@ -1460,6 +1494,8 @@ type GetFederationTokenInput struct { // of characters consisting of upper- and lower-case alphanumeric characters // with no spaces. You can also include underscores or any of the following // characters: =,.@- + // + // Name is a required field Name *string `min:"2" type:"string" required:"true"` // An IAM policy in JSON format that is passed with the GetFederationToken call diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go index 565bf58..d42a0bc 100644 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go @@ -13,9 +13,10 @@ // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // NOTE: Due to the following build constraints, this file will only be compiled -// when the code is not running on Google App Engine and "-tags disableunsafe" -// is not added to the go build command line. -// +build !appengine,!disableunsafe +// when the code is not running on Google App Engine, compiled by GopherJS, and +// "-tags safe" is not added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// +build !js,!appengine,!safe,!disableunsafe package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go index 457e412..e47a4e7 100644 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go @@ -13,9 +13,10 @@ // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // NOTE: Due to the following build constraints, this file will only be compiled -// when either the code is running on Google App Engine or "-tags disableunsafe" -// is added to the go build command line. -// +build appengine disableunsafe +// when the code is running on Google App Engine, compiled by GopherJS, or +// "-tags safe" is added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// +build js appengine safe disableunsafe package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go index ee1ab07..5552827 100644 --- a/vendor/github.com/davecgh/go-spew/spew/config.go +++ b/vendor/github.com/davecgh/go-spew/spew/config.go @@ -64,7 +64,7 @@ type ConfigState struct { // inside these interface methods. As a result, this option relies on // access to the unsafe package, so it will not have any effect when // running in environments without access to the unsafe package such as - // Google App Engine or with the "disableunsafe" build tag specified. + // Google App Engine or with the "safe" build tag specified. DisablePointerMethods bool // ContinueOnMethod specifies whether or not recursion should continue once diff --git a/vendor/github.com/fsnotify/fsnotify/AUTHORS b/vendor/github.com/fsnotify/fsnotify/AUTHORS index 71c47ce..0a5bf8f 100644 --- a/vendor/github.com/fsnotify/fsnotify/AUTHORS +++ b/vendor/github.com/fsnotify/fsnotify/AUTHORS @@ -26,12 +26,14 @@ Kelvin Fo Ken-ichirou MATSUZAWA Matt Layher Nathan Youngman +Patrick Paul Hammond Pawel Knap Pieter Droogendijk Pursuit92 Riku Voipio Rob Figueiredo +Slawek Ligus Soge Zhang Tiffany Jernigan Tilak Sharma diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md index f6c7c48..7fe8794 100644 --- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md +++ b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v1.4.1 / 2016-10-04 + +* Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack) + +## v1.4.0 / 2016-10-01 + +* add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie) + ## v1.3.1 / 2016-06-28 * windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc) diff --git a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md index 617e45a..6a81ba4 100644 --- a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md +++ b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md @@ -40,7 +40,7 @@ Contribute upstream: 3. Push to the branch (`git push fork my-new-feature`) 4. Create a new Pull Request on GitHub -This workflow is [thoroughly explained by Katrina Owen](https://blog.splice.com/contributing-open-source-git-repositories-go/). +This workflow is [thoroughly explained by Katrina Owen](https://splice.com/blog/contributing-open-source-git-repositories-go/). ### Testing diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index 5ebce86..3c891e3 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -1,6 +1,6 @@ # File system notifications for Go -[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Coverage](http://gocover.io/_badge/github.com/fsnotify/fsnotify)](http://gocover.io/github.com/fsnotify/fsnotify) +[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) fsnotify utilizes [golang.org/x/sys](https://godoc.org/golang.org/x/sys) rather than `syscall` from the standard library. Ensure you have the latest version installed by running: diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index d1d39a0..e7f55fe 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -30,33 +30,33 @@ const ( Chmod ) -// String returns a string representation of the event in the form -// "file: REMOVE|WRITE|..." -func (e Event) String() string { +func (op Op) String() string { // Use a buffer for efficient string concatenation var buffer bytes.Buffer - if e.Op&Create == Create { + if op&Create == Create { buffer.WriteString("|CREATE") } - if e.Op&Remove == Remove { + if op&Remove == Remove { buffer.WriteString("|REMOVE") } - if e.Op&Write == Write { + if op&Write == Write { buffer.WriteString("|WRITE") } - if e.Op&Rename == Rename { + if op&Rename == Rename { buffer.WriteString("|RENAME") } - if e.Op&Chmod == Chmod { + if op&Chmod == Chmod { buffer.WriteString("|CHMOD") } - - // If buffer remains empty, return no event names if buffer.Len() == 0 { - return fmt.Sprintf("%q: ", e.Name) + return "" } + return buffer.String()[1:] // Strip leading pipe +} - // Return a list of event names, with leading pipe character stripped - return fmt.Sprintf("%q: %s", e.Name, buffer.String()[1:]) +// String returns a string representation of the event in the form +// "file: REMOVE|WRITE|..." +func (e Event) String() string { + return fmt.Sprintf("%q: %s", e.Name, e.Op.String()) } diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go index 8c1b8fd..68b9b30 100644 --- a/vendor/github.com/golang/protobuf/proto/encode.go +++ b/vendor/github.com/golang/protobuf/proto/encode.go @@ -234,10 +234,6 @@ func Marshal(pb Message) ([]byte, error) { } p := NewBuffer(nil) err := p.Marshal(pb) - var state errorState - if err != nil && !state.shouldContinue(err, nil) { - return nil, err - } if p.buf == nil && err == nil { // Return a non-nil slice on success. return []byte{}, nil @@ -266,11 +262,8 @@ func (p *Buffer) Marshal(pb Message) error { // Can the object marshal itself? if m, ok := pb.(Marshaler); ok { data, err := m.Marshal() - if err != nil { - return err - } p.buf = append(p.buf, data...) - return nil + return err } t, base, err := getbase(pb) @@ -282,7 +275,7 @@ func (p *Buffer) Marshal(pb Message) error { } if collectStats { - stats.Encode++ + (stats).Encode++ // Parens are to work around a goimports bug. } if len(p.buf) > maxMarshalSize { @@ -309,7 +302,7 @@ func Size(pb Message) (n int) { } if collectStats { - stats.Size++ + (stats).Size++ // Parens are to work around a goimports bug. } return @@ -1014,7 +1007,6 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) { if p.isMarshaler { m := structPointer_Interface(structp, p.stype).(Marshaler) data, _ := m.Marshal() - n += len(p.tagcode) n += sizeRawBytes(data) continue } diff --git a/vendor/github.com/google/go-github/github/activity_events.go b/vendor/github.com/google/go-github/github/activity_events.go index a0e5f08..6bf38b4 100644 --- a/vendor/github.com/google/go-github/github/activity_events.go +++ b/vendor/github.com/google/go-github/github/activity_events.go @@ -45,6 +45,10 @@ func (e *Event) Payload() (payload interface{}) { payload = &ForkEvent{} case "GollumEvent": payload = &GollumEvent{} + case "IntegrationInstallationEvent": + payload = &IntegrationInstallationEvent{} + case "IntegrationInstallationRepositoriesEvent": + payload = &IntegrationInstallationRepositoriesEvent{} case "IssueActivityEvent": payload = &IssueActivityEvent{} case "IssueCommentEvent": diff --git a/vendor/github.com/google/go-github/github/event_types.go b/vendor/github.com/google/go-github/github/event_types.go index 20f509a..da18f71 100644 --- a/vendor/github.com/google/go-github/github/event_types.go +++ b/vendor/github.com/google/go-github/github/event_types.go @@ -146,6 +146,40 @@ type EditChange struct { } `json:"body,omitempty"` } +// IntegrationInstallationEvent is triggered when an integration is created or deleted. +// The Webhook event name is "integration_installation". +// +// GitHub docs: https://developer.github.com/early-access/integrations/webhooks/#integrationinstallationevent +type IntegrationInstallationEvent struct { + // The action that was performed. Possible values for an "integration_installation" + // event are: "created", "deleted". + Action *string `json:"action,omitempty"` + Installation *Installation `json:"installation,omitempty"` + Sender *User `json:"sender,omitempty"` +} + +// IntegrationInstallationRepositoriesEvent is triggered when an integration repository +// is added or removed. The Webhook event name is "integration_installation_repositories". +// +// GitHub docs: https://developer.github.com/early-access/integrations/webhooks/#integrationinstallationrepositoriesevent +type IntegrationInstallationRepositoriesEvent struct { + // The action that was performed. Possible values for an "integration_installation_repositories" + // event are: "added", "removed". + Action *string `json:"action,omitempty"` + Installation *Installation `json:"installation,omitempty"` + RepositoriesAdded []*Repository `json:"repositories_added,omitempty"` + RepositoriesRemoved []*Repository `json:"repositories_removed,omitempty"` + Sender *User `json:"sender,omitempty"` +} + +// Installation represents a GitHub integration installation. +type Installation struct { + ID *int `json:"id,omitempty"` + Account *User `json:"account,omitempty"` + AccessTokensURL *string `json:"access_tokens_url,omitempty"` + RepositoriesURL *string `json:"repositories_url,omitempty"` +} + // IssueCommentEvent is triggered when an issue comment is created on an issue // or pull request. // The Webhook event name is "issue_comment". diff --git a/vendor/github.com/google/go-github/github/github.go b/vendor/github.com/google/go-github/github/github.go index 8448982..f04a011 100644 --- a/vendor/github.com/google/go-github/github/github.go +++ b/vendor/github.com/google/go-github/github/github.go @@ -87,6 +87,9 @@ const ( // https://developer.github.com/v3/repos/traffic/ mediaTypeTrafficPreview = "application/vnd.github.spiderman-preview+json" + + // https://developer.github.com/changes/2016-09-14-projects-api/ + mediaTypeProjectsPreview = "application/vnd.github.inertia-preview+json" ) // A Client manages communication with the GitHub API. @@ -611,8 +614,8 @@ type RateLimits struct { Core *Rate `json:"core"` // The rate limit for search API requests. Unauthenticated requests - // are limited to 5 requests per minutes. Authenticated requests are - // limited to 20 per minute. + // are limited to 10 requests per minutes. Authenticated requests are + // limited to 30 per minute. // // GitHub API docs: https://developer.github.com/v3/search/#rate-limit Search *Rate `json:"search"` diff --git a/vendor/github.com/google/go-github/github/messages.go b/vendor/github.com/google/go-github/github/messages.go index 9f0aba9..eedb190 100644 --- a/vendor/github.com/google/go-github/github/messages.go +++ b/vendor/github.com/google/go-github/github/messages.go @@ -14,6 +14,7 @@ import ( "crypto/sha256" "crypto/sha512" "encoding/hex" + "encoding/json" "errors" "fmt" "hash" @@ -30,6 +31,37 @@ const ( sha512Prefix = "sha512" // signatureHeader is the GitHub header key used to pass the HMAC hexdigest. signatureHeader = "X-Hub-Signature" + // eventTypeHeader is the Github header key used to pass the event type. + eventTypeHeader = "X-Github-Event" +) + +var ( + // eventTypeMapping maps webhooks types to their corresponding go-github struct types. + eventTypeMapping = map[string]string{ + "commit_comment": "CommitCommentEvent", + "create": "CreateEvent", + "delete": "DeleteEvent", + "deployment": "DeploymentEvent", + "deployment_status": "DeploymentStatusEvent", + "fork": "ForkEvent", + "gollum": "GollumEvent", + "integration_installation": "IntegrationInstallationEvent", + "integration_installation_repositories": "IntegrationInstallationRepositoriesEvent", + "issue_comment": "IssueCommentEvent", + "issues": "IssuesEvent", + "member": "MemberEvent", + "membership": "MembershipEvent", + "page_build": "PageBuildEvent", + "public": "PublicEvent", + "pull_request_review_comment": "PullRequestReviewCommentEvent", + "pull_request": "PullRequestEvent", + "push": "PushEvent", + "repository": "RepositoryEvent", + "release": "ReleaseEvent", + "status": "StatusEvent", + "team_add": "TeamAddEvent", + "watch": "WatchEvent", + } ) // genMAC generates the HMAC signature for a message provided the secret key @@ -117,3 +149,42 @@ func validateSignature(signature string, payload, secretKey []byte) error { } return nil } + +// WebHookType returns the event type of webhook request r. +func WebHookType(r *http.Request) string { + return r.Header.Get(eventTypeHeader) +} + +// ParseWebHook parses the event payload. For recognized event types, a +// value of the corresponding struct type will be returned (as returned +// by Event.Payload()). An error will be returned for unrecognized event +// types. +// +// Example usage: +// +// func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// payload, err := github.ValidatePayload(r, s.webhookSecretKey) +// if err != nil { ... } +// event, err := github.ParseWebHook(github.WebHookType(r), payload) +// if err != nil { ... } +// switch event := event.(type) { +// case CommitCommentEvent: +// processCommitCommentEvent(event) +// case CreateEvent: +// processCreateEvent(event) +// ... +// } +// } +// +func ParseWebHook(messageType string, payload []byte) (interface{}, error) { + eventType, ok := eventTypeMapping[messageType] + if !ok { + return nil, fmt.Errorf("unknown X-Github-Event in message: %v", messageType) + } + + event := Event{ + Type: &eventType, + RawPayload: (*json.RawMessage)(&payload), + } + return event.Payload(), nil +} diff --git a/vendor/github.com/google/go-github/github/pulls.go b/vendor/github.com/google/go-github/github/pulls.go index 0611507..a823c43 100644 --- a/vendor/github.com/google/go-github/github/pulls.go +++ b/vendor/github.com/google/go-github/github/pulls.go @@ -44,6 +44,7 @@ type PullRequest struct { PatchURL *string `json:"patch_url,omitempty"` Assignee *User `json:"assignee,omitempty"` Assignees []*User `json:"assignees,omitempty"` + Milestone *Milestone `json:"milestone,omitempty"` Head *PullRequestBranch `json:"head,omitempty"` Base *PullRequestBranch `json:"base,omitempty"` diff --git a/vendor/github.com/google/go-github/github/repos_forks.go b/vendor/github.com/google/go-github/github/repos_forks.go index 92e9f27..7ef4cb3 100644 --- a/vendor/github.com/google/go-github/github/repos_forks.go +++ b/vendor/github.com/google/go-github/github/repos_forks.go @@ -50,7 +50,7 @@ type RepositoryCreateForkOptions struct { // CreateFork creates a fork of the specified repository. // -// GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks +// GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork func (s *RepositoriesService) CreateFork(owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) { u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) u, err := addOptions(u, opt) diff --git a/vendor/github.com/google/go-github/github/repos_projects.go b/vendor/github.com/google/go-github/github/repos_projects.go new file mode 100644 index 0000000..e37e220 --- /dev/null +++ b/vendor/github.com/google/go-github/github/repos_projects.go @@ -0,0 +1,464 @@ +// Copyright 2016 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "fmt" +) + +// Project represents a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/ +type Project struct { + ID *int `json:"id,omitempty"` + URL *string `json:"url,omitempty"` + OwnerURL *string `json:"owner_url,omitempty"` + Name *string `json:"name,omitempty"` + Body *string `json:"body,omitempty"` + Number *int `json:"number,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` + + // The User object that generated the project. + Creator *User `json:"creator,omitempty"` +} + +func (p Project) String() string { + return Stringify(p) +} + +// ListProjects lists the projects for a repo. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#list-projects +func (s *RepositoriesService) ListProjects(owner, repo string, opt *ListOptions) ([]*Project, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + projects := []*Project{} + resp, err := s.client.Do(req, &projects) + if err != nil { + return nil, resp, err + } + + return projects, resp, err +} + +// GetProject gets a GitHub Project for a repo. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#get-a-project +func (s *RepositoriesService) GetProject(owner, repo string, number int) (*Project, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/%v", owner, repo, number) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + project := &Project{} + resp, err := s.client.Do(req, project) + if err != nil { + return nil, resp, err + } + + return project, resp, err +} + +// ProjectOptions specifies the parameters to the +// RepositoriesService.CreateProject and +// RepositoriesService.UpdateProject methods. +type ProjectOptions struct { + // The name of the project. (Required for creation; optional for update.) + Name string `json:"name,omitempty"` + // The body of the project. (Optional.) + Body string `json:"body,omitempty"` +} + +// CreateProject creates a GitHub Project for the specified repository. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#create-a-project +func (s *RepositoriesService) CreateProject(owner, repo string, projectOptions *ProjectOptions) (*Project, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects", owner, repo) + req, err := s.client.NewRequest("POST", u, projectOptions) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + project := &Project{} + resp, err := s.client.Do(req, project) + if err != nil { + return nil, resp, err + } + + return project, resp, err +} + +// UpdateProject updates a repository project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#update-a-project +func (s *RepositoriesService) UpdateProject(owner, repo string, number int, projectOptions *ProjectOptions) (*Project, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/%v", owner, repo, number) + req, err := s.client.NewRequest("PATCH", u, projectOptions) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + project := &Project{} + resp, err := s.client.Do(req, project) + if err != nil { + return nil, resp, err + } + + return project, resp, err +} + +// DeleteProject deletes a GitHub Project from a repository. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#delete-a-project +func (s *RepositoriesService) DeleteProject(owner, repo string, number int) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/%v", owner, repo, number) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectColumn represents a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/ +type ProjectColumn struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + ProjectURL *string `json:"project_url,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` +} + +// ListProjectColumns lists the columns of a GitHub Project for a repo. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#list-columns +func (s *RepositoriesService) ListProjectColumns(owner, repo string, number int, opt *ListOptions) ([]*ProjectColumn, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/%v/columns", owner, repo, number) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + columns := []*ProjectColumn{} + resp, err := s.client.Do(req, &columns) + if err != nil { + return nil, resp, err + } + + return columns, resp, err +} + +// GetProjectColumn gets a column of a GitHub Project for a repo. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#get-a-column +func (s *RepositoriesService) GetProjectColumn(owner, repo string, columnID int) (*ProjectColumn, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/%v", owner, repo, columnID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + column := &ProjectColumn{} + resp, err := s.client.Do(req, column) + if err != nil { + return nil, resp, err + } + + return column, resp, err +} + +// ProjectColumnOptions specifies the parameters to the +// RepositoriesService.CreateProjectColumn and +// RepositoriesService.UpdateProjectColumn methods. +type ProjectColumnOptions struct { + // The name of the project column. (Required for creation and update.) + Name string `json:"name"` +} + +// CreateProjectColumn creates a column for the specified (by number) project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#create-a-column +func (s *RepositoriesService) CreateProjectColumn(owner, repo string, number int, columnOptions *ProjectColumnOptions) (*ProjectColumn, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/%v/columns", owner, repo, number) + req, err := s.client.NewRequest("POST", u, columnOptions) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + column := &ProjectColumn{} + resp, err := s.client.Do(req, column) + if err != nil { + return nil, resp, err + } + + return column, resp, err +} + +// UpdateProjectColumn updates a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#update-a-column +func (s *RepositoriesService) UpdateProjectColumn(owner, repo string, columnID int, columnOptions *ProjectColumnOptions) (*ProjectColumn, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/%v", owner, repo, columnID) + req, err := s.client.NewRequest("PATCH", u, columnOptions) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + column := &ProjectColumn{} + resp, err := s.client.Do(req, column) + if err != nil { + return nil, resp, err + } + + return column, resp, err +} + +// DeleteProjectColumn deletes a column from a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#delete-a-column +func (s *RepositoriesService) DeleteProjectColumn(owner, repo string, columnID int) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/%v", owner, repo, columnID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectColumnMoveOptions specifies the parameters to the +// RepositoriesService.MoveProjectColumn method. +type ProjectColumnMoveOptions struct { + // Position can be one of "first", "last", or "after:", where + // is the ID of a column in the same project. (Required.) + Position string `json:"position"` +} + +// MoveProjectColumn moves a column within a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#move-a-column +func (s *RepositoriesService) MoveProjectColumn(owner, repo string, columnID int, moveOptions *ProjectColumnMoveOptions) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/%v/moves", owner, repo, columnID) + req, err := s.client.NewRequest("POST", u, moveOptions) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectCard represents a card in a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/ +type ProjectCard struct { + ColumnURL *string `json:"column_url,omitempty"` + ContentURL *string `json:"content_url,omitempty"` + ID *int `json:"id,omitempty"` + Note *string `json:"note,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + UpdatedAt *Timestamp `json:"updated_at,omitempty"` +} + +// ListProjectCards lists the cards in a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#list-projects-cards +func (s *RepositoriesService) ListProjectCards(owner, repo string, columnID int, opt *ListOptions) ([]*ProjectCard, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/%v/cards", owner, repo, columnID) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + cards := []*ProjectCard{} + resp, err := s.client.Do(req, &cards) + if err != nil { + return nil, resp, err + } + + return cards, resp, err +} + +// GetProjectCard gets a card in a column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#get-a-project-card +func (s *RepositoriesService) GetProjectCard(owner, repo string, columnID int) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v", owner, repo, columnID) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + card := &ProjectCard{} + resp, err := s.client.Do(req, card) + if err != nil { + return nil, resp, err + } + + return card, resp, err +} + +// ProjectCardOptions specifies the parameters to the +// RepositoriesService.CreateProjectCard and +// RepositoriesService.UpdateProjectCard methods. +type ProjectCardOptions struct { + // The note of the card. Note and ContentID are mutually exclusive. + Note string `json:"note,omitempty"` + // The ID (not Number) of the Issue or Pull Request to associate with this card. + // Note and ContentID are mutually exclusive. + ContentID int `json:"content_id,omitempty"` + // The type of content to associate with this card. Possible values are: "Issue", "PullRequest". + ContentType string `json:"content_type,omitempty"` +} + +// CreateProjectCard creates a card in the specified column of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#create-a-project-card +func (s *RepositoriesService) CreateProjectCard(owner, repo string, columnID int, cardOptions *ProjectCardOptions) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/%v/cards", owner, repo, columnID) + req, err := s.client.NewRequest("POST", u, cardOptions) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + card := &ProjectCard{} + resp, err := s.client.Do(req, card) + if err != nil { + return nil, resp, err + } + + return card, resp, err +} + +// UpdateProjectCard updates a card of a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#update-a-project-card +func (s *RepositoriesService) UpdateProjectCard(owner, repo string, cardID int, cardOptions *ProjectCardOptions) (*ProjectCard, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v", owner, repo, cardID) + req, err := s.client.NewRequest("PATCH", u, cardOptions) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + card := &ProjectCard{} + resp, err := s.client.Do(req, card) + if err != nil { + return nil, resp, err + } + + return card, resp, err +} + +// DeleteProjectCard deletes a card from a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#delete-a-project-card +func (s *RepositoriesService) DeleteProjectCard(owner, repo string, cardID int) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v", owner, repo, cardID) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} + +// ProjectCardMoveOptions specifies the parameters to the +// RepositoriesService.MoveProjectCard method. +type ProjectCardMoveOptions struct { + // Position can be one of "top", "bottom", or "after:", where + // is the ID of a card in the same project. + Position string `json:"position"` + // ColumnID is the ID of a column in the same project. Note that ColumnID + // is required when using Position "after:" when that card is in + // another column; otherwise it is optional. + ColumnID int `json:"column_id,omitempty"` +} + +// MoveProjectCard moves a card within a GitHub Project. +// +// GitHub API docs: https://developer.github.com/v3/repos/projects/#move-a-project-card +func (s *RepositoriesService) MoveProjectCard(owner, repo string, cardID int, moveOptions *ProjectCardMoveOptions) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/projects/columns/cards/%v/moves", owner, repo, cardID) + req, err := s.client.NewRequest("POST", u, moveOptions) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeProjectsPreview) + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/gorilla/csrf/README.md b/vendor/github.com/gorilla/csrf/README.md index 02e4f42..9bcf3f8 100644 --- a/vendor/github.com/gorilla/csrf/README.md +++ b/vendor/github.com/gorilla/csrf/README.md @@ -89,7 +89,7 @@ func main() { func ShowSignupForm(w http.ResponseWriter, r *http.Request) { // signup_form.tmpl just needs a {{ .csrfField }} template tag for // csrf.TemplateField to inject the CSRF token into. Easy! - t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{ + t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{}{ csrf.TemplateTag: csrf.TemplateField(r), }) // We could also retrieve the token directly from csrf.Token(r) and diff --git a/vendor/github.com/gorilla/csrf/csrf.go b/vendor/github.com/gorilla/csrf/csrf.go index b4b0439..58ffd5b 100644 --- a/vendor/github.com/gorilla/csrf/csrf.go +++ b/vendor/github.com/gorilla/csrf/csrf.go @@ -110,7 +110,7 @@ type options struct { // func GetSignupForm(w http.ResponseWriter, r *http.Request) { // // signup_form.tmpl just needs a {{ .csrfField }} template tag for // // csrf.TemplateField to inject the CSRF token into. Easy! -// t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{ +// t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{}{ // csrf.TemplateTag: csrf.TemplateField(r), // }) // // We could also retrieve the token directly from csrf.Token(r) and diff --git a/vendor/github.com/gorilla/mux/doc.go b/vendor/github.com/gorilla/mux/doc.go index 291ef5e..e9573dd 100644 --- a/vendor/github.com/gorilla/mux/doc.go +++ b/vendor/github.com/gorilla/mux/doc.go @@ -47,6 +47,10 @@ variable will be anything until the next slash. For example: r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) +Groups can be used inside patterns, as long as they are non-capturing (?:re). For example: + + r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler) + The names are used to create a map of route variables which can be retrieved calling mux.Vars(): diff --git a/vendor/github.com/gorilla/securecookie/securecookie.go b/vendor/github.com/gorilla/securecookie/securecookie.go index 83dd606..cd4e097 100644 --- a/vendor/github.com/gorilla/securecookie/securecookie.go +++ b/vendor/github.com/gorilla/securecookie/securecookie.go @@ -102,6 +102,7 @@ var ( errTimestampExpired = cookieError{typ: decodeError, msg: "expired timestamp"} errDecryptionFailed = cookieError{typ: decodeError, msg: "the value could not be decrypted"} errValueNotByte = cookieError{typ: decodeError, msg: "value not a []byte."} + errValueNotBytePtr = cookieError{typ: decodeError, msg: "value not a pointer to []byte."} // ErrMacInvalid indicates that cookie decoding failed because the HMAC // could not be extracted and verified. Direct use of this error @@ -474,12 +475,11 @@ func (e NopEncoder) Serialize(src interface{}) ([]byte, error) { // Deserialize passes a []byte through as-is. func (e NopEncoder) Deserialize(src []byte, dst interface{}) error { - if _, ok := dst.([]byte); ok { - dst = src + if dat, ok := dst.(*[]byte); ok { + *dat = src return nil } - - return errValueNotByte + return errValueNotBytePtr } // Encoding ------------------------------------------------------------------- diff --git a/vendor/github.com/gorilla/sessions/README.md b/vendor/github.com/gorilla/sessions/README.md index 12f6118..65e5e1b 100644 --- a/vendor/github.com/gorilla/sessions/README.md +++ b/vendor/github.com/gorilla/sessions/README.md @@ -64,7 +64,7 @@ Other implementations of the `sessions.Store` interface: * [github.com/srinathgs/couchbasestore](https://github.com/srinathgs/couchbasestore) - Couchbase * [github.com/denizeren/dynamostore](https://github.com/denizeren/dynamostore) - Dynamodb on AWS * [github.com/bradleypeabody/gorilla-sessions-memcache](https://github.com/bradleypeabody/gorilla-sessions-memcache) - Memcache -* [github.com/dsoprea/goappenginesessioncascade](https://github.com/dsoprea/goappenginesessioncascade) - Memcache/Datastore/Context in AppEngine +* [github.com/dsoprea/go-appengine-sessioncascade](https://github.com/dsoprea/go-appengine-sessioncascade) - Memcache/Datastore/Context in AppEngine * [github.com/kidstuff/mongostore](https://github.com/kidstuff/mongostore) - MongoDB * [github.com/srinathgs/mysqlstore](https://github.com/srinathgs/mysqlstore) - MySQL * [github.com/antonlindstrom/pgstore](https://github.com/antonlindstrom/pgstore) - PostgreSQL diff --git a/vendor/github.com/gorilla/sessions/store.go b/vendor/github.com/gorilla/sessions/store.go index ba3b9e9..4ff6b6c 100644 --- a/vendor/github.com/gorilla/sessions/store.go +++ b/vendor/github.com/gorilla/sessions/store.go @@ -205,8 +205,22 @@ func (s *FilesystemStore) New(r *http.Request, name string) (*Session, error) { } // Save adds a single session to the response. +// +// If the Options.MaxAge of the session is <= 0 then the session file will be +// deleted from the store path. With this process it enforces the properly +// session cookie handling so no need to trust in the cookie management in the +// web browser. func (s *FilesystemStore) Save(r *http.Request, w http.ResponseWriter, session *Session) error { + // Delete if max-age is <= 0 + if session.Options.MaxAge <= 0 { + if err := s.erase(session); err != nil { + return err + } + http.SetCookie(w, NewCookie(session.Name(), "", session.Options)) + return nil + } + if session.ID == "" { // Because the ID is used in the filename, encode it to // use alphanumeric characters only. @@ -268,3 +282,14 @@ func (s *FilesystemStore) load(session *Session) error { } return nil } + +// delete session file +func (s *FilesystemStore) erase(session *Session) error { + filename := filepath.Join(s.path, "session_"+session.ID) + + fileMutex.RLock() + defer fileMutex.RUnlock() + + err := os.Remove(filename) + return err +} diff --git a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go index ea3734f..6e5ef65 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go +++ b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go @@ -156,7 +156,8 @@ func (o *ObjectKey) Pos() token.Pos { type LiteralType struct { Token token.Token - // associated line comment, only when used in a list + // comment types, only used when in a list + LeadComment *CommentGroup LineComment *CommentGroup } diff --git a/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go b/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go index f46ed4c..0aa080f 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go +++ b/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go @@ -337,6 +337,12 @@ func (p *Parser) listType() (*ast.ListType, error) { return nil, err } + // If there is a lead comment, apply it + if p.leadComment != nil { + node.LeadComment = p.leadComment + p.leadComment = nil + } + l.Add(node) needComma = true case token.COMMA: diff --git a/vendor/github.com/hashicorp/hcl/json/parser/parser.go b/vendor/github.com/hashicorp/hcl/json/parser/parser.go index 3a62ec3..acf9594 100644 --- a/vendor/github.com/hashicorp/hcl/json/parser/parser.go +++ b/vendor/github.com/hashicorp/hcl/json/parser/parser.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/hashicorp/hcl/hcl/ast" + hcltoken "github.com/hashicorp/hcl/hcl/token" "github.com/hashicorp/hcl/json/scanner" "github.com/hashicorp/hcl/json/token" ) @@ -103,6 +104,14 @@ func (p *Parser) objectItem() (*ast.ObjectItem, error) { switch p.tok.Type { case token.COLON: + pos := p.tok.Pos + o.Assign = hcltoken.Pos{ + Filename: pos.Filename, + Offset: pos.Offset, + Line: pos.Line, + Column: pos.Column, + } + o.Val, err = p.objectValue() if err != nil { return nil, err diff --git a/vendor/github.com/mattn/go-sqlite3/doc.go b/vendor/github.com/mattn/go-sqlite3/doc.go index c721f77..030cd93 100644 --- a/vendor/github.com/mattn/go-sqlite3/doc.go +++ b/vendor/github.com/mattn/go-sqlite3/doc.go @@ -110,3 +110,5 @@ See the documentation of RegisterFunc for more details. */ package sqlite3 + +import "C" diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3.go b/vendor/github.com/mattn/go-sqlite3/sqlite3.go index f3c1226..af4c68d 100644 --- a/vendor/github.com/mattn/go-sqlite3/sqlite3.go +++ b/vendor/github.com/mattn/go-sqlite3/sqlite3.go @@ -9,6 +9,8 @@ package sqlite3 #cgo CFLAGS: -std=gnu99 #cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE #cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61 +#cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15 +#cgo CFLAGS: -Wno-deprecated-declarations -Wno-c99-extensions #ifndef USE_LIBSQLITE3 #include #else @@ -97,8 +99,6 @@ int _sqlite3_create_function( } void callbackTrampoline(sqlite3_context*, int, sqlite3_value**); -void stepTrampoline(sqlite3_context*, int, sqlite3_value**); -void doneTrampoline(sqlite3_context*); */ import "C" import ( @@ -388,131 +388,6 @@ func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) erro return nil } -// RegisterAggregator makes a Go type available as a SQLite aggregation function. -// -// Because aggregation is incremental, it's implemented in Go with a -// type that has 2 methods: func Step(values) accumulates one row of -// data into the accumulator, and func Done() ret finalizes and -// returns the aggregate value. "values" and "ret" may be any type -// supported by RegisterFunc. -// -// RegisterAggregator takes as implementation a constructor function -// that constructs an instance of the aggregator type each time an -// aggregation begins. The constructor must return a pointer to a -// type, or an interface that implements Step() and Done(). -// -// The constructor function and the Step/Done methods may optionally -// return an error in addition to their other return values. -// -// See _example/go_custom_funcs for a detailed example. -func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { - var ai aggInfo - ai.constructor = reflect.ValueOf(impl) - t := ai.constructor.Type() - if t.Kind() != reflect.Func { - return errors.New("non-function passed to RegisterAggregator") - } - if t.NumOut() != 1 && t.NumOut() != 2 { - return errors.New("SQLite aggregator constructors must return 1 or 2 values") - } - if t.NumOut() == 2 && !t.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { - return errors.New("Second return value of SQLite function must be error") - } - if t.NumIn() != 0 { - return errors.New("SQLite aggregator constructors must not have arguments") - } - - agg := t.Out(0) - switch agg.Kind() { - case reflect.Ptr, reflect.Interface: - default: - return errors.New("SQlite aggregator constructor must return a pointer object") - } - stepFn, found := agg.MethodByName("Step") - if !found { - return errors.New("SQlite aggregator doesn't have a Step() function") - } - step := stepFn.Type - if step.NumOut() != 0 && step.NumOut() != 1 { - return errors.New("SQlite aggregator Step() function must return 0 or 1 values") - } - if step.NumOut() == 1 && !step.Out(0).Implements(reflect.TypeOf((*error)(nil)).Elem()) { - return errors.New("type of SQlite aggregator Step() return value must be error") - } - - stepNArgs := step.NumIn() - start := 0 - if agg.Kind() == reflect.Ptr { - // Skip over the method receiver - stepNArgs-- - start++ - } - if step.IsVariadic() { - stepNArgs-- - } - for i := start; i < start+stepNArgs; i++ { - conv, err := callbackArg(step.In(i)) - if err != nil { - return err - } - ai.stepArgConverters = append(ai.stepArgConverters, conv) - } - if step.IsVariadic() { - conv, err := callbackArg(t.In(start + stepNArgs).Elem()) - if err != nil { - return err - } - ai.stepVariadicConverter = conv - // Pass -1 to sqlite so that it allows any number of - // arguments. The call helper verifies that the minimum number - // of arguments is present for variadic functions. - stepNArgs = -1 - } - - doneFn, found := agg.MethodByName("Done") - if !found { - return errors.New("SQlite aggregator doesn't have a Done() function") - } - done := doneFn.Type - doneNArgs := done.NumIn() - if agg.Kind() == reflect.Ptr { - // Skip over the method receiver - doneNArgs-- - } - if doneNArgs != 0 { - return errors.New("SQlite aggregator Done() function must have no arguments") - } - if done.NumOut() != 1 && done.NumOut() != 2 { - return errors.New("SQLite aggregator Done() function must return 1 or 2 values") - } - if done.NumOut() == 2 && !done.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { - return errors.New("second return value of SQLite aggregator Done() function must be error") - } - - conv, err := callbackRet(done.Out(0)) - if err != nil { - return err - } - ai.doneRetConverter = conv - ai.active = make(map[int64]reflect.Value) - ai.next = 1 - - // ai must outlast the database connection, or we'll have dangling pointers. - c.aggregators = append(c.aggregators, &ai) - - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - opts := C.SQLITE_UTF8 - if pure { - opts |= C.SQLITE_DETERMINISTIC - } - rv := C._sqlite3_create_function(c.db, cname, C.int(stepNArgs), C.int(opts), C.uintptr_t(newHandle(c, &ai)), nil, (*[0]byte)(unsafe.Pointer(C.stepTrampoline)), (*[0]byte)(unsafe.Pointer(C.doneTrampoline))) - if rv != C.SQLITE_OK { - return c.lastError() - } - return nil -} - // AutoCommit return which currently auto commit or not. func (c *SQLiteConn) AutoCommit() bool { return int(C.sqlite3_get_autocommit(c.db)) != 0 diff --git a/vendor/github.com/mattn/go-sqlite3/tracecallback.go b/vendor/github.com/mattn/go-sqlite3/tracecallback.go new file mode 100644 index 0000000..bf222b5 --- /dev/null +++ b/vendor/github.com/mattn/go-sqlite3/tracecallback.go @@ -0,0 +1,415 @@ +// Copyright (C) 2016 Yasuhiro Matsumoto . +// TODO: add "Gimpl do foo" team? +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. +// +build trace + +package sqlite3 + +/* +#ifndef USE_LIBSQLITE3 +#include +#else +#include +#endif +#include + +void stepTrampoline(sqlite3_context*, int, sqlite3_value**); +void doneTrampoline(sqlite3_context*); +void traceCallbackTrampoline(unsigned traceEventCode, void *ctx, void *p, void *x); +*/ +import "C" + +import ( + "errors" + "fmt" + "reflect" + "strings" + "sync" + "unsafe" +) + +// Trace... constants identify the possible events causing callback invocation. +// Values are same as the corresponding SQLite Trace Event Codes. +const ( + TraceStmt = C.SQLITE_TRACE_STMT + TraceProfile = C.SQLITE_TRACE_PROFILE + TraceRow = C.SQLITE_TRACE_ROW + TraceClose = C.SQLITE_TRACE_CLOSE +) + +type TraceInfo struct { + // Pack together the shorter fields, to keep the struct smaller. + // On a 64-bit machine there would be padding + // between EventCode and ConnHandle; having AutoCommit here is "free": + EventCode uint32 + AutoCommit bool + ConnHandle uintptr + + // Usually filled, unless EventCode = TraceClose = SQLITE_TRACE_CLOSE: + // identifier for a prepared statement: + StmtHandle uintptr + + // Two strings filled when EventCode = TraceStmt = SQLITE_TRACE_STMT: + // (1) either the unexpanded SQL text of the prepared statement, or + // an SQL comment that indicates the invocation of a trigger; + // (2) expanded SQL, if requested and if (1) is not an SQL comment. + StmtOrTrigger string + ExpandedSQL string // only if requested (TraceConfig.WantExpandedSQL = true) + + // filled when EventCode = TraceProfile = SQLITE_TRACE_PROFILE: + // estimated number of nanoseconds that the prepared statement took to run: + RunTimeNanosec int64 + + DBError Error +} + +// TraceUserCallback gives the signature for a trace function +// provided by the user (Go application programmer). +// SQLite 3.14 documentation (as of September 2, 2016) +// for SQL Trace Hook = sqlite3_trace_v2(): +// The integer return value from the callback is currently ignored, +// though this may change in future releases. Callback implementations +// should return zero to ensure future compatibility. +type TraceUserCallback func(TraceInfo) int + +type TraceConfig struct { + Callback TraceUserCallback + EventMask uint + WantExpandedSQL bool +} + +func fillDBError(dbErr *Error, db *C.sqlite3) { + // See SQLiteConn.lastError(), in file 'sqlite3.go' at the time of writing (Sept 5, 2016) + dbErr.Code = ErrNo(C.sqlite3_errcode(db)) + dbErr.ExtendedCode = ErrNoExtended(C.sqlite3_extended_errcode(db)) + dbErr.err = C.GoString(C.sqlite3_errmsg(db)) +} + +func fillExpandedSQL(info *TraceInfo, db *C.sqlite3, pStmt unsafe.Pointer) { + if pStmt == nil { + panic("No SQLite statement pointer in P arg of trace_v2 callback") + } + + expSQLiteCStr := C.sqlite3_expanded_sql((*C.sqlite3_stmt)(pStmt)) + if expSQLiteCStr == nil { + fillDBError(&info.DBError, db) + return + } + info.ExpandedSQL = C.GoString(expSQLiteCStr) +} + +//export traceCallbackTrampoline +func traceCallbackTrampoline( + traceEventCode uint, + // Parameter named 'C' in SQLite docs = Context given at registration: + ctx unsafe.Pointer, + // Parameter named 'P' in SQLite docs (Primary event data?): + p unsafe.Pointer, + // Parameter named 'X' in SQLite docs (eXtra event data?): + xValue unsafe.Pointer) int { + + if ctx == nil { + panic(fmt.Sprintf("No context (ev 0x%x)", traceEventCode)) + } + + contextDB := (*C.sqlite3)(ctx) + connHandle := uintptr(ctx) + + var traceConf TraceConfig + var found bool + if traceEventCode == TraceClose { + // clean up traceMap: 'pop' means get and delete + traceConf, found = popTraceMapping(connHandle) + } else { + traceConf, found = lookupTraceMapping(connHandle) + } + + if !found { + panic(fmt.Sprintf("Mapping not found for handle 0x%x (ev 0x%x)", + connHandle, traceEventCode)) + } + + var info TraceInfo + + info.EventCode = uint32(traceEventCode) + info.AutoCommit = (int(C.sqlite3_get_autocommit(contextDB)) != 0) + info.ConnHandle = connHandle + + switch traceEventCode { + case TraceStmt: + info.StmtHandle = uintptr(p) + + var xStr string + if xValue != nil { + xStr = C.GoString((*C.char)(xValue)) + } + info.StmtOrTrigger = xStr + if !strings.HasPrefix(xStr, "--") { + // Not SQL comment, therefore the current event + // is not related to a trigger. + // The user might want to receive the expanded SQL; + // let's check: + if traceConf.WantExpandedSQL { + fillExpandedSQL(&info, contextDB, p) + } + } + + case TraceProfile: + info.StmtHandle = uintptr(p) + + if xValue == nil { + panic("NULL pointer in X arg of trace_v2 callback for SQLITE_TRACE_PROFILE event") + } + + info.RunTimeNanosec = *(*int64)(xValue) + + // sample the error //TODO: is it safe? is it useful? + fillDBError(&info.DBError, contextDB) + + case TraceRow: + info.StmtHandle = uintptr(p) + + case TraceClose: + handle := uintptr(p) + if handle != info.ConnHandle { + panic(fmt.Sprintf("Different conn handle 0x%x (expected 0x%x) in SQLITE_TRACE_CLOSE event.", + handle, info.ConnHandle)) + } + + default: + // Pass unsupported events to the user callback (if configured); + // let the user callback decide whether to panic or ignore them. + } + + // Do not execute user callback when the event was not requested by user! + // Remember that the Close event is always selected when + // registering this callback trampoline with SQLite --- for cleanup. + // In the future there may be more events forced to "selected" in SQLite + // for the driver's needs. + if traceConf.EventMask&traceEventCode == 0 { + return 0 + } + + r := 0 + if traceConf.Callback != nil { + r = traceConf.Callback(info) + } + return r +} + +type traceMapEntry struct { + config TraceConfig +} + +var traceMapLock sync.Mutex +var traceMap = make(map[uintptr]traceMapEntry) + +func addTraceMapping(connHandle uintptr, traceConf TraceConfig) { + traceMapLock.Lock() + defer traceMapLock.Unlock() + + oldEntryCopy, found := traceMap[connHandle] + if found { + panic(fmt.Sprintf("Adding trace config %v: handle 0x%x already registered (%v).", + traceConf, connHandle, oldEntryCopy.config)) + } + traceMap[connHandle] = traceMapEntry{config: traceConf} + fmt.Printf("Added trace config %v: handle 0x%x.\n", traceConf, connHandle) +} + +func lookupTraceMapping(connHandle uintptr) (TraceConfig, bool) { + traceMapLock.Lock() + defer traceMapLock.Unlock() + + entryCopy, found := traceMap[connHandle] + return entryCopy.config, found +} + +// 'pop' = get and delete from map before returning the value to the caller +func popTraceMapping(connHandle uintptr) (TraceConfig, bool) { + traceMapLock.Lock() + defer traceMapLock.Unlock() + + entryCopy, found := traceMap[connHandle] + if found { + delete(traceMap, connHandle) + fmt.Printf("Pop handle 0x%x: deleted trace config %v.\n", connHandle, entryCopy.config) + } + return entryCopy.config, found +} + +// RegisterAggregator makes a Go type available as a SQLite aggregation function. +// +// Because aggregation is incremental, it's implemented in Go with a +// type that has 2 methods: func Step(values) accumulates one row of +// data into the accumulator, and func Done() ret finalizes and +// returns the aggregate value. "values" and "ret" may be any type +// supported by RegisterFunc. +// +// RegisterAggregator takes as implementation a constructor function +// that constructs an instance of the aggregator type each time an +// aggregation begins. The constructor must return a pointer to a +// type, or an interface that implements Step() and Done(). +// +// The constructor function and the Step/Done methods may optionally +// return an error in addition to their other return values. +// +// See _example/go_custom_funcs for a detailed example. +func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { + var ai aggInfo + ai.constructor = reflect.ValueOf(impl) + t := ai.constructor.Type() + if t.Kind() != reflect.Func { + return errors.New("non-function passed to RegisterAggregator") + } + if t.NumOut() != 1 && t.NumOut() != 2 { + return errors.New("SQLite aggregator constructors must return 1 or 2 values") + } + if t.NumOut() == 2 && !t.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { + return errors.New("Second return value of SQLite function must be error") + } + if t.NumIn() != 0 { + return errors.New("SQLite aggregator constructors must not have arguments") + } + + agg := t.Out(0) + switch agg.Kind() { + case reflect.Ptr, reflect.Interface: + default: + return errors.New("SQlite aggregator constructor must return a pointer object") + } + stepFn, found := agg.MethodByName("Step") + if !found { + return errors.New("SQlite aggregator doesn't have a Step() function") + } + step := stepFn.Type + if step.NumOut() != 0 && step.NumOut() != 1 { + return errors.New("SQlite aggregator Step() function must return 0 or 1 values") + } + if step.NumOut() == 1 && !step.Out(0).Implements(reflect.TypeOf((*error)(nil)).Elem()) { + return errors.New("type of SQlite aggregator Step() return value must be error") + } + + stepNArgs := step.NumIn() + start := 0 + if agg.Kind() == reflect.Ptr { + // Skip over the method receiver + stepNArgs-- + start++ + } + if step.IsVariadic() { + stepNArgs-- + } + for i := start; i < start+stepNArgs; i++ { + conv, err := callbackArg(step.In(i)) + if err != nil { + return err + } + ai.stepArgConverters = append(ai.stepArgConverters, conv) + } + if step.IsVariadic() { + conv, err := callbackArg(t.In(start + stepNArgs).Elem()) + if err != nil { + return err + } + ai.stepVariadicConverter = conv + // Pass -1 to sqlite so that it allows any number of + // arguments. The call helper verifies that the minimum number + // of arguments is present for variadic functions. + stepNArgs = -1 + } + + doneFn, found := agg.MethodByName("Done") + if !found { + return errors.New("SQlite aggregator doesn't have a Done() function") + } + done := doneFn.Type + doneNArgs := done.NumIn() + if agg.Kind() == reflect.Ptr { + // Skip over the method receiver + doneNArgs-- + } + if doneNArgs != 0 { + return errors.New("SQlite aggregator Done() function must have no arguments") + } + if done.NumOut() != 1 && done.NumOut() != 2 { + return errors.New("SQLite aggregator Done() function must return 1 or 2 values") + } + if done.NumOut() == 2 && !done.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) { + return errors.New("second return value of SQLite aggregator Done() function must be error") + } + + conv, err := callbackRet(done.Out(0)) + if err != nil { + return err + } + ai.doneRetConverter = conv + ai.active = make(map[int64]reflect.Value) + ai.next = 1 + + // ai must outlast the database connection, or we'll have dangling pointers. + c.aggregators = append(c.aggregators, &ai) + + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + opts := C.SQLITE_UTF8 + if pure { + opts |= C.SQLITE_DETERMINISTIC + } + rv := C._sqlite3_create_function(c.db, cname, C.int(stepNArgs), C.int(opts), C.uintptr_t(newHandle(c, &ai)), nil, (*[0]byte)(unsafe.Pointer(C.stepTrampoline)), (*[0]byte)(unsafe.Pointer(C.doneTrampoline))) + if rv != C.SQLITE_OK { + return c.lastError() + } + return nil +} + +// SetTrace installs or removes the trace callback for the given database connection. +// It's not named 'RegisterTrace' because only one callback can be kept and called. +// Calling SetTrace a second time on same database connection +// overrides (cancels) any prior callback and all its settings: +// event mask, etc. +func (c *SQLiteConn) SetTrace(requested *TraceConfig) error { + connHandle := uintptr(unsafe.Pointer(c.db)) + + _, _ = popTraceMapping(connHandle) + + if requested == nil { + // The traceMap entry was deleted already by popTraceMapping(): + // can disable all events now, no need to watch for TraceClose. + err := c.setSQLiteTrace(0) + return err + } + + reqCopy := *requested + + // Disable potentially expensive operations + // if their result will not be used. We are doing this + // just in case the caller provided nonsensical input. + if reqCopy.EventMask&TraceStmt == 0 { + reqCopy.WantExpandedSQL = false + } + + addTraceMapping(connHandle, reqCopy) + + // The callback trampoline function does cleanup on Close event, + // regardless of the presence or absence of the user callback. + // Therefore it needs the Close event to be selected: + actualEventMask := reqCopy.EventMask | TraceClose + err := c.setSQLiteTrace(actualEventMask) + return err +} + +func (c *SQLiteConn) setSQLiteTrace(sqliteEventMask uint) error { + rv := C.sqlite3_trace_v2(c.db, + C.uint(sqliteEventMask), + (*[0]byte)(unsafe.Pointer(C.traceCallbackTrampoline)), + unsafe.Pointer(c.db)) // Fourth arg is same as first: we are + // passing the database connection handle as callback context. + + if rv != C.SQLITE_OK { + return c.lastError() + } + return nil +} diff --git a/vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go b/vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go new file mode 100644 index 0000000..c0a49e9 --- /dev/null +++ b/vendor/github.com/mattn/go-sqlite3/tracecallback_noimpl.go @@ -0,0 +1,9 @@ +// +build !trace + +package sqlite3 + +import "errors" + +func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { + return errors.New("This feature is not implemented") +} diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go index a554e79..d1cb607 100644 --- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -698,7 +698,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) if !rawMapVal.IsValid() { // Do a slower search by iterating over each key and // doing case-insensitive search. - for dataValKey, _ := range dataValKeys { + for dataValKey := range dataValKeys { mK, ok := dataValKey.Interface().(string) if !ok { // Not a string key @@ -746,7 +746,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { keys := make([]string, 0, len(dataValKeysUnused)) - for rawKey, _ := range dataValKeysUnused { + for rawKey := range dataValKeysUnused { keys = append(keys, rawKey.(string)) } sort.Strings(keys) @@ -761,7 +761,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) // Add the unused keys to the list of unused keys if we're tracking metadata if d.config.Metadata != nil { - for rawKey, _ := range dataValKeysUnused { + for rawKey := range dataValKeysUnused { key := rawKey.(string) if name != "" { key = fmt.Sprintf("%s.%s", name, key) diff --git a/vendor/github.com/pelletier/go-toml/keysparsing.go b/vendor/github.com/pelletier/go-toml/keysparsing.go index 4deed81..b67664f 100644 --- a/vendor/github.com/pelletier/go-toml/keysparsing.go +++ b/vendor/github.com/pelletier/go-toml/keysparsing.go @@ -12,6 +12,7 @@ func parseKey(key string) ([]string, error) { groups := []string{} var buffer bytes.Buffer inQuotes := false + wasInQuotes := false escapeNext := false ignoreSpace := true expectDot := false @@ -33,16 +34,27 @@ func parseKey(key string) ([]string, error) { escapeNext = true continue case '"': + if inQuotes { + groups = append(groups, buffer.String()) + buffer.Reset() + wasInQuotes = true + } inQuotes = !inQuotes expectDot = false case '.': if inQuotes { buffer.WriteRune(char) } else { - groups = append(groups, buffer.String()) - buffer.Reset() + if !wasInQuotes { + if buffer.Len() == 0 { + return nil, fmt.Errorf("empty key group") + } + groups = append(groups, buffer.String()) + buffer.Reset() + } ignoreSpace = true expectDot = false + wasInQuotes = false } case ' ': if inQuotes { diff --git a/vendor/github.com/pelletier/go-toml/toml.go b/vendor/github.com/pelletier/go-toml/toml.go index c0e1ad2..ad23fe8 100644 --- a/vendor/github.com/pelletier/go-toml/toml.go +++ b/vendor/github.com/pelletier/go-toml/toml.go @@ -222,9 +222,6 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) { func (t *TomlTree) createSubTree(keys []string, pos Position) error { subtree := t for _, intermediateKey := range keys { - if intermediateKey == "" { - return fmt.Errorf("empty intermediate table") - } nextTree, exists := subtree.values[intermediateKey] if !exists { tree := newTomlTree() diff --git a/vendor/github.com/pelletier/go-toml/tomltree_conversions.go b/vendor/github.com/pelletier/go-toml/tomltree_conversions.go index c9c6f95..bf9321b 100644 --- a/vendor/github.com/pelletier/go-toml/tomltree_conversions.go +++ b/vendor/github.com/pelletier/go-toml/tomltree_conversions.go @@ -45,8 +45,28 @@ func encodeTomlString(value string) string { func toTomlValue(item interface{}, indent int) string { tab := strings.Repeat(" ", indent) switch value := item.(type) { + case int: + return tab + strconv.FormatInt(int64(value), 10) + case int8: + return tab + strconv.FormatInt(int64(value), 10) + case int16: + return tab + strconv.FormatInt(int64(value), 10) + case int32: + return tab + strconv.FormatInt(int64(value), 10) case int64: return tab + strconv.FormatInt(value, 10) + case uint: + return tab + strconv.FormatUint(uint64(value), 10) + case uint8: + return tab + strconv.FormatUint(uint64(value), 10) + case uint16: + return tab + strconv.FormatUint(uint64(value), 10) + case uint32: + return tab + strconv.FormatUint(uint64(value), 10) + case uint64: + return tab + strconv.FormatUint(value, 10) + case float32: + return tab + strconv.FormatFloat(float64(value), 'f', -1, 32) case float64: return tab + strconv.FormatFloat(value, 'f', -1, 64) case string: @@ -64,8 +84,10 @@ func toTomlValue(item interface{}, indent int) string { result += toTomlValue(item, indent+2) + ",\n" } return result + tab + "]" + case nil: + return "" default: - panic(fmt.Sprintf("unsupported value type: %v", value)) + panic(fmt.Sprintf("unsupported value type %T: %v", value, value)) } } @@ -96,6 +118,20 @@ func (t *TomlTree) toToml(indent, keyspace string) string { case map[string]interface{}: sub := TreeFromMap(node) + if len(sub.Keys()) > 0 { + result += fmt.Sprintf("\n%s[%s]\n", indent, combinedKey) + } + result += sub.toToml(indent+" ", combinedKey) + case map[string]string: + sub := TreeFromMap(convertMapStringString(node)) + + if len(sub.Keys()) > 0 { + result += fmt.Sprintf("\n%s[%s]\n", indent, combinedKey) + } + result += sub.toToml(indent+" ", combinedKey) + case map[interface{}]interface{}: + sub := TreeFromMap(convertMapInterfaceInterface(node)) + if len(sub.Keys()) > 0 { result += fmt.Sprintf("\n%s[%s]\n", indent, combinedKey) } @@ -109,6 +145,22 @@ func (t *TomlTree) toToml(indent, keyspace string) string { return result } +func convertMapStringString(in map[string]string) map[string]interface{} { + result := make(map[string]interface{}, len(in)) + for k, v := range in { + result[k] = v + } + return result +} + +func convertMapInterfaceInterface(in map[interface{}]interface{}) map[string]interface{} { + result := make(map[string]interface{}, len(in)) + for k, v := range in { + result[k.(string)] = v + } + return result +} + // ToString is an alias for String func (t *TomlTree) ToString() string { return t.String() diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go index 1c9731a..842ee80 100644 --- a/vendor/github.com/pkg/errors/errors.go +++ b/vendor/github.com/pkg/errors/errors.go @@ -14,13 +14,18 @@ // Adding context to an error // // The errors.Wrap function returns a new error that adds context to the -// original error. For example +// original error by recording a stack trace at the point Wrap is called, +// and the supplied message. For example // // _, err := ioutil.ReadAll(r) // if err != nil { // return errors.Wrap(err, "read failed") // } // +// If additional control is required the errors.WithStack and errors.WithMessage +// functions destructure errors.Wrap into its component operations of annotating +// an error with a stack trace and an a message, respectively. +// // Retrieving the cause of an error // // Using errors.Wrap constructs a stack of errors, adding context to the @@ -134,6 +139,18 @@ func (f *fundamental) Format(s fmt.State, verb rune) { } } +// WithStack annotates err with a stack trace at the point WithStack was called. +// If err is nil, WithStack returns nil. +func WithStack(err error) error { + if err == nil { + return nil + } + return &withStack{ + err, + callers(), + } +} + type withStack struct { error *stack @@ -157,7 +174,8 @@ func (w *withStack) Format(s fmt.State, verb rune) { } } -// Wrap returns an error annotating err with message. +// Wrap returns an error annotating err with a stack trace +// at the point Wrap is called, and the supplied message. // If err is nil, Wrap returns nil. func Wrap(err error, message string) error { if err == nil { @@ -173,7 +191,8 @@ func Wrap(err error, message string) error { } } -// Wrapf returns an error annotating err with the format specifier. +// Wrapf returns an error annotating err with a stack trace +// at the point Wrapf is call, and the format specifier. // If err is nil, Wrapf returns nil. func Wrapf(err error, format string, args ...interface{}) error { if err == nil { @@ -189,6 +208,18 @@ func Wrapf(err error, format string, args ...interface{}) error { } } +// WithMessage annotates err with a new message. +// If err is nil, WithMessage returns nil. +func WithMessage(err error, message string) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: message, + } +} + type withMessage struct { cause error msg string diff --git a/vendor/github.com/pkg/sftp/client.go b/vendor/github.com/pkg/sftp/client.go index 41f1063..e95bbab 100644 --- a/vendor/github.com/pkg/sftp/client.go +++ b/vendor/github.com/pkg/sftp/client.go @@ -490,18 +490,13 @@ func (c *Client) Join(elem ...string) string { return path.Join(elem...) } // is not empty. func (c *Client) Remove(path string) error { err := c.removeFile(path) - switch err := err.(type) { - case *StatusError: + if err, ok := err.(*StatusError); ok { switch err.Code { // some servers, *cough* osx *cough*, return EPERM, not ENODIR. // serv-u returns ssh_FX_FILE_IS_A_DIRECTORY case ssh_FX_PERMISSION_DENIED, ssh_FX_FAILURE, ssh_FX_FILE_IS_A_DIRECTORY: return c.removeDirectory(path) - default: - return err } - default: - return err } return err } diff --git a/vendor/github.com/pkg/sftp/server_statvfs_linux.go b/vendor/github.com/pkg/sftp/server_statvfs_linux.go index 77fd1bf..43478e8 100644 --- a/vendor/github.com/pkg/sftp/server_statvfs_linux.go +++ b/vendor/github.com/pkg/sftp/server_statvfs_linux.go @@ -15,9 +15,8 @@ func statvfsFromStatfst(stat *syscall.Statfs_t) (*StatVFS, error) { Bavail: stat.Bavail, Files: stat.Files, Ffree: stat.Ffree, - Favail: stat.Ffree, // not sure how to calculate Favail - Fsid: uint64(uint64(stat.Fsid.X__val[1])<<32 | uint64(stat.Fsid.X__val[0])), // endianness? - Flag: uint64(stat.Flags), // assuming POSIX? + Favail: stat.Ffree, // not sure how to calculate Favail + Flag: uint64(stat.Flags), // assuming POSIX? Namemax: uint64(stat.Namelen), }, nil } diff --git a/vendor/github.com/spf13/afero/mem/file.go b/vendor/github.com/spf13/afero/mem/file.go index 9096ff0..3c1e09a 100644 --- a/vendor/github.com/spf13/afero/mem/file.go +++ b/vendor/github.com/spf13/afero/mem/file.go @@ -59,7 +59,9 @@ type FileData struct { modtime time.Time } -func (d FileData) Name() string { +func (d *FileData) Name() string { + d.Lock() + defer d.Unlock() return d.name } @@ -107,9 +109,7 @@ func (f *File) Close() error { } func (f *File) Name() string { - f.fileData.Lock() - defer f.fileData.Unlock() - return f.fileData.name + return f.fileData.Name() } func (f *File) Stat() (os.FileInfo, error) { diff --git a/vendor/github.com/spf13/cast/cast.go b/vendor/github.com/spf13/cast/cast.go index de5a686..6ca3e0e 100644 --- a/vendor/github.com/spf13/cast/cast.go +++ b/vendor/github.com/spf13/cast/cast.go @@ -67,6 +67,11 @@ func ToSlice(i interface{}) []interface{} { return v } +func ToBoolSlice(i interface{}) []bool { + v, _ := ToBoolSliceE(i) + return v +} + func ToStringSlice(i interface{}) []string { v, _ := ToStringSliceE(i) return v diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go index 863585b..23f59a1 100644 --- a/vendor/github.com/spf13/cast/caste.go +++ b/vendor/github.com/spf13/cast/caste.go @@ -12,14 +12,11 @@ import ( "strconv" "strings" "time" - - jww "github.com/spf13/jwalterweatherman" ) // ToTimeE casts an empty interface to time.Time. func ToTimeE(i interface{}) (tim time.Time, err error) { i = indirect(i) - jww.TRACE.Println("ToTimeE called on type:", reflect.TypeOf(i)) switch s := i.(type) { case time.Time: @@ -38,19 +35,22 @@ func ToTimeE(i interface{}) (tim time.Time, err error) { // ToDurationE casts an empty interface to time.Duration. func ToDurationE(i interface{}) (d time.Duration, err error) { i = indirect(i) - jww.TRACE.Println("ToDurationE called on type:", reflect.TypeOf(i)) switch s := i.(type) { case time.Duration: return s, nil - case int64: - d = time.Duration(s) + case int64, int32, int16, int8, int: + d = time.Duration(ToInt64(s)) return - case float64: - d = time.Duration(s) + case float32, float64: + d = time.Duration(ToFloat64(s)) return case string: - d, err = time.ParseDuration(s) + if strings.ContainsAny(s, "nsuµmh") { + d, err = time.ParseDuration(s) + } else { + d, err = time.ParseDuration(s + "ns") + } return default: err = fmt.Errorf("Unable to Cast %#v to Duration\n", i) @@ -60,8 +60,8 @@ func ToDurationE(i interface{}) (d time.Duration, err error) { // ToBoolE casts an empty interface to a bool. func ToBoolE(i interface{}) (bool, error) { + i = indirect(i) - jww.TRACE.Println("ToBoolE called on type:", reflect.TypeOf(i)) switch b := i.(type) { case bool: @@ -83,7 +83,6 @@ func ToBoolE(i interface{}) (bool, error) { // ToFloat64E casts an empty interface to a float64. func ToFloat64E(i interface{}) (float64, error) { i = indirect(i) - jww.TRACE.Println("ToFloat64E called on type:", reflect.TypeOf(i)) switch s := i.(type) { case float64: @@ -114,7 +113,6 @@ func ToFloat64E(i interface{}) (float64, error) { // ToInt64E casts an empty interface to an int64. func ToInt64E(i interface{}) (int64, error) { i = indirect(i) - jww.TRACE.Println("ToInt64E called on type:", reflect.TypeOf(i)) switch s := i.(type) { case int64: @@ -150,7 +148,6 @@ func ToInt64E(i interface{}) (int64, error) { // ToIntE casts an empty interface to an int. func ToIntE(i interface{}) (int, error) { i = indirect(i) - jww.TRACE.Println("ToIntE called on type:", reflect.TypeOf(i)) switch s := i.(type) { case int: @@ -225,7 +222,6 @@ func indirectToStringerOrError(a interface{}) interface{} { // ToStringE casts an empty interface to a string. func ToStringE(i interface{}) (string, error) { i = indirectToStringerOrError(i) - jww.TRACE.Println("ToStringE called on type:", reflect.TypeOf(i)) switch s := i.(type) { case string: @@ -263,7 +259,6 @@ func ToStringE(i interface{}) (string, error) { // ToStringMapStringE casts an empty interface to a map[string]string. func ToStringMapStringE(i interface{}) (map[string]string, error) { - jww.TRACE.Println("ToStringMapStringE called on type:", reflect.TypeOf(i)) var m = map[string]string{} @@ -292,7 +287,6 @@ func ToStringMapStringE(i interface{}) (map[string]string, error) { // ToStringMapStringSliceE casts an empty interface to a map[string][]string. func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { - jww.TRACE.Println("ToStringMapStringSliceE called on type:", reflect.TypeOf(i)) var m = map[string][]string{} @@ -310,7 +304,14 @@ func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { } case map[string]interface{}: for k, val := range v { - m[ToString(k)] = []string{ToString(val)} + switch vt := val.(type) { + case []interface{}: + m[ToString(k)] = ToStringSlice(vt) + case []string: + m[ToString(k)] = vt + default: + m[ToString(k)] = []string{ToString(val)} + } } return m, nil case map[interface{}][]string: @@ -348,7 +349,6 @@ func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { // ToStringMapBoolE casts an empty interface to a map[string]bool. func ToStringMapBoolE(i interface{}) (map[string]bool, error) { - jww.TRACE.Println("ToStringMapBoolE called on type:", reflect.TypeOf(i)) var m = map[string]bool{} @@ -372,7 +372,6 @@ func ToStringMapBoolE(i interface{}) (map[string]bool, error) { // ToStringMapE casts an empty interface to a map[string]interface{}. func ToStringMapE(i interface{}) (map[string]interface{}, error) { - jww.TRACE.Println("ToStringMapE called on type:", reflect.TypeOf(i)) var m = map[string]interface{}{} @@ -391,7 +390,6 @@ func ToStringMapE(i interface{}) (map[string]interface{}, error) { // ToSliceE casts an empty interface to a []interface{}. func ToSliceE(i interface{}) ([]interface{}, error) { - jww.TRACE.Println("ToSliceE called on type:", reflect.TypeOf(i)) var s []interface{} @@ -411,9 +409,38 @@ func ToSliceE(i interface{}) ([]interface{}, error) { } } +// ToBoolSliceE casts an empty interface to a []bool. +func ToBoolSliceE(i interface{}) ([]bool, error) { + + if i == nil { + return []bool{}, fmt.Errorf("Unable to Cast %#v to []bool", i) + } + + switch v := i.(type) { + case []bool: + return v, nil + } + + kind := reflect.TypeOf(i).Kind() + switch kind { + case reflect.Slice, reflect.Array: + s := reflect.ValueOf(i) + a := make([]bool, s.Len()) + for j := 0; j < s.Len(); j++ { + val, err := ToBoolE(s.Index(j).Interface()) + if err != nil { + return []bool{}, fmt.Errorf("Unable to Cast %#v to []bool", i) + } + a[j] = val + } + return a, nil + default: + return []bool{}, fmt.Errorf("Unable to Cast %#v to []bool", i) + } +} + // ToStringSliceE casts an empty interface to a []string. func ToStringSliceE(i interface{}) ([]string, error) { - jww.TRACE.Println("ToStringSliceE called on type:", reflect.TypeOf(i)) var a []string @@ -440,7 +467,6 @@ func ToStringSliceE(i interface{}) ([]string, error) { // ToIntSliceE casts an empty interface to a []int. func ToIntSliceE(i interface{}) ([]int, error) { - jww.TRACE.Println("ToIntSliceE called on type:", reflect.TypeOf(i)) if i == nil { return []int{}, fmt.Errorf("Unable to Cast %#v to []int", i) diff --git a/vendor/github.com/spf13/pflag/bool.go b/vendor/github.com/spf13/pflag/bool.go index d272e40..c4c5c0b 100644 --- a/vendor/github.com/spf13/pflag/bool.go +++ b/vendor/github.com/spf13/pflag/bool.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // optional interface to indicate boolean flags that can be // supplied without "=value" text @@ -30,7 +27,7 @@ func (b *boolValue) Type() string { return "bool" } -func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } +func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) } func (b *boolValue) IsBoolFlag() bool { return true } diff --git a/vendor/github.com/spf13/pflag/count.go b/vendor/github.com/spf13/pflag/count.go index 7b1f142..d22be41 100644 --- a/vendor/github.com/spf13/pflag/count.go +++ b/vendor/github.com/spf13/pflag/count.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- count Value type countValue int @@ -28,7 +25,7 @@ func (i *countValue) Type() string { return "count" } -func (i *countValue) String() string { return fmt.Sprintf("%v", *i) } +func (i *countValue) String() string { return strconv.Itoa(int(*i)) } func countConv(sval string) (interface{}, error) { i, err := strconv.Atoi(sval) diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go index eb143d7..4258f45 100644 --- a/vendor/github.com/spf13/pflag/flag.go +++ b/vendor/github.com/spf13/pflag/flag.go @@ -416,7 +416,7 @@ func Set(name, value string) error { // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { usages := f.FlagUsages() - fmt.Fprintf(f.out(), "%s", usages) + fmt.Fprint(f.out(), usages) } // defaultIsZeroValue returns true if the default value for this flag represents @@ -434,10 +434,20 @@ func (f *Flag) defaultIsZeroValue() bool { return f.DefValue == "" case *ipValue, *ipMaskValue, *ipNetValue: return f.DefValue == "" - case *intSliceValue, *stringSliceValue: + case *intSliceValue, *stringSliceValue, *stringArrayValue: return f.DefValue == "[]" default: - return true + switch f.Value.String() { + case "false": + return true + case "": + return true + case "": + return true + case "0": + return true + } + return false } } diff --git a/vendor/github.com/spf13/pflag/float32.go b/vendor/github.com/spf13/pflag/float32.go index 7683fae..a243f81 100644 --- a/vendor/github.com/spf13/pflag/float32.go +++ b/vendor/github.com/spf13/pflag/float32.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- float32 Value type float32Value float32 @@ -23,7 +20,7 @@ func (f *float32Value) Type() string { return "float32" } -func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) } +func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) } func float32Conv(sval string) (interface{}, error) { v, err := strconv.ParseFloat(sval, 32) diff --git a/vendor/github.com/spf13/pflag/float64.go b/vendor/github.com/spf13/pflag/float64.go index 50fbf8c..04b5492 100644 --- a/vendor/github.com/spf13/pflag/float64.go +++ b/vendor/github.com/spf13/pflag/float64.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- float64 Value type float64Value float64 @@ -23,7 +20,7 @@ func (f *float64Value) Type() string { return "float64" } -func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } +func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) } func float64Conv(sval string) (interface{}, error) { return strconv.ParseFloat(sval, 64) diff --git a/vendor/github.com/spf13/pflag/int.go b/vendor/github.com/spf13/pflag/int.go index b656036..1474b89 100644 --- a/vendor/github.com/spf13/pflag/int.go +++ b/vendor/github.com/spf13/pflag/int.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- int Value type intValue int @@ -23,7 +20,7 @@ func (i *intValue) Type() string { return "int" } -func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } +func (i *intValue) String() string { return strconv.Itoa(int(*i)) } func intConv(sval string) (interface{}, error) { return strconv.Atoi(sval) diff --git a/vendor/github.com/spf13/pflag/int32.go b/vendor/github.com/spf13/pflag/int32.go index 41659a9..9b95944 100644 --- a/vendor/github.com/spf13/pflag/int32.go +++ b/vendor/github.com/spf13/pflag/int32.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- int32 Value type int32Value int32 @@ -23,7 +20,7 @@ func (i *int32Value) Type() string { return "int32" } -func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int32Conv(sval string) (interface{}, error) { v, err := strconv.ParseInt(sval, 0, 32) diff --git a/vendor/github.com/spf13/pflag/int64.go b/vendor/github.com/spf13/pflag/int64.go index 6e67e38..0026d78 100644 --- a/vendor/github.com/spf13/pflag/int64.go +++ b/vendor/github.com/spf13/pflag/int64.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- int64 Value type int64Value int64 @@ -23,7 +20,7 @@ func (i *int64Value) Type() string { return "int64" } -func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int64Conv(sval string) (interface{}, error) { return strconv.ParseInt(sval, 0, 64) diff --git a/vendor/github.com/spf13/pflag/int8.go b/vendor/github.com/spf13/pflag/int8.go index 400db21..4da9222 100644 --- a/vendor/github.com/spf13/pflag/int8.go +++ b/vendor/github.com/spf13/pflag/int8.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- int8 Value type int8Value int8 @@ -23,7 +20,7 @@ func (i *int8Value) Type() string { return "int8" } -func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int8Conv(sval string) (interface{}, error) { v, err := strconv.ParseInt(sval, 0, 8) diff --git a/vendor/github.com/spf13/pflag/string.go b/vendor/github.com/spf13/pflag/string.go index e296136..04e0a26 100644 --- a/vendor/github.com/spf13/pflag/string.go +++ b/vendor/github.com/spf13/pflag/string.go @@ -1,7 +1,5 @@ package pflag -import "fmt" - // -- string Value type stringValue string @@ -18,7 +16,7 @@ func (s *stringValue) Type() string { return "string" } -func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } +func (s *stringValue) String() string { return string(*s) } func stringConv(sval string) (interface{}, error) { return sval, nil diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go new file mode 100644 index 0000000..f320f2e --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_array.go @@ -0,0 +1,110 @@ +package pflag + +import ( + "fmt" + "strings" +) + +var _ = fmt.Fprint + +// -- stringArray Value +type stringArrayValue struct { + value *[]string + changed bool +} + +func newStringArrayValue(val []string, p *[]string) *stringArrayValue { + ssv := new(stringArrayValue) + ssv.value = p + *ssv.value = val + return ssv +} + +func (s *stringArrayValue) Set(val string) error { + if !s.changed { + *s.value = []string{val} + s.changed = true + } else { + *s.value = append(*s.value, val) + } + return nil +} + +func (s *stringArrayValue) Type() string { + return "stringArray" +} + +func (s *stringArrayValue) String() string { + str, _ := writeAsCSV(*s.value) + return "[" + str + "]" +} + +func stringArrayConv(sval string) (interface{}, error) { + sval = strings.Trim(sval, "[]") + // An empty string would cause a array with one (empty) string + if len(sval) == 0 { + return []string{}, nil + } + return readAsCSV(sval) +} + +// GetStringArray return the []string value of a flag with the given name +func (f *FlagSet) GetStringArray(name string) ([]string, error) { + val, err := f.getFlagType(name, "stringArray", stringArrayConv) + if err != nil { + return []string{}, err + } + return val.([]string), nil +} + +// StringArrayVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a []string variable in which to store the values of the multiple flags. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) { + f.VarP(newStringArrayValue(value, p), name, "", usage) +} + +// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) { + f.VarP(newStringArrayValue(value, p), name, shorthand, usage) +} + +// StringArrayVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a []string variable in which to store the value of the flag. +// The value of each argument will not try to be separated by comma +func StringArrayVar(p *[]string, name string, value []string, usage string) { + CommandLine.VarP(newStringArrayValue(value, p), name, "", usage) +} + +// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash. +func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) { + CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage) +} + +// StringArray defines a string flag with specified name, default value, and usage string. +// The return value is the address of a []string variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string { + p := []string{} + f.StringArrayVarP(&p, name, "", value, usage) + return &p +} + +// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string { + p := []string{} + f.StringArrayVarP(&p, name, shorthand, value, usage) + return &p +} + +// StringArray defines a string flag with specified name, default value, and usage string. +// The return value is the address of a []string variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func StringArray(name string, value []string, usage string) *[]string { + return CommandLine.StringArrayP(name, "", value, usage) +} + +// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash. +func StringArrayP(name, shorthand string, value []string, usage string) *[]string { + return CommandLine.StringArrayP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/string_slice.go b/vendor/github.com/spf13/pflag/string_slice.go index 927a440..7829cfa 100644 --- a/vendor/github.com/spf13/pflag/string_slice.go +++ b/vendor/github.com/spf13/pflag/string_slice.go @@ -31,6 +31,17 @@ func readAsCSV(val string) ([]string, error) { return csvReader.Read() } +func writeAsCSV(vals []string) (string, error) { + b := &bytes.Buffer{} + w := csv.NewWriter(b) + err := w.Write(vals) + if err != nil { + return "", err + } + w.Flush() + return strings.TrimSuffix(b.String(), fmt.Sprintln()), nil +} + func (s *stringSliceValue) Set(val string) error { v, err := readAsCSV(val) if err != nil { @@ -50,15 +61,12 @@ func (s *stringSliceValue) Type() string { } func (s *stringSliceValue) String() string { - b := &bytes.Buffer{} - w := csv.NewWriter(b) - w.Write(*s.value) - w.Flush() - return "[" + strings.TrimSuffix(b.String(), fmt.Sprintln()) + "]" + str, _ := writeAsCSV(*s.value) + return "[" + str + "]" } func stringSliceConv(sval string) (interface{}, error) { - sval = strings.Trim(sval, "[]") + sval = sval[1 : len(sval)-1] // An empty string would cause a slice with one (empty) string if len(sval) == 0 { return []string{}, nil diff --git a/vendor/github.com/spf13/pflag/uint.go b/vendor/github.com/spf13/pflag/uint.go index e142b49..dcbc2b7 100644 --- a/vendor/github.com/spf13/pflag/uint.go +++ b/vendor/github.com/spf13/pflag/uint.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- uint Value type uintValue uint @@ -23,7 +20,7 @@ func (i *uintValue) Type() string { return "uint" } -func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } +func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) } func uintConv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 0) diff --git a/vendor/github.com/spf13/pflag/uint16.go b/vendor/github.com/spf13/pflag/uint16.go index 5c96c19..7e9914e 100644 --- a/vendor/github.com/spf13/pflag/uint16.go +++ b/vendor/github.com/spf13/pflag/uint16.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- uint16 value type uint16Value uint16 @@ -12,7 +9,7 @@ func newUint16Value(val uint16, p *uint16) *uint16Value { *p = val return (*uint16Value)(p) } -func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) } + func (i *uint16Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 16) *i = uint16Value(v) @@ -23,6 +20,8 @@ func (i *uint16Value) Type() string { return "uint16" } +func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) } + func uint16Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 16) if err != nil { diff --git a/vendor/github.com/spf13/pflag/uint32.go b/vendor/github.com/spf13/pflag/uint32.go index 294fcaa..d802453 100644 --- a/vendor/github.com/spf13/pflag/uint32.go +++ b/vendor/github.com/spf13/pflag/uint32.go @@ -1,18 +1,15 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" -// -- uint16 value +// -- uint32 value type uint32Value uint32 func newUint32Value(val uint32, p *uint32) *uint32Value { *p = val return (*uint32Value)(p) } -func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) } + func (i *uint32Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 32) *i = uint32Value(v) @@ -23,6 +20,8 @@ func (i *uint32Value) Type() string { return "uint32" } +func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) } + func uint32Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 32) if err != nil { diff --git a/vendor/github.com/spf13/pflag/uint64.go b/vendor/github.com/spf13/pflag/uint64.go index c681885..f62240f 100644 --- a/vendor/github.com/spf13/pflag/uint64.go +++ b/vendor/github.com/spf13/pflag/uint64.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- uint64 Value type uint64Value uint64 @@ -23,7 +20,7 @@ func (i *uint64Value) Type() string { return "uint64" } -func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) } func uint64Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 64) diff --git a/vendor/github.com/spf13/pflag/uint8.go b/vendor/github.com/spf13/pflag/uint8.go index 26db418..bb0e83c 100644 --- a/vendor/github.com/spf13/pflag/uint8.go +++ b/vendor/github.com/spf13/pflag/uint8.go @@ -1,9 +1,6 @@ package pflag -import ( - "fmt" - "strconv" -) +import "strconv" // -- uint8 Value type uint8Value uint8 @@ -23,7 +20,7 @@ func (i *uint8Value) Type() string { return "uint8" } -func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) } func uint8Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 8) diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md index cf17560..f4e72f8 100644 --- a/vendor/github.com/spf13/viper/README.md +++ b/vendor/github.com/spf13/viper/README.md @@ -458,16 +458,17 @@ Viper can access a nested field by passing a `.` delimited path of keys: GetString("datastore.metric.host") // (returns "127.0.0.1") ``` -This obeys the precedence rules established above; the search for the root key -(in this example, `datastore`) will cascade through the remaining configuration -registries until found. The search for the sub-keys (`metric` and `host`), -however, will not. +This obeys the precedence rules established above; the search for the path +will cascade through the remaining configuration registries until found. -For example, if the `metric` key was not defined in the configuration loaded -from file, but was defined in the defaults, Viper would return the zero value. +For example, given this configuration file, both `datastore.metric.host` and +`datastore.metric.port` are already defined (and may be overridden). If in addition +`datastore.metric.protocol` was defined in the defaults, Viper would also find it. -On the other hand, if the primary key was not defined, Viper would go through -the remaining registries looking for it. +However, if `datastore.metric` was overridden (by a flag, an environment variable, +the `Set()` method, …) with an immediate value, then all sub-keys of +`datastore.metric` become undefined, they are “shadowed” by the higher-priority +configuration level. Lastly, if there exists a key that matches the delimited key path, its value will be returned instead. E.g. @@ -491,7 +492,7 @@ will be returned instead. E.g. } } -GetString("datastore.metric.host") //returns "0.0.0.0" +GetString("datastore.metric.host") // returns "0.0.0.0" ``` ### Extract sub-tree diff --git a/vendor/github.com/spf13/viper/util.go b/vendor/github.com/spf13/viper/util.go index fe6cb45..b0903fb 100644 --- a/vendor/github.com/spf13/viper/util.go +++ b/vendor/github.com/spf13/viper/util.go @@ -29,12 +29,12 @@ import ( "gopkg.in/yaml.v2" ) -// Denotes failing to parse configuration file. +// ConfigParseError denotes failing to parse configuration file. type ConfigParseError struct { err error } -// Returns the formatted configuration error. +// Error returns the formatted configuration error. func (pe ConfigParseError) Error() string { return fmt.Sprintf("While parsing config: %s", pe.err.Error()) } @@ -45,6 +45,10 @@ func insensitiviseMap(m map[string]interface{}) { if key != lower { delete(m, key) m[lower] = val + if m2, ok := val.(map[string]interface{}); ok { + // nested map: recursively insensitivise + insensitiviseMap(m2) + } } } } @@ -68,10 +72,10 @@ func absPathify(inPath string) string { p, err := filepath.Abs(inPath) if err == nil { return filepath.Clean(p) - } else { - jww.ERROR.Println("Couldn't discover absolute path") - jww.ERROR.Println(err) } + + jww.ERROR.Println("Couldn't discover absolute path") + jww.ERROR.Println(err) return "" } @@ -107,29 +111,6 @@ func userHomeDir() string { return os.Getenv("HOME") } -func findCWD() (string, error) { - serverFile, err := filepath.Abs(os.Args[0]) - - if err != nil { - return "", fmt.Errorf("Can't get absolute path for executable: %v", err) - } - - path := filepath.Dir(serverFile) - realFile, err := filepath.EvalSymlinks(serverFile) - - if err != nil { - if _, err = os.Stat(serverFile + ".exe"); err == nil { - realFile = filepath.Clean(serverFile + ".exe") - } - } - - if err == nil && realFile != serverFile { - path = filepath.Dir(realFile) - } - - return path, nil -} - func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType string) error { buf := new(bytes.Buffer) buf.ReadFrom(in) @@ -172,7 +153,12 @@ func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType s } for _, key := range p.Keys() { value, _ := p.Get(key) - c[key] = value + // recursively build nested maps + path := strings.Split(key, ".") + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(c, path[0:len(path)-1]) + // set innermost value + deepestMap[lastKey] = value } } @@ -222,3 +208,34 @@ func parseSizeInBytes(sizeStr string) uint { return safeMul(uint(size), multiplier) } + +// deepSearch scans deep maps, following the key indexes listed in the +// sequence "path". +// The last value is expected to be another map, and is returned. +// +// In case intermediate keys do not exist, or map to a non-map value, +// a new map is created and inserted, and the search continues from there: +// the initial map "m" may be modified! +func deepSearch(m map[string]interface{}, path []string) map[string]interface{} { + for _, k := range path { + m2, ok := m[k] + if !ok { + // intermediate key does not exist + // => create it and continue from there + m3 := make(map[string]interface{}) + m[k] = m3 + m = m3 + continue + } + m3, ok := m2.(map[string]interface{}) + if !ok { + // intermediate key is a value + // => replace with a new map + m3 = make(map[string]interface{}) + m[k] = m3 + } + // continue search from here + m = m3 + } + return m +} diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go index f17790e..8f27849 100644 --- a/vendor/github.com/spf13/viper/viper.go +++ b/vendor/github.com/spf13/viper/viper.go @@ -52,40 +52,40 @@ type remoteConfigFactory interface { // RemoteConfig is optional, see the remote package var RemoteConfig remoteConfigFactory -// Denotes encountering an unsupported +// UnsupportedConfigError denotes encountering an unsupported // configuration filetype. type UnsupportedConfigError string -// Returns the formatted configuration error. +// Error returns the formatted configuration error. func (str UnsupportedConfigError) Error() string { return fmt.Sprintf("Unsupported Config Type %q", string(str)) } -// Denotes encountering an unsupported remote +// UnsupportedRemoteProviderError denotes encountering an unsupported remote // provider. Currently only etcd and Consul are // supported. type UnsupportedRemoteProviderError string -// Returns the formatted remote provider error. +// Error returns the formatted remote provider error. func (str UnsupportedRemoteProviderError) Error() string { return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str)) } -// Denotes encountering an error while trying to +// RemoteConfigError denotes encountering an error while trying to // pull the configuration from the remote provider. type RemoteConfigError string -// Returns the formatted remote provider error +// Error returns the formatted remote provider error func (rce RemoteConfigError) Error() string { return fmt.Sprintf("Remote Configurations Error: %s", string(rce)) } -// Denotes failing to find configuration file. +// ConfigFileNotFoundError denotes failing to find configuration file. type ConfigFileNotFoundError struct { name, locations string } -// Returns the formatted configuration error. +// Error returns the formatted configuration error. func (fnfe ConfigFileNotFoundError) Error() string { return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations) } @@ -107,11 +107,11 @@ func (fnfe ConfigFileNotFoundError) Error() string { // Defaults : { // "secret": "", // "user": "default", -// "endpoint": "https://localhost" +// "endpoint": "https://localhost" // } // Config : { // "user": "root" -// "secret": "defaultsecret" +// "secret": "defaultsecret" // } // Env : { // "secret": "somesecretkey" @@ -159,7 +159,7 @@ type Viper struct { onConfigChange func(fsnotify.Event) } -// Returns an initialized Viper instance. +// New returns an initialized Viper instance. func New() *Viper { v := new(Viper) v.keyDelim = "." @@ -220,11 +220,11 @@ type RemoteProvider interface { SecretKeyring() string } -// Universally supported extensions. -var SupportedExts []string = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} +// SupportedExts are universally supported extensions. +var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} -// Universally supported remote providers. -var SupportedRemoteProviders []string = []string{"etcd", "consul"} +// SupportedRemoteProviders are universally supported remote providers. +var SupportedRemoteProviders = []string{"etcd", "consul"} func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) } func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) { @@ -270,7 +270,7 @@ func (v *Viper) WatchConfig() { }() } -// Explicitly define the path, name and extension of the config file +// SetConfigFile explicitly defines the path, name and extension of the config file // Viper will use this and not check any of the config paths func SetConfigFile(in string) { v.SetConfigFile(in) } func (v *Viper) SetConfigFile(in string) { @@ -279,7 +279,7 @@ func (v *Viper) SetConfigFile(in string) { } } -// Define a prefix that ENVIRONMENT variables will use. +// SetEnvPrefix defines a prefix that ENVIRONMENT variables will use. // E.g. if your prefix is "spf", the env registry // will look for env. variables that start with "SPF_" func SetEnvPrefix(in string) { v.SetEnvPrefix(in) } @@ -301,7 +301,7 @@ func (v *Viper) mergeWithEnvPrefix(in string) string { // rewriting keys many things, Ex: Get('someKey') -> some_key // (cammel case to snake case for JSON keys perhaps) -// getEnv s a wrapper around os.Getenv which replaces characters in the original +// getEnv is a wrapper around os.Getenv which replaces characters in the original // key. This allows env vars which have different keys then the config object // keys func (v *Viper) getEnv(key string) string { @@ -311,11 +311,11 @@ func (v *Viper) getEnv(key string) string { return os.Getenv(key) } -// Return the file used to populate the config registry +// ConfigFileUsed returns the file used to populate the config registry func ConfigFileUsed() string { return v.ConfigFileUsed() } func (v *Viper) ConfigFileUsed() string { return v.configFile } -// Add a path for Viper to search for the config file in. +// AddConfigPath adds a path for Viper to search for the config file in. // Can be called multiple times to define multiple search paths. func AddConfigPath(in string) { v.AddConfigPath(in) } func (v *Viper) AddConfigPath(in string) { @@ -399,8 +399,9 @@ func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool { return false } +// searchMap recursively searches for a value for path in source map. +// Returns nil if not found. func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} { - if len(path) == 0 { return source } @@ -424,11 +425,133 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac // if the type of `next` is the same as the type being asserted return v.searchMap(next.(map[string]interface{}), path[1:]) default: - return next + if len(path) == 1 { + return next + } + // got a value but nested key expected, return "nil" for not found + return nil + } + } + return nil +} + +// searchMapWithPathPrefixes recursively searches for a value for path in source map. +// +// While searchMap() considers each path element as a single map key, this +// function searches for, and prioritizes, merged path elements. +// e.g., if in the source, "foo" is defined with a sub-key "bar", and "foo.bar" +// is also defined, this latter value is returned for path ["foo", "bar"]. +// +// This should be useful only at config level (other maps may not contain dots +// in their keys). +func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []string) interface{} { + if len(path) == 0 { + return source + } + + // search for path prefixes, starting from the longest one + for i := len(path); i > 0; i-- { + prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim)) + + var ok bool + var next interface{} + for k, v := range source { + if strings.ToLower(k) == prefixKey { + ok = true + next = v + break + } + } + + if ok { + var val interface{} + switch next.(type) { + case map[interface{}]interface{}: + val = v.searchMapWithPathPrefixes(cast.ToStringMap(next), path[i:]) + case map[string]interface{}: + // Type assertion is safe here since it is only reached + // if the type of `next` is the same as the type being asserted + val = v.searchMapWithPathPrefixes(next.(map[string]interface{}), path[i:]) + default: + if len(path) == i { + val = next + } + // got a value but nested key expected, do nothing and look for next prefix + } + if val != nil { + return val + } + } + } + + // not found + return nil +} + +// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere +// on its path in the map. +// e.g., if "foo.bar" has a value in the given map, it “shadows” +// "foo.bar.baz" in a lower-priority map +func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string { + var parentVal interface{} + for i := 1; i < len(path); i++ { + parentVal = v.searchMap(m, path[0:i]) + if parentVal == nil { + // not found, no need to add more path elements + return "" + } + switch parentVal.(type) { + case map[interface{}]interface{}: + continue + case map[string]interface{}: + continue + default: + // parentVal is a regular value which shadows "path" + return strings.Join(path[0:i], v.keyDelim) + } + } + return "" +} + +// isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere +// in a sub-path of the map. +// e.g., if "foo.bar" has a value in the given map, it “shadows” +// "foo.bar.baz" in a lower-priority map +func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string { + // unify input map + var m map[string]interface{} + switch mi.(type) { + case map[string]string, map[string]FlagValue: + m = cast.ToStringMap(mi) + default: + return "" + } + + // scan paths + var parentKey string + for i := 1; i < len(path); i++ { + parentKey = strings.Join(path[0:i], v.keyDelim) + if _, ok := m[parentKey]; ok { + return parentKey + } + } + return "" +} + +// isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere +// in the environment, when automatic env is on. +// e.g., if "foo.bar" has a value in the environment, it “shadows” +// "foo.bar.baz" in a lower-priority map +func (v *Viper) isPathShadowedInAutoEnv(path []string) string { + var parentKey string + var val string + for i := 1; i < len(path); i++ { + parentKey = strings.Join(path[0:i], v.keyDelim) + if val = v.getEnv(v.mergeWithEnvPrefix(parentKey)); val != "" { + return parentKey } - } else { - return nil } + return "" } // SetTypeByDefaultValue enables or disables the inference of a key value's @@ -455,8 +578,7 @@ func GetViper() *Viper { return v } -// Viper is essentially repository for configurations -// Get can retrieve any value given the key to use +// Get can retrieve any value given the key to use. // Get has the behavior of returning the value associated with the first // place from where it is set. Viper will check in the following order: // override, flag, env, config file, key/value store, default @@ -464,49 +586,18 @@ func GetViper() *Viper { // Get returns an interface. For a specific value use one of the Get____ methods. func Get(key string) interface{} { return v.Get(key) } func (v *Viper) Get(key string) interface{} { - path := strings.Split(key, v.keyDelim) - lcaseKey := strings.ToLower(key) val := v.find(lcaseKey) - - if val == nil { - source := v.find(strings.ToLower(path[0])) - if source != nil { - if reflect.TypeOf(source).Kind() == reflect.Map { - val = v.searchMap(cast.ToStringMap(source), path[1:]) - } - } - } - - // if no other value is returned and a flag does exist for the value, - // get the flag's value even if the flag's value has not changed - if val == nil { - if flag, exists := v.pflags[lcaseKey]; exists { - jww.TRACE.Println(key, "get pflag default", val) - switch flag.ValueType() { - case "int", "int8", "int16", "int32", "int64": - val = cast.ToInt(flag.ValueString()) - case "bool": - val = cast.ToBool(flag.ValueString()) - default: - val = flag.ValueString() - } - } - } - if val == nil { return nil } - var valType interface{} - if !v.typeByDefValue { - valType = val - } else { - defVal, defExists := v.defaults[lcaseKey] - if defExists { + valType := val + if v.typeByDefValue { + path := strings.Split(lcaseKey, v.keyDelim) + defVal := v.searchMap(v.defaults, path) + if defVal != nil { valType = defVal - } else { - valType = val } } @@ -529,86 +620,89 @@ func (v *Viper) Get(key string) interface{} { return val } -// Returns new Viper instance representing a sub tree of this instance +// Sub returns new Viper instance representing a sub tree of this instance. func Sub(key string) *Viper { return v.Sub(key) } func (v *Viper) Sub(key string) *Viper { subv := New() data := v.Get(key) + if data == nil { + return nil + } + if reflect.TypeOf(data).Kind() == reflect.Map { subv.config = cast.ToStringMap(data) return subv - } else { - return nil } + return nil } -// Returns the value associated with the key as a string +// GetString returns the value associated with the key as a string. func GetString(key string) string { return v.GetString(key) } func (v *Viper) GetString(key string) string { return cast.ToString(v.Get(key)) } -// Returns the value associated with the key as a boolean +// GetBool returns the value associated with the key as a boolean. func GetBool(key string) bool { return v.GetBool(key) } func (v *Viper) GetBool(key string) bool { return cast.ToBool(v.Get(key)) } -// Returns the value associated with the key as an integer +// GetInt returns the value associated with the key as an integer. func GetInt(key string) int { return v.GetInt(key) } func (v *Viper) GetInt(key string) int { return cast.ToInt(v.Get(key)) } -// Returns the value associated with the key as an integer +// GetInt64 returns the value associated with the key as an integer. func GetInt64(key string) int64 { return v.GetInt64(key) } func (v *Viper) GetInt64(key string) int64 { return cast.ToInt64(v.Get(key)) } -// Returns the value associated with the key as a float64 +// GetFloat64 returns the value associated with the key as a float64. func GetFloat64(key string) float64 { return v.GetFloat64(key) } func (v *Viper) GetFloat64(key string) float64 { return cast.ToFloat64(v.Get(key)) } -// Returns the value associated with the key as time +// GetTime returns the value associated with the key as time. func GetTime(key string) time.Time { return v.GetTime(key) } func (v *Viper) GetTime(key string) time.Time { return cast.ToTime(v.Get(key)) } -// Returns the value associated with the key as a duration +// GetDuration returns the value associated with the key as a duration. func GetDuration(key string) time.Duration { return v.GetDuration(key) } func (v *Viper) GetDuration(key string) time.Duration { return cast.ToDuration(v.Get(key)) } -// Returns the value associated with the key as a slice of strings +// GetStringSlice returns the value associated with the key as a slice of strings. func GetStringSlice(key string) []string { return v.GetStringSlice(key) } func (v *Viper) GetStringSlice(key string) []string { return cast.ToStringSlice(v.Get(key)) } -// Returns the value associated with the key as a map of interfaces +// GetStringMap returns the value associated with the key as a map of interfaces. func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) } func (v *Viper) GetStringMap(key string) map[string]interface{} { return cast.ToStringMap(v.Get(key)) } -// Returns the value associated with the key as a map of strings +// GetStringMapString returns the value associated with the key as a map of strings. func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) } func (v *Viper) GetStringMapString(key string) map[string]string { return cast.ToStringMapString(v.Get(key)) } -// Returns the value associated with the key as a map to a slice of strings. +// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings. func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) } func (v *Viper) GetStringMapStringSlice(key string) map[string][]string { return cast.ToStringMapStringSlice(v.Get(key)) } -// Returns the size of the value associated with the given key +// GetSizeInBytes returns the size of the value associated with the given key // in bytes. func GetSizeInBytes(key string) uint { return v.GetSizeInBytes(key) } func (v *Viper) GetSizeInBytes(key string) uint { @@ -616,17 +710,17 @@ func (v *Viper) GetSizeInBytes(key string) uint { return parseSizeInBytes(sizeStr) } -// Takes a single key and unmarshals it into a Struct +// UnmarshalKey takes a single key and unmarshals it into a Struct. func UnmarshalKey(key string, rawVal interface{}) error { return v.UnmarshalKey(key, rawVal) } func (v *Viper) UnmarshalKey(key string, rawVal interface{}) error { return mapstructure.Decode(v.Get(key), rawVal) } -// Unmarshals the config into a Struct. Make sure that the tags +// Unmarshal unmarshals the config into a Struct. Make sure that the tags // on the fields of the structure are properly set. func Unmarshal(rawVal interface{}) error { return v.Unmarshal(rawVal) } func (v *Viper) Unmarshal(rawVal interface{}) error { - err := mapstructure.WeakDecode(v.AllSettings(), rawVal) + err := decode(v.AllSettings(), defaultDecoderConfig(rawVal)) if err != nil { return err @@ -637,16 +731,19 @@ func (v *Viper) Unmarshal(rawVal interface{}) error { return nil } -// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality -// while erroring on non existing vals in the destination struct -func weakDecodeExact(input, output interface{}) error { - config := &mapstructure.DecoderConfig{ - ErrorUnused: true, +// defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot +// of time.Duration values +func defaultDecoderConfig(output interface{}) *mapstructure.DecoderConfig { + return &mapstructure.DecoderConfig{ Metadata: nil, Result: output, WeaklyTypedInput: true, + DecodeHook: mapstructure.StringToTimeDurationHookFunc(), } +} +// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality +func decode(input interface{}, config *mapstructure.DecoderConfig) error { decoder, err := mapstructure.NewDecoder(config) if err != nil { return err @@ -654,10 +751,13 @@ func weakDecodeExact(input, output interface{}) error { return decoder.Decode(input) } -// Unmarshals the config into a Struct, erroring if a field is non-existant -// in the destination struct +// UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent +// in the destination struct. func (v *Viper) UnmarshalExact(rawVal interface{}) error { - err := weakDecodeExact(v.AllSettings(), rawVal) + config := defaultDecoderConfig(rawVal) + config.ErrorUnused = true + + err := decode(v.AllSettings(), config) if err != nil { return err @@ -668,27 +768,27 @@ func (v *Viper) UnmarshalExact(rawVal interface{}) error { return nil } -// Bind a full flag set to the configuration, using each flag's long +// BindPFlags binds a full flag set to the configuration, using each flag's long // name as the config key. -func BindPFlags(flags *pflag.FlagSet) (err error) { return v.BindPFlags(flags) } -func (v *Viper) BindPFlags(flags *pflag.FlagSet) (err error) { +func BindPFlags(flags *pflag.FlagSet) error { return v.BindPFlags(flags) } +func (v *Viper) BindPFlags(flags *pflag.FlagSet) error { return v.BindFlagValues(pflagValueSet{flags}) } -// Bind a specific key to a pflag (as used by cobra). +// BindPFlag binds a specific key to a pflag (as used by cobra). // Example (where serverCmd is a Cobra instance): // // serverCmd.Flags().Int("port", 1138, "Port to run Application server on") // Viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) // -func BindPFlag(key string, flag *pflag.Flag) (err error) { return v.BindPFlag(key, flag) } -func (v *Viper) BindPFlag(key string, flag *pflag.Flag) (err error) { +func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) } +func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error { return v.BindFlagValue(key, pflagValue{flag}) } -// Bind a full FlagValue set to the configuration, using each flag's long +// BindFlagValues binds a full FlagValue set to the configuration, using each flag's long // name as the config key. -func BindFlagValues(flags FlagValueSet) (err error) { return v.BindFlagValues(flags) } +func BindFlagValues(flags FlagValueSet) error { return v.BindFlagValues(flags) } func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) { flags.VisitAll(func(flag FlagValue) { if err = v.BindFlagValue(flag.Name(), flag); err != nil { @@ -698,14 +798,14 @@ func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) { return nil } -// Bind a specific key to a FlagValue. +// BindFlagValue binds a specific key to a FlagValue. // Example(where serverCmd is a Cobra instance): // // serverCmd.Flags().Int("port", 1138, "Port to run Application server on") // Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port")) // -func BindFlagValue(key string, flag FlagValue) (err error) { return v.BindFlagValue(key, flag) } -func (v *Viper) BindFlagValue(key string, flag FlagValue) (err error) { +func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) } +func (v *Viper) BindFlagValue(key string, flag FlagValue) error { if flag == nil { return fmt.Errorf("flag for %q is nil", key) } @@ -713,12 +813,12 @@ func (v *Viper) BindFlagValue(key string, flag FlagValue) (err error) { return nil } -// Binds a Viper key to a ENV variable -// ENV variables are case sensitive +// BindEnv binds a Viper key to a ENV variable. +// ENV variables are case sensitive. // If only a key is provided, it will use the env key matching the key, uppercased. // EnvPrefix will be used when set when env name is not provided. -func BindEnv(input ...string) (err error) { return v.BindEnv(input...) } -func (v *Viper) BindEnv(input ...string) (err error) { +func BindEnv(input ...string) error { return v.BindEnv(input...) } +func (v *Viper) BindEnv(input ...string) error { var key, envkey string if len(input) == 0 { return fmt.Errorf("BindEnv missing key to bind to") @@ -737,113 +837,130 @@ func (v *Viper) BindEnv(input ...string) (err error) { return nil } -// Given a key, find the value +// Given a key, find the value. // Viper will check in the following order: -// flag, env, config file, key/value store, default -// Viper will check to see if an alias exists first +// flag, env, config file, key/value store, default. +// Viper will check to see if an alias exists first. func (v *Viper) find(key string) interface{} { var val interface{} var exists bool + // compute the path through the nested maps to the nested value + path := strings.Split(key, v.keyDelim) + if shadow := v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)); shadow != "" { + return nil + } + // if the requested key is an alias, then return the proper key key = v.realKey(key) + // re-compute the path + path = strings.Split(key, v.keyDelim) + + // Set() override first + val = v.searchMap(v.override, path) + if val != nil { + return val + } + if shadow := v.isPathShadowedInDeepMap(path, v.override); shadow != "" { + return nil + } - // PFlag Override first + // PFlag override next flag, exists := v.pflags[key] if exists && flag.HasChanged() { - jww.TRACE.Println(key, "found in override (via pflag):", flag.ValueString()) switch flag.ValueType() { case "int", "int8", "int16", "int32", "int64": return cast.ToInt(flag.ValueString()) case "bool": return cast.ToBool(flag.ValueString()) + case "stringSlice": + s := strings.TrimPrefix(flag.ValueString(), "[") + return strings.TrimSuffix(s, "]") default: return flag.ValueString() } } - - val, exists = v.override[key] - if exists { - jww.TRACE.Println(key, "found in override:", val) - return val + if shadow := v.isPathShadowedInFlatMap(path, v.pflags); shadow != "" { + return nil } + // Env override next if v.automaticEnvApplied { // even if it hasn't been registered, if automaticEnv is used, // check any Get request if val = v.getEnv(v.mergeWithEnvPrefix(key)); val != "" { - jww.TRACE.Println(key, "found in environment with val:", val) return val } + if shadow := v.isPathShadowedInAutoEnv(path); shadow != "" { + return nil + } } - envkey, exists := v.env[key] if exists { - jww.TRACE.Println(key, "registered as env var", envkey) if val = v.getEnv(envkey); val != "" { - jww.TRACE.Println(envkey, "found in environment with val:", val) return val - } else { - jww.TRACE.Println(envkey, "env value unset:") } } + if shadow := v.isPathShadowedInFlatMap(path, v.env); shadow != "" { + return nil + } - val, exists = v.config[key] - if exists { - jww.TRACE.Println(key, "found in config:", val) + // Config file next + val = v.searchMapWithPathPrefixes(v.config, path) + if val != nil { return val } - - // Test for nested config parameter - if strings.Contains(key, v.keyDelim) { - path := strings.Split(key, v.keyDelim) - - source := v.find(path[0]) - if source != nil { - if reflect.TypeOf(source).Kind() == reflect.Map { - val := v.searchMap(cast.ToStringMap(source), path[1:]) - jww.TRACE.Println(key, "found in nested config:", val) - return val - } - } + if shadow := v.isPathShadowedInDeepMap(path, v.config); shadow != "" { + return nil } - val, exists = v.kvstore[key] - if exists { - jww.TRACE.Println(key, "found in key/value store:", val) + // K/V store next + val = v.searchMap(v.kvstore, path) + if val != nil { return val } + if shadow := v.isPathShadowedInDeepMap(path, v.kvstore); shadow != "" { + return nil + } - val, exists = v.defaults[key] - if exists { - jww.TRACE.Println(key, "found in defaults:", val) + // Default next + val = v.searchMap(v.defaults, path) + if val != nil { return val } + if shadow := v.isPathShadowedInDeepMap(path, v.defaults); shadow != "" { + return nil + } + + // last chance: if no other value is returned and a flag does exist for the value, + // get the flag's value even if the flag's value has not changed + if flag, exists := v.pflags[key]; exists { + switch flag.ValueType() { + case "int", "int8", "int16", "int32", "int64": + return cast.ToInt(flag.ValueString()) + case "bool": + return cast.ToBool(flag.ValueString()) + case "stringSlice": + s := strings.TrimPrefix(flag.ValueString(), "[") + return strings.TrimSuffix(s, "]") + default: + return flag.ValueString() + } + } + // last item, no need to check shadowing return nil } -// Check to see if the key has been set in any of the data locations +// IsSet checks to see if the key has been set in any of the data locations. func IsSet(key string) bool { return v.IsSet(key) } func (v *Viper) IsSet(key string) bool { - path := strings.Split(key, v.keyDelim) - lcaseKey := strings.ToLower(key) val := v.find(lcaseKey) - - if val == nil { - source := v.find(strings.ToLower(path[0])) - if source != nil { - if reflect.TypeOf(source).Kind() == reflect.Map { - val = v.searchMap(cast.ToStringMap(source), path[1:]) - } - } - } - return val != nil } -// Have Viper check ENV variables for all +// AutomaticEnv has Viper check ENV variables for all. // keys set in config, default & flags func AutomaticEnv() { v.AutomaticEnv() } func (v *Viper) AutomaticEnv() { @@ -902,12 +1019,11 @@ func (v *Viper) realKey(key string) string { if exists { jww.DEBUG.Println("Alias", key, "to", newkey) return v.realKey(newkey) - } else { - return key } + return key } -// Check to see if the given key (or an alias) is in the config file +// InConfig checks to see if the given key (or an alias) is in the config file. func InConfig(key string) bool { return v.InConfig(key) } func (v *Viper) InConfig(key string) bool { // if the requested key is an alias, then return the proper key @@ -917,26 +1033,38 @@ func (v *Viper) InConfig(key string) bool { return exists } -// Set the default value for this key. +// SetDefault sets the default value for this key. // Default only used when no value is provided by the user via flag, config or ENV. func SetDefault(key string, value interface{}) { v.SetDefault(key, value) } func (v *Viper) SetDefault(key string, value interface{}) { // If alias passed in, then set the proper default key = v.realKey(strings.ToLower(key)) - v.defaults[key] = value + + path := strings.Split(key, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(v.defaults, path[0:len(path)-1]) + + // set innermost value + deepestMap[lastKey] = value } -// Sets the value for the key in the override regiser. +// Set sets the value for the key in the override regiser. // Will be used instead of values obtained via -// flags, config file, ENV, default, or key/value store +// flags, config file, ENV, default, or key/value store. func Set(key string, value interface{}) { v.Set(key, value) } func (v *Viper) Set(key string, value interface{}) { // If alias passed in, then set the proper override key = v.realKey(strings.ToLower(key)) - v.override[key] = value + + path := strings.Split(key, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(v.override, path[0:len(path)-1]) + + // set innermost value + deepestMap[lastKey] = value } -// Viper will discover and load the configuration file from disk +// ReadInConfig will discover and load the configuration file from disk // and key/value stores, searching in one of the defined paths. func ReadInConfig() error { return v.ReadInConfig() } func (v *Viper) ReadInConfig() error { @@ -971,7 +1099,7 @@ func (v *Viper) MergeInConfig() error { return v.MergeConfig(bytes.NewReader(file)) } -// Viper will read a configuration file, setting existing keys to nil if the +// ReadConfig will read a configuration file, setting existing keys to nil if the // key does not exist in the file. func ReadConfig(in io.Reader) error { return v.ReadConfig(in) } func (v *Viper) ReadConfig(in io.Reader) error { @@ -1013,6 +1141,14 @@ func castToMapStringInterface( return tgt } +func castMapStringToMapInterface(src map[string]string) map[string]interface{} { + tgt := map[string]interface{}{} + for k, v := range src { + tgt[k] = v + } + return tgt +} + // mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's // insistence on parsing nested structures as `map[interface{}]interface{}` // instead of using a `string` as the key for nest structures beyond one level @@ -1073,34 +1209,20 @@ func mergeMaps( } } -// func ReadBufConfig(buf *bytes.Buffer) error { return v.ReadBufConfig(buf) } -// func (v *Viper) ReadBufConfig(buf *bytes.Buffer) error { -// v.config = make(map[string]interface{}) -// return v.unmarshalReader(buf, v.config) -// } - -// Attempts to get configuration from a remote source +// ReadRemoteConfig attempts to get configuration from a remote source // and read it in the remote configuration registry. func ReadRemoteConfig() error { return v.ReadRemoteConfig() } func (v *Viper) ReadRemoteConfig() error { - err := v.getKeyValueConfig() - if err != nil { - return err - } - return nil + return v.getKeyValueConfig() } func WatchRemoteConfig() error { return v.WatchRemoteConfig() } func (v *Viper) WatchRemoteConfig() error { - err := v.watchKeyValueConfig() - if err != nil { - return err - } - return nil + return v.watchKeyValueConfig() } -// Unmarshall a Reader into a map -// Should probably be an unexported function +// Unmarshall a Reader into a map. +// Should probably be an unexported function. func unmarshalReader(in io.Reader, c map[string]interface{}) error { return v.unmarshalReader(in, c) } @@ -1116,7 +1238,7 @@ func (v *Viper) insensitiviseMaps() { insensitiviseMap(v.kvstore) } -// retrieve the first found remote configuration +// Retrieve the first found remote configuration. func (v *Viper) getKeyValueConfig() error { if RemoteConfig == nil { return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'") @@ -1133,8 +1255,7 @@ func (v *Viper) getKeyValueConfig() error { return RemoteConfigError("No Files Found") } -func (v *Viper) getRemoteConfig(provider *defaultRemoteProvider) (map[string]interface{}, error) { - +func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { reader, err := RemoteConfig.Get(provider) if err != nil { return nil, err @@ -1143,7 +1264,7 @@ func (v *Viper) getRemoteConfig(provider *defaultRemoteProvider) (map[string]int return v.kvstore, err } -// retrieve the first found remote configuration +// Retrieve the first found remote configuration. func (v *Viper) watchKeyValueConfig() error { for _, rp := range v.remoteProviders { val, err := v.watchRemoteConfig(rp) @@ -1156,7 +1277,7 @@ func (v *Viper) watchKeyValueConfig() error { return RemoteConfigError("No Files Found") } -func (v *Viper) watchRemoteConfig(provider *defaultRemoteProvider) (map[string]interface{}, error) { +func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { reader, err := RemoteConfig.Watch(provider) if err != nil { return nil, err @@ -1165,65 +1286,124 @@ func (v *Viper) watchRemoteConfig(provider *defaultRemoteProvider) (map[string]i return v.kvstore, err } -// Return all keys regardless where they are set +// AllKeys returns all keys holding a value, regardless of where they are set. +// Nested keys are returned with a v.keyDelim (= ".") separator func AllKeys() []string { return v.AllKeys() } func (v *Viper) AllKeys() []string { - m := map[string]struct{}{} - - for key, _ := range v.defaults { - m[strings.ToLower(key)] = struct{}{} - } - - for key, _ := range v.pflags { - m[strings.ToLower(key)] = struct{}{} - } - - for key, _ := range v.env { - m[strings.ToLower(key)] = struct{}{} - } - - for key, _ := range v.config { - m[strings.ToLower(key)] = struct{}{} + m := map[string]bool{} + // add all paths, by order of descending priority to ensure correct shadowing + m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "") + m = v.flattenAndMergeMap(m, v.override, "") + m = v.mergeFlatMap(m, v.pflags) + m = v.mergeFlatMap(m, v.env) + m = v.flattenAndMergeMap(m, v.config, "") + m = v.flattenAndMergeMap(m, v.kvstore, "") + m = v.flattenAndMergeMap(m, v.defaults, "") + + // convert set of paths to list + a := []string{} + for x := range m { + a = append(a, x) } + return a +} - for key, _ := range v.kvstore { - m[strings.ToLower(key)] = struct{}{} +// flattenAndMergeMap recursively flattens the given map into a map[string]bool +// of key paths (used as a set, easier to manipulate than a []string): +// - each path is merged into a single key string, delimited with v.keyDelim (= ".") +// - if a path is shadowed by an earlier value in the initial shadow map, +// it is skipped. +// The resulting set of paths is merged to the given shadow set at the same time. +func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool { + if shadow != nil && prefix != "" && shadow[prefix] { + // prefix is shadowed => nothing more to flatten + return shadow } - - for key, _ := range v.override { - m[strings.ToLower(key)] = struct{}{} + if shadow == nil { + shadow = make(map[string]bool) } - for key, _ := range v.aliases { - m[strings.ToLower(key)] = struct{}{} + var m2 map[string]interface{} + if prefix != "" { + prefix += v.keyDelim } - - a := []string{} - for x, _ := range m { - a = append(a, x) + for k, val := range m { + fullKey := prefix + k + switch val.(type) { + case map[string]interface{}: + m2 = val.(map[string]interface{}) + case map[interface{}]interface{}: + m2 = cast.ToStringMap(val) + default: + // immediate value + shadow[strings.ToLower(fullKey)] = true + continue + } + // recursively merge to shadow map + shadow = v.flattenAndMergeMap(shadow, m2, fullKey) + } + return shadow +} + +// mergeFlatMap merges the given maps, excluding values of the second map +// shadowed by values from the first map. +func (v *Viper) mergeFlatMap(shadow map[string]bool, mi interface{}) map[string]bool { + // unify input map + var m map[string]interface{} + switch mi.(type) { + case map[string]string, map[string]FlagValue: + m = cast.ToStringMap(mi) + default: + return shadow + } + + // scan keys +outer: + for k, _ := range m { + path := strings.Split(k, v.keyDelim) + // scan intermediate paths + var parentKey string + for i := 1; i < len(path); i++ { + parentKey = strings.Join(path[0:i], v.keyDelim) + if shadow[parentKey] { + // path is shadowed, continue + continue outer + } + } + // add key + shadow[strings.ToLower(k)] = true } - - return a + return shadow } -// Return all settings as a map[string]interface{} +// AllSettings merges all settings and returns them as a map[string]interface{}. func AllSettings() map[string]interface{} { return v.AllSettings() } func (v *Viper) AllSettings() map[string]interface{} { m := map[string]interface{}{} - for _, x := range v.AllKeys() { - m[x] = v.Get(x) + // start from the list of keys, and construct the map one value at a time + for _, k := range v.AllKeys() { + value := v.Get(k) + if value == nil { + // should not happen, since AllKeys() returns only keys holding a value, + // check just in case anything changes + continue + } + path := strings.Split(k, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(m, path[0:len(path)-1]) + // set innermost value + deepestMap[lastKey] = value } - return m } -// Se the filesystem to use to read configuration. +// SetFs sets the filesystem to use to read configuration. func SetFs(fs afero.Fs) { v.SetFs(fs) } func (v *Viper) SetFs(fs afero.Fs) { v.fs = fs } -// Name for the config file. +// SetConfigName sets name for the config file. // Does not include extension. func SetConfigName(in string) { v.SetConfigName(in) } func (v *Viper) SetConfigName(in string) { @@ -1233,7 +1413,7 @@ func (v *Viper) SetConfigName(in string) { } } -// Sets the type of the configuration returned by the +// SetConfigType sets the type of the configuration returned by the // remote source, e.g. "json". func SetConfigType(in string) { v.SetConfigType(in) } func (v *Viper) SetConfigType(in string) { @@ -1252,9 +1432,9 @@ func (v *Viper) getConfigType() string { if len(ext) > 1 { return ext[1:] - } else { - return "" } + + return "" } func (v *Viper) getConfigFile() string { @@ -1285,8 +1465,8 @@ func (v *Viper) searchInPath(in string) (filename string) { return "" } -// search all configPaths for any config file. -// Returns the first path that exists (and is a config file) +// Search all configPaths for any config file. +// Returns the first path that exists (and is a config file). func (v *Viper) findConfigFile() (string, error) { jww.INFO.Println("Searching for config in ", v.configPaths) @@ -1300,11 +1480,10 @@ func (v *Viper) findConfigFile() (string, error) { return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} } -// Prints all configuration registries for debugging +// Debug prints all configuration registries for debugging // purposes. func Debug() { v.Debug() } func (v *Viper) Debug() { - fmt.Println("Aliases:") fmt.Printf("Aliases:\n%#v\n", v.aliases) fmt.Printf("Override:\n%#v\n", v.override) fmt.Printf("PFlags:\n%#v\n", v.pflags) diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index e6a7960..29b71d1 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -1,386 +1,345 @@ /* * CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen * THIS FILE MUST NOT BE EDITED BY HAND -*/ + */ package assert import ( - http "net/http" url "net/url" time "time" ) - // Condition uses a Comparison to assert a complex condition. func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { return Condition(a.t, comp, msgAndArgs...) } - // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. -// +// // a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") // a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") // a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { return Contains(a.t, s, contains, msgAndArgs...) } - // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. -// +// // a.Empty(obj) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { return Empty(a.t, object, msgAndArgs...) } - // Equal asserts that two objects are equal. -// +// // a.Equal(123, 123, "123 and 123 should be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Equal(a.t, expected, actual, msgAndArgs...) } - // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. -// +// // actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// +// a.EqualError(err, expectedErrorString, "An error was expected") +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { return EqualError(a.t, theError, errString, msgAndArgs...) } - // EqualValues asserts that two objects are equal or convertable to the same types // and equal. -// +// // a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return EqualValues(a.t, expected, actual, msgAndArgs...) } - // Error asserts that a function returned an error (i.e. not `nil`). -// +// // actualObj, err := SomeFunction() // if a.Error(err, "An error was expected") { // assert.Equal(t, err, expectedError) // } -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { return Error(a.t, err, msgAndArgs...) } - // Exactly asserts that two objects are equal is value and type. -// +// // a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Exactly(a.t, expected, actual, msgAndArgs...) } - // Fail reports a failure through func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { return Fail(a.t, failureMessage, msgAndArgs...) } - // FailNow fails test func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { return FailNow(a.t, failureMessage, msgAndArgs...) } - // False asserts that the specified value is false. -// +// // a.False(myBool, "myBool should be false") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { return False(a.t, value, msgAndArgs...) } - // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. -// +// // a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { return HTTPBodyContains(a.t, handler, method, url, values, str) } - // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. -// +// // a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { return HTTPBodyNotContains(a.t, handler, method, url, values, str) } - // HTTPError asserts that a specified handler returns an error status code. -// +// // a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool { return HTTPError(a.t, handler, method, url, values) } - // HTTPRedirect asserts that a specified handler returns a redirect status code. -// +// // a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool { return HTTPRedirect(a.t, handler, method, url, values) } - // HTTPSuccess asserts that a specified handler returns a success status code. -// +// // a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool { return HTTPSuccess(a.t, handler, method, url, values) } - // Implements asserts that an object is implemented by the specified interface. -// +// // a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { return Implements(a.t, interfaceObject, object, msgAndArgs...) } - // InDelta asserts that the two numerals are within delta of each other. -// +// // a.InDelta(math.Pi, (22 / 7.0), 0.01) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { return InDelta(a.t, expected, actual, delta, msgAndArgs...) } - // InDeltaSlice is the same as InDelta, except it compares two slices. func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) } - // InEpsilon asserts that expected and actual have a relative error less than epsilon -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) } - -// InEpsilonSlice is the same as InEpsilon, except it compares two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - return InEpsilonSlice(a.t, expected, actual, delta, msgAndArgs...) +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) } - // IsType asserts that the specified objects are of the same type. func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { return IsType(a.t, expectedType, object, msgAndArgs...) } - // JSONEq asserts that two JSON strings are equivalent. -// +// // a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { return JSONEq(a.t, expected, actual, msgAndArgs...) } - // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. -// +// // a.Len(mySlice, 3, "The size of slice is not 3") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { return Len(a.t, object, length, msgAndArgs...) } - // Nil asserts that the specified object is nil. -// +// // a.Nil(err, "err should be nothing") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { return Nil(a.t, object, msgAndArgs...) } - // NoError asserts that a function returned no error (i.e. `nil`). -// +// // actualObj, err := SomeFunction() // if a.NoError(err) { // assert.Equal(t, actualObj, expectedObj) // } -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } - // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. -// +// // a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") // a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") // a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { return NotContains(a.t, s, contains, msgAndArgs...) } - // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. -// +// // if a.NotEmpty(obj) { // assert.Equal(t, "two", obj[1]) // } -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { return NotEmpty(a.t, object, msgAndArgs...) } - // NotEqual asserts that the specified values are NOT equal. -// +// // a.NotEqual(obj1, obj2, "two objects shouldn't be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return NotEqual(a.t, expected, actual, msgAndArgs...) } - // NotNil asserts that the specified object is not nil. -// +// // a.NotNil(err, "err should be something") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { return NotNil(a.t, object, msgAndArgs...) } - // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// +// // a.NotPanics(func(){ // RemainCalm() // }, "Calling RemainCalm() should NOT panic") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { return NotPanics(a.t, f, msgAndArgs...) } - // NotRegexp asserts that a specified regexp does not match a string. -// +// // a.NotRegexp(regexp.MustCompile("starts"), "it's starting") // a.NotRegexp("^start", "it's not starting") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { return NotRegexp(a.t, rx, str, msgAndArgs...) } - // NotZero asserts that i is not the zero value for its type and returns the truth. func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { return NotZero(a.t, i, msgAndArgs...) } - // Panics asserts that the code inside the specified PanicTestFunc panics. -// +// // a.Panics(func(){ // GoCrazy() // }, "Calling GoCrazy() should panic") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { return Panics(a.t, f, msgAndArgs...) } - // Regexp asserts that a specified regexp matches a string. -// +// // a.Regexp(regexp.MustCompile("start"), "it's starting") // a.Regexp("start...$", "it's not starting") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { return Regexp(a.t, rx, str, msgAndArgs...) } - // True asserts that the specified value is true. -// +// // a.True(myBool, "myBool should be true") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { return True(a.t, value, msgAndArgs...) } - // WithinDuration asserts that the two times are within duration delta of each other. -// +// // a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) } - // Zero asserts that i is the zero value for its type and returns the truth. func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { return Zero(a.t, i, msgAndArgs...) diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index 348d5f1..835084f 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -18,6 +18,10 @@ import ( "github.com/pmezard/go-difflib/difflib" ) +func init() { + spew.Config.SortKeys = true +} + // TestingT is an interface wrapper around *testing.T type TestingT interface { Errorf(format string, args ...interface{}) @@ -65,7 +69,7 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool { /* CallerInfo is necessary because the assert functions use the testing object internally, causing it to print the file:line of the assert method, rather than where -the problem actually occured in calling code.*/ +the problem actually occurred in calling code.*/ // CallerInfo returns an array of strings containing the file and line number // of each stack frame leading from the current test to the assert call that @@ -82,7 +86,9 @@ func CallerInfo() []string { for i := 0; ; i++ { pc, file, line, ok = runtime.Caller(i) if !ok { - return nil + // The breaks below failed to terminate the loop, and we ran off the + // end of the call stack. + break } // This is a huge edge case, but it will panic if this is the case, see #180 @@ -90,6 +96,21 @@ func CallerInfo() []string { break } + f := runtime.FuncForPC(pc) + if f == nil { + break + } + name = f.Name() + + // testing.tRunner is the standard library function that calls + // tests. Subtests are called directly by tRunner, without going through + // the Test/Benchmark/Example function that contains the t.Run calls, so + // with subtests we should break when we hit tRunner, without adding it + // to the list of callers. + if name == "testing.tRunner" { + break + } + parts := strings.Split(file, "/") dir := parts[len(parts)-2] file = parts[len(parts)-1] @@ -97,11 +118,6 @@ func CallerInfo() []string { callers = append(callers, fmt.Sprintf("%s:%d", file, line)) } - f := runtime.FuncForPC(pc) - if f == nil { - break - } - name = f.Name() // Drop the package segments := strings.Split(name, ".") name = segments[len(segments)-1] @@ -262,14 +278,48 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) if !ObjectsAreEqual(expected, actual) { diff := diff(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ - " != %#v (actual)%s", expected, actual, diff), msgAndArgs...) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "received: %s%s", expected, actual, diff), msgAndArgs...) } return true } +// formatUnequalValues takes two values of arbitrary types and returns string +// representations appropriate to be presented to the user. +// +// If the values are not of like type, the returned strings will be prefixed +// with the type name, and the value will be enclosed in parenthesis similar +// to a type conversion in the Go grammar. +func formatUnequalValues(expected, actual interface{}) (e string, a string) { + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType && isNumericType(aType) && isNumericType(bType) { + return fmt.Sprintf("%v(%#v)", aType, expected), + fmt.Sprintf("%v(%#v)", bType, actual) + } + + return fmt.Sprintf("%#v", expected), + fmt.Sprintf("%#v", actual) +} + +func isNumericType(t reflect.Type) bool { + switch t.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + case reflect.Float32, reflect.Float64: + return true + } + + return false +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // @@ -279,8 +329,11 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if !ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ - " != %#v (actual)", expected, actual), msgAndArgs...) + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "received: %s%s", expected, actual, diff), msgAndArgs...) } return true @@ -833,7 +886,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m // Returns whether the assertion was successful (true) or not (false). func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if err != nil { - return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) } return true @@ -849,9 +902,8 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { // Returns whether the assertion was successful (true) or not (false). func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { - message := messageFromMsgAndArgs(msgAndArgs...) if err == nil { - return Fail(t, "An error is expected but got nil. %s", message) + return Fail(t, "An error is expected but got nil.", msgAndArgs...) } return true @@ -861,20 +913,22 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } +// assert.EqualError(t, err, expectedErrorString, "An error was expected") // // Returns whether the assertion was successful (true) or not (false). func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { - - message := messageFromMsgAndArgs(msgAndArgs...) - if !NotNil(t, theError, "An error is expected but got nil. %s", message) { + if !Error(t, theError, msgAndArgs...) { return false } - s := "An error with value \"%s\" is expected but got \"%s\". %s" - return Equal(t, errString, theError.Error(), - s, errString, theError.Error(), message) + expected := errString + actual := theError.Error() + // don't need to use deep equals here, we know they are both strings + if expected != actual { + return Fail(t, fmt.Sprintf("Error message not equal:\n"+ + "expected: %q\n"+ + "received: %q", expected, actual), msgAndArgs...) + } + return true } // matchRegexp return true if a specified regexp matches a string. @@ -989,7 +1043,6 @@ func diff(expected interface{}, actual interface{}) string { return "" } - spew.Config.SortKeys = true e := spew.Sdump(expected) a := spew.Sdump(actual) diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go index e1b9442..fa7ab89 100644 --- a/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -99,7 +99,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url strin contains := strings.Contains(body, fmt.Sprint(str)) if contains { - Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) } return !contains diff --git a/vendor/go4.org/wkfs/gcs/gcs.go b/vendor/go4.org/wkfs/gcs/gcs.go index 21f2551..a970c75 100644 --- a/vendor/go4.org/wkfs/gcs/gcs.go +++ b/vendor/go4.org/wkfs/gcs/gcs.go @@ -32,13 +32,13 @@ import ( "strings" "time" + "cloud.google.com/go/compute/metadata" + "cloud.google.com/go/storage" "go4.org/wkfs" "golang.org/x/net/context" "golang.org/x/oauth2" "golang.org/x/oauth2/google" - "google.golang.org/cloud" - "google.golang.org/cloud/compute/metadata" - "google.golang.org/cloud/storage" + "google.golang.org/api/option" ) // Max size for all files read, because we use a bytes.Reader as our file @@ -56,13 +56,8 @@ func init() { registerBrokenFS(fmt.Errorf("could not get http client for context: %v", err)) return } - projID, err := metadata.ProjectID() - if projID == "" || err != nil { - registerBrokenFS(fmt.Errorf("could not get GCE project ID: %v", err)) - return - } - ctx := cloud.NewContext(projID, hc) - sc, err := storage.NewClient(ctx) + ctx := context.Background() + sc, err := storage.NewClient(ctx, option.WithHTTPClient(hc)) if err != nil { registerBrokenFS(fmt.Errorf("could not get cloud storage client: %v", err)) return diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go index 12ffa82..a6ba06a 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring.go +++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "sync" + "time" "golang.org/x/crypto/ssh" ) @@ -18,6 +19,7 @@ import ( type privKey struct { signer ssh.Signer comment string + expire *time.Time } type keyring struct { @@ -48,15 +50,9 @@ func (r *keyring) RemoveAll() error { return nil } -// Remove removes all identities with the given public key. -func (r *keyring) Remove(key ssh.PublicKey) error { - r.mu.Lock() - defer r.mu.Unlock() - if r.locked { - return errLocked - } - - want := key.Marshal() +// removeLocked does the actual key removal. The caller must already be holding the +// keyring mutex. +func (r *keyring) removeLocked(want []byte) error { found := false for i := 0; i < len(r.keys); { if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) { @@ -75,7 +71,18 @@ func (r *keyring) Remove(key ssh.PublicKey) error { return nil } -// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list. +// Remove removes all identities with the given public key. +func (r *keyring) Remove(key ssh.PublicKey) error { + r.mu.Lock() + defer r.mu.Unlock() + if r.locked { + return errLocked + } + + return r.removeLocked(key.Marshal()) +} + +// Lock locks the agent. Sign and Remove will fail, and List will return an empty list. func (r *keyring) Lock(passphrase []byte) error { r.mu.Lock() defer r.mu.Unlock() @@ -104,6 +111,17 @@ func (r *keyring) Unlock(passphrase []byte) error { return nil } +// expireKeysLocked removes expired keys from the keyring. If a key was added +// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have +// ellapsed, it is removed. The caller *must* be holding the keyring mutex. +func (r *keyring) expireKeysLocked() { + for _, k := range r.keys { + if k.expire != nil && time.Now().After(*k.expire) { + r.removeLocked(k.signer.PublicKey().Marshal()) + } + } +} + // List returns the identities known to the agent. func (r *keyring) List() ([]*Key, error) { r.mu.Lock() @@ -113,6 +131,7 @@ func (r *keyring) List() ([]*Key, error) { return nil, nil } + r.expireKeysLocked() var ids []*Key for _, k := range r.keys { pub := k.signer.PublicKey() @@ -146,7 +165,17 @@ func (r *keyring) Add(key AddedKey) error { } } - r.keys = append(r.keys, privKey{signer, key.Comment}) + p := privKey{ + signer: signer, + comment: key.Comment, + } + + if key.LifetimeSecs > 0 { + t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second) + p.expire = &t + } + + r.keys = append(r.keys, p) return nil } @@ -159,6 +188,7 @@ func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { return nil, errLocked } + r.expireKeysLocked() wanted := key.Marshal() for _, k := range r.keys { if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) { @@ -176,6 +206,7 @@ func (r *keyring) Signers() ([]ssh.Signer, error) { return nil, errLocked } + r.expireKeysLocked() s := make([]ssh.Signer, 0, len(r.keys)) for _, k := range r.keys { s = append(s, k.signer) diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index ae26191..37d42e4 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -371,7 +371,16 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro } // We don't send FirstKexFollows, but we handle receiving it. - if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] { + // + // RFC 4253 section 7 defines the kex and the agreement method for + // first_kex_packet_follows. It states that the guessed packet + // should be ignored if the "kex algorithm and/or the host + // key algorithm is guessed wrong (server and client have + // different preferred algorithm), or if any of the other + // algorithms cannot be agreed upon". The other algorithms have + // already been checked above so the kex algorithm and host key + // algorithm are checked here. + if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) { // other side sent a kex message for the wrong algorithm, // which we have to ignore. if _, err := t.conn.readPacket(); err != nil { diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 0324e12..e13cf9c 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -281,6 +281,12 @@ type PublicKey interface { Verify(data []byte, sig *Signature) error } +// CryptoPublicKey, if implemented by a PublicKey, +// returns the underlying crypto.PublicKey form of the key. +type CryptoPublicKey interface { + CryptoPublicKey() crypto.PublicKey +} + // A Signer can create signatures that verify against a public key. type Signer interface { // PublicKey returns an associated PublicKey instance. @@ -348,6 +354,10 @@ func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob) } +func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey { + return (*rsa.PublicKey)(r) +} + type dsaPublicKey dsa.PublicKey func (r *dsaPublicKey) Type() string { @@ -416,6 +426,10 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error { return errors.New("ssh: signature did not verify") } +func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey { + return (*dsa.PublicKey)(k) +} + type dsaPrivateKey struct { *dsa.PrivateKey } @@ -509,6 +523,10 @@ func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error { return nil } +func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey { + return ed25519.PublicKey(k) +} + func supportedEllipticCurve(curve elliptic.Curve) bool { return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521() } @@ -604,6 +622,10 @@ func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error { return errors.New("ssh: signature did not verify") } +func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey { + return (*ecdsa.PublicKey)(k) +} + // NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey, // *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding // Signer instance. ECDSA keys must use P-256, P-384 or P-521. @@ -731,6 +753,14 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) { return NewSignerFromKey(key) } +// encryptedBlock tells whether a private key is +// encrypted by examining its Proc-Type header +// for a mention of ENCRYPTED +// according to RFC 1421 Section 4.6.1.1. +func encryptedBlock(block *pem.Block) bool { + return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED") +} + // ParseRawPrivateKey returns a private key from a PEM encoded private key. It // supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys. func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { @@ -739,6 +769,10 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { return nil, errors.New("ssh: no key found") } + if encryptedBlock(block) { + return nil, errors.New("ssh: cannot decode encrypted private keys") + } + switch block.Type { case "RSA PRIVATE KEY": return x509.ParsePKCS1PrivateKey(block.Bytes) diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index c9b09bb..b0c79b0 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -737,7 +737,7 @@ func (f *Framer) WriteSettings(settings ...Setting) error { return f.endWrite() } -// WriteSettings writes an empty SETTINGS frame with the ACK bit set. +// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set. // // It will perform exactly one Write to the underlying Writer. // It is the caller's responsibility to not call other Write methods concurrently. diff --git a/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go index 730319d..47b7fae 100644 --- a/vendor/golang.org/x/net/http2/go17.go +++ b/vendor/golang.org/x/net/http2/go17.go @@ -39,6 +39,13 @@ type clientTrace httptrace.ClientTrace func reqContext(r *http.Request) context.Context { return r.Context() } +func (t *Transport) idleConnTimeout() time.Duration { + if t.t1 != nil { + return t.t1.IdleConnTimeout + } + return 0 +} + func setResponseUncompressed(res *http.Response) { res.Uncompressed = true } func traceGotConn(req *http.Request, cc *ClientConn) { @@ -92,3 +99,8 @@ func requestTrace(req *http.Request) *clientTrace { trace := httptrace.ContextClientTrace(req.Context()) return (*clientTrace)(trace) } + +// Ping sends a PING frame to the server and waits for the ack. +func (cc *ClientConn) Ping(ctx context.Context) error { + return cc.ping(ctx) +} diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 8aa197a..135b9f6 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -57,7 +57,7 @@ func (hf HeaderField) String() string { return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix) } -// Size returns the size of an entry per RFC 7540 section 5.2. +// Size returns the size of an entry per RFC 7541 section 4.1. func (hf HeaderField) Size() uint32 { // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 401923b..2e27b09 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -343,7 +343,7 @@ func (s *sorter) Keys(h http.Header) []string { } func (s *sorter) SortStrings(ss []string) { - // Our sorter works on s.v, which sorter owners, so + // Our sorter works on s.v, which sorter owns, so // stash it away while we sort the user's buffer. save := s.v s.v = ss @@ -352,11 +352,14 @@ func (s *sorter) SortStrings(ss []string) { } // validPseudoPath reports whether v is a valid :path pseudo-header -// value. It must be a non-empty string starting with '/', and not -// start with two slashes. +// value. It must be either: +// +// *) a non-empty string starting with '/', but not with with "//", +// *) the string '*', for OPTIONS requests. +// // For now this is only used a quick check for deciding when to clean // up Opaque URLs before sending requests from the Transport. // See golang.org/issue/16847 func validPseudoPath(v string) bool { - return len(v) > 0 && v[0] == '/' && (len(v) == 1 || v[1] != '/') + return (len(v) > 0 && v[0] == '/' && (len(v) == 1 || v[1] != '/')) || v == "*" } diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go index 667867f..140434a 100644 --- a/vendor/golang.org/x/net/http2/not_go17.go +++ b/vendor/golang.org/x/net/http2/not_go17.go @@ -10,9 +10,13 @@ import ( "crypto/tls" "net" "net/http" + "time" ) -type contextContext interface{} +type contextContext interface { + Done() <-chan struct{} + Err() error +} type fakeContext struct{} @@ -75,3 +79,9 @@ func cloneTLSConfig(c *tls.Config) *tls.Config { CurvePreferences: c.CurvePreferences, } } + +func (cc *ClientConn) Ping(ctx contextContext) error { + return cc.ping(ctx) +} + +func (t *Transport) idleConnTimeout() time.Duration { return 0 } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 8206fa7..c986bc1 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -1475,6 +1475,19 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { handler = new400Handler(err) } + // The net/http package sets the read deadline from the + // http.Server.ReadTimeout during the TLS handshake, but then + // passes the connection off to us with the deadline already + // set. Disarm it here after the request headers are read, similar + // to how the http1 server works. + // Unlike http1, though, we never re-arm it yet, though. + // TODO(bradfitz): figure out golang.org/issue/14204 + // (IdleTimeout) and how this relates. Maybe the default + // IdleTimeout is ReadTimeout. + if sc.hs.ReadTimeout != 0 { + sc.conn.SetReadDeadline(time.Time{}) + } + go sc.runHandler(rw, req, handler) return nil } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 47c66d9..b939fed 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -10,6 +10,7 @@ import ( "bufio" "bytes" "compress/gzip" + "crypto/rand" "crypto/tls" "errors" "fmt" @@ -26,6 +27,7 @@ import ( "time" "golang.org/x/net/http2/hpack" + "golang.org/x/net/idna" "golang.org/x/net/lex/httplex" ) @@ -149,6 +151,9 @@ type ClientConn struct { readerDone chan struct{} // closed on error readerErr error // set before readerDone is closed + idleTimeout time.Duration // or 0 for never + idleTimer *time.Timer + mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes flow flow // our conn-level flow control quota (cs.flow is per stream) @@ -159,6 +164,7 @@ type ClientConn struct { goAwayDebug string // goAway frame's debug data, retained as a string streams map[uint32]*clientStream // client-initiated nextStreamID uint32 + pings map[[8]byte]chan struct{} // in flight ping data to notification channel bw *bufio.Writer br *bufio.Reader fr *Framer @@ -285,14 +291,18 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { // authorityAddr returns a given authority (a host/IP, or host:port / ip:port) // and returns a host:port. The port 443 is added if needed. func authorityAddr(scheme string, authority string) (addr string) { - if _, _, err := net.SplitHostPort(authority); err == nil { - return authority + host, port, err := net.SplitHostPort(authority) + if err != nil { // authority didn't have a port + port = "443" + if scheme == "http" { + port = "80" + } + host = authority } - port := "443" - if scheme == "http" { - port = "80" + if a, err := idna.ToASCII(host); err == nil { + host = a } - return net.JoinHostPort(authority, port) + return net.JoinHostPort(host, port) } // RoundTripOpt is like RoundTrip, but takes options. @@ -426,6 +436,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro streams: make(map[uint32]*clientStream), singleUse: singleUse, wantSettingsAck: true, + pings: make(map[[8]byte]chan struct{}), + } + if d := t.idleConnTimeout(); d != 0 { + cc.idleTimeout = d + cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -503,6 +518,16 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool { cc.nextStreamID < math.MaxInt32 } +// onIdleTimeout is called from a time.AfterFunc goroutine. It will +// only be called when we're idle, but because we're coming from a new +// goroutine, there could be a new request coming in at the same time, +// so this simply calls the synchronized closeIfIdle to shut down this +// connection. The timer could just call closeIfIdle, but this is more +// clear. +func (cc *ClientConn) onIdleTimeout() { + cc.closeIfIdle() +} + func (cc *ClientConn) closeIfIdle() { cc.mu.Lock() if len(cc.streams) > 0 { @@ -599,13 +624,13 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration { // Certain headers are special-cased as okay but not transmitted later. func checkConnHeaders(req *http.Request) error { if v := req.Header.Get("Upgrade"); v != "" { - return errors.New("http2: invalid Upgrade request header") + return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"]) } - if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 { - return errors.New("http2: invalid Transfer-Encoding request header") + if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { + return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) } - if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 { - return errors.New("http2: invalid Connection request header") + if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") { + return fmt.Errorf("http2: invalid Connection request header: %q", vv) } return nil } @@ -618,6 +643,11 @@ func bodyAndLength(req *http.Request) (body io.Reader, contentLen int64) { if req.ContentLength != 0 { return req.Body, req.ContentLength } + // Don't try to sniff the size if they're doing an expect + // request (Issue 16002): + if req.Header.Get("Expect") == "100-continue" { + return req.Body, -1 + } // We have a body but a zero content length. Test to see if // it's actually zero or just unset. @@ -644,6 +674,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { if err := checkConnHeaders(req); err != nil { return nil, err } + if cc.idleTimer != nil { + cc.idleTimer.Stop() + } trailers, err := commaSeparatedTrailers(req) if err != nil { @@ -651,9 +684,6 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { } hasTrailers := trailers != "" - body, contentLen := bodyAndLength(req) - hasBody := body != nil - cc.mu.Lock() cc.lastActive = time.Now() if cc.closed || !cc.canTakeNewRequestLocked() { @@ -661,6 +691,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { return nil, errClientConnUnusable } + body, contentLen := bodyAndLength(req) + hasBody := body != nil + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? var requestedGzip bool if !cc.t.disableCompression() && @@ -997,6 +1030,10 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail if host == "" { host = req.URL.Host } + host, err := httplex.PunycodeHostPort(host) + if err != nil { + return nil, err + } var path string if req.Method != "CONNECT" { @@ -1037,7 +1074,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail cc.writeHeader(":method", req.Method) if req.Method != "CONNECT" { cc.writeHeader(":path", path) - cc.writeHeader(":scheme", "https") + cc.writeHeader(":scheme", req.URL.Scheme) } if trailers != "" { cc.writeHeader("trailer", trailers) @@ -1164,6 +1201,9 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream { if andRemove && cs != nil && !cc.closed { cc.lastActive = time.Now() delete(cc.streams, id) + if len(cc.streams) == 0 && cc.idleTimer != nil { + cc.idleTimer.Reset(cc.idleTimeout) + } close(cs.done) cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl } @@ -1220,6 +1260,10 @@ func (rl *clientConnReadLoop) cleanup() { defer cc.t.connPool().MarkDead(cc) defer close(cc.readerDone) + if cc.idleTimer != nil { + cc.idleTimer.Stop() + } + // Close any response bodies if the server closes prematurely. // TODO: also do this if we've written the headers but not // gotten a response yet. @@ -1806,10 +1850,56 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { return nil } +// Ping sends a PING frame to the server and waits for the ack. +// Public implementation is in go17.go and not_go17.go +func (cc *ClientConn) ping(ctx contextContext) error { + c := make(chan struct{}) + // Generate a random payload + var p [8]byte + for { + if _, err := rand.Read(p[:]); err != nil { + return err + } + cc.mu.Lock() + // check for dup before insert + if _, found := cc.pings[p]; !found { + cc.pings[p] = c + cc.mu.Unlock() + break + } + cc.mu.Unlock() + } + cc.wmu.Lock() + if err := cc.fr.WritePing(false, p); err != nil { + cc.wmu.Unlock() + return err + } + if err := cc.bw.Flush(); err != nil { + cc.wmu.Unlock() + return err + } + cc.wmu.Unlock() + select { + case <-c: + return nil + case <-ctx.Done(): + return ctx.Err() + case <-cc.readerDone: + // connection closed + return cc.readerErr + } +} + func (rl *clientConnReadLoop) processPing(f *PingFrame) error { if f.IsAck() { - // 6.7 PING: " An endpoint MUST NOT respond to PING frames - // containing this flag." + cc := rl.cc + cc.mu.Lock() + defer cc.mu.Unlock() + // If ack, notify listener if any + if c, ok := cc.pings[f.Data]; ok { + close(c) + delete(cc.pings, f.Data) + } return nil } cc := rl.cc diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go new file mode 100644 index 0000000..3daa897 --- /dev/null +++ b/vendor/golang.org/x/net/idna/idna.go @@ -0,0 +1,68 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package idna implements IDNA2008 (Internationalized Domain Names for +// Applications), defined in RFC 5890, RFC 5891, RFC 5892, RFC 5893 and +// RFC 5894. +package idna // import "golang.org/x/net/idna" + +import ( + "strings" + "unicode/utf8" +) + +// TODO(nigeltao): specify when errors occur. For example, is ToASCII(".") or +// ToASCII("foo\x00") an error? See also http://www.unicode.org/faq/idn.html#11 + +// acePrefix is the ASCII Compatible Encoding prefix. +const acePrefix = "xn--" + +// ToASCII converts a domain or domain label to its ASCII form. For example, +// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and +// ToASCII("golang") is "golang". +func ToASCII(s string) (string, error) { + if ascii(s) { + return s, nil + } + labels := strings.Split(s, ".") + for i, label := range labels { + if !ascii(label) { + a, err := encode(acePrefix, label) + if err != nil { + return "", err + } + labels[i] = a + } + } + return strings.Join(labels, "."), nil +} + +// ToUnicode converts a domain or domain label to its Unicode form. For example, +// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and +// ToUnicode("golang") is "golang". +func ToUnicode(s string) (string, error) { + if !strings.Contains(s, acePrefix) { + return s, nil + } + labels := strings.Split(s, ".") + for i, label := range labels { + if strings.HasPrefix(label, acePrefix) { + u, err := decode(label[len(acePrefix):]) + if err != nil { + return "", err + } + labels[i] = u + } + } + return strings.Join(labels, "."), nil +} + +func ascii(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} diff --git a/vendor/golang.org/x/net/idna/punycode.go b/vendor/golang.org/x/net/idna/punycode.go new file mode 100644 index 0000000..92e733f --- /dev/null +++ b/vendor/golang.org/x/net/idna/punycode.go @@ -0,0 +1,200 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package idna + +// This file implements the Punycode algorithm from RFC 3492. + +import ( + "fmt" + "math" + "strings" + "unicode/utf8" +) + +// These parameter values are specified in section 5. +// +// All computation is done with int32s, so that overflow behavior is identical +// regardless of whether int is 32-bit or 64-bit. +const ( + base int32 = 36 + damp int32 = 700 + initialBias int32 = 72 + initialN int32 = 128 + skew int32 = 38 + tmax int32 = 26 + tmin int32 = 1 +) + +// decode decodes a string as specified in section 6.2. +func decode(encoded string) (string, error) { + if encoded == "" { + return "", nil + } + pos := 1 + strings.LastIndex(encoded, "-") + if pos == 1 { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + if pos == len(encoded) { + return encoded[:len(encoded)-1], nil + } + output := make([]rune, 0, len(encoded)) + if pos != 0 { + for _, r := range encoded[:pos-1] { + output = append(output, r) + } + } + i, n, bias := int32(0), initialN, initialBias + for pos < len(encoded) { + oldI, w := i, int32(1) + for k := base; ; k += base { + if pos == len(encoded) { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + digit, ok := decodeDigit(encoded[pos]) + if !ok { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + pos++ + i += digit * w + if i < 0 { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + t := k - bias + if t < tmin { + t = tmin + } else if t > tmax { + t = tmax + } + if digit < t { + break + } + w *= base - t + if w >= math.MaxInt32/base { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + } + x := int32(len(output) + 1) + bias = adapt(i-oldI, x, oldI == 0) + n += i / x + i %= x + if n > utf8.MaxRune || len(output) >= 1024 { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + output = append(output, 0) + copy(output[i+1:], output[i:]) + output[i] = n + i++ + } + return string(output), nil +} + +// encode encodes a string as specified in section 6.3 and prepends prefix to +// the result. +// +// The "while h < length(input)" line in the specification becomes "for +// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes. +func encode(prefix, s string) (string, error) { + output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) + copy(output, prefix) + delta, n, bias := int32(0), initialN, initialBias + b, remaining := int32(0), int32(0) + for _, r := range s { + if r < 0x80 { + b++ + output = append(output, byte(r)) + } else { + remaining++ + } + } + h := b + if b > 0 { + output = append(output, '-') + } + for remaining != 0 { + m := int32(0x7fffffff) + for _, r := range s { + if m > r && r >= n { + m = r + } + } + delta += (m - n) * (h + 1) + if delta < 0 { + return "", fmt.Errorf("idna: invalid label %q", s) + } + n = m + for _, r := range s { + if r < n { + delta++ + if delta < 0 { + return "", fmt.Errorf("idna: invalid label %q", s) + } + continue + } + if r > n { + continue + } + q := delta + for k := base; ; k += base { + t := k - bias + if t < tmin { + t = tmin + } else if t > tmax { + t = tmax + } + if q < t { + break + } + output = append(output, encodeDigit(t+(q-t)%(base-t))) + q = (q - t) / (base - t) + } + output = append(output, encodeDigit(q)) + bias = adapt(delta, h+1, h == b) + delta = 0 + h++ + remaining-- + } + delta++ + n++ + } + return string(output), nil +} + +func decodeDigit(x byte) (digit int32, ok bool) { + switch { + case '0' <= x && x <= '9': + return int32(x - ('0' - 26)), true + case 'A' <= x && x <= 'Z': + return int32(x - 'A'), true + case 'a' <= x && x <= 'z': + return int32(x - 'a'), true + } + return 0, false +} + +func encodeDigit(digit int32) byte { + switch { + case 0 <= digit && digit < 26: + return byte(digit + 'a') + case 26 <= digit && digit < 36: + return byte(digit + ('0' - 26)) + } + panic("idna: internal error in punycode encoding") +} + +// adapt is the bias adaptation function specified in section 6.1. +func adapt(delta, numPoints int32, firstTime bool) int32 { + if firstTime { + delta /= damp + } else { + delta /= 2 + } + delta += delta / numPoints + k := int32(0) + for delta > ((base-tmin)*tmax)/2 { + delta /= base - tmin + k += base + } + return k + (base-tmin+1)*delta/(delta+skew) +} diff --git a/vendor/golang.org/x/net/lex/httplex/httplex.go b/vendor/golang.org/x/net/lex/httplex/httplex.go index bd0ec24..20f2b89 100644 --- a/vendor/golang.org/x/net/lex/httplex/httplex.go +++ b/vendor/golang.org/x/net/lex/httplex/httplex.go @@ -10,8 +10,11 @@ package httplex import ( + "net" "strings" "unicode/utf8" + + "golang.org/x/net/idna" ) var isTokenTable = [127]bool{ @@ -310,3 +313,39 @@ func ValidHeaderFieldValue(v string) bool { } return true } + +func isASCII(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} + +// PunycodeHostPort returns the IDNA Punycode version +// of the provided "host" or "host:port" string. +func PunycodeHostPort(v string) (string, error) { + if isASCII(v) { + return v, nil + } + + host, port, err := net.SplitHostPort(v) + if err != nil { + // The input 'v' argument was just a "host" argument, + // without a port. This error should not be returned + // to the caller. + host = v + port = "" + } + host, err = idna.ToASCII(host) + if err != nil { + // Non-UTF-8? Not representable in Punycode, in any + // case. + return "", err + } + if port == "" { + return host, nil + } + return net.JoinHostPort(host, port), nil +} diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index d860fcc..1826586 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -91,7 +91,7 @@ var DebugUseAfterFinish = false // It returns two bools; the first indicates whether the page may be viewed at all, // and the second indicates whether sensitive events will be shown. // -// AuthRequest may be replaced by a program to customise its authorisation requirements. +// AuthRequest may be replaced by a program to customize its authorization requirements. // // The default AuthRequest function returns (true, true) if and only if the request // comes from localhost/127.0.0.1/[::1]. @@ -333,7 +333,8 @@ func New(family, title string) Trace { tr.ref() tr.Family, tr.Title = family, title tr.Start = time.Now() - tr.events = make([]event, 0, maxEventsPerTrace) + tr.maxEvents = maxEventsPerTrace + tr.events = tr.eventsBuf[:0] activeMu.RLock() s := activeTraces[tr.Family] @@ -650,8 +651,8 @@ type event struct { Elapsed time.Duration // since previous event in trace NewDay bool // whether this event is on a different day to the previous event Recyclable bool // whether this event was passed via LazyLog - What interface{} // string or fmt.Stringer Sensitive bool // whether this event contains sensitive information + What interface{} // string or fmt.Stringer } // WhenString returns a string representation of the elapsed time of the event. @@ -692,14 +693,17 @@ type trace struct { IsError bool // Append-only sequence of events (modulo discards). - mu sync.RWMutex - events []event + mu sync.RWMutex + events []event + maxEvents int refs int32 // how many buckets this is in recycler func(interface{}) disc discarded // scratch space to avoid allocation finishStack []byte // where finish was called, if DebugUseAfterFinish is set + + eventsBuf [4]event // preallocated buffer in case we only log a few events } func (tr *trace) reset() { @@ -711,11 +715,15 @@ func (tr *trace) reset() { tr.traceID = 0 tr.spanID = 0 tr.IsError = false + tr.maxEvents = 0 tr.events = nil tr.refs = 0 tr.recycler = nil tr.disc = 0 tr.finishStack = nil + for i := range tr.eventsBuf { + tr.eventsBuf[i] = event{} + } } // delta returns the elapsed time since the last event or the trace start, @@ -753,11 +761,11 @@ func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { e := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive} tr.mu.Lock() e.Elapsed, e.NewDay = tr.delta(e.When) - if len(tr.events) < cap(tr.events) { + if len(tr.events) < tr.maxEvents { tr.events = append(tr.events, e) } else { // Discard the middle events. - di := int((cap(tr.events) - 1) / 2) + di := int((tr.maxEvents - 1) / 2) if d, ok := tr.events[di].What.(*discarded); ok { (*d)++ } else { @@ -777,7 +785,7 @@ func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { go tr.recycler(tr.events[di+1].What) } copy(tr.events[di+1:], tr.events[di+2:]) - tr.events[cap(tr.events)-1] = e + tr.events[tr.maxEvents-1] = e } tr.mu.Unlock() } @@ -803,7 +811,7 @@ func (tr *trace) SetTraceInfo(traceID, spanID uint64) { func (tr *trace) SetMaxEvents(m int) { // Always keep at least three events: first, discarded count, last. if len(tr.events) == 0 && m > 3 { - tr.events = make([]event, 0, m) + tr.maxEvents = m } } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index 4b6ff2a..4a13639 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -6,8 +6,6 @@ package unix -const _SYS_dup = SYS_DUP3 - //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index 440f54e..8119fde 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -7,13 +7,6 @@ package unix -// Linux introduced getdents64 syscall for N64 ABI only in 3.10 -// (May 21 2013, rev dec33abaafc89bcbd78f85fad0513170415a26d5), -// to support older kernels, we have to use getdents for mips64. -// Also note that struct dirent is different for these two. -// Lookup linux_dirent{,64} in kernel source code for details. -const _SYS_getdents = SYS_GETDENTS - //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index eb489b1..acb74b1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -72,18 +72,20 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, return origlen - len(buf), count, names } -func pipe() (r uintptr, w uintptr, err uintptr) +//sysnb pipe(p *[2]_C_int) (n int, err error) func Pipe(p []int) (err error) { if len(p) != 2 { return EINVAL } - r0, w0, e1 := pipe() - if e1 != 0 { - err = syscall.Errno(e1) + var pp [2]_C_int + n, err := pipe(&pp) + if n != 0 { + return err } - p[0], p[1] = int(r0), int(w0) - return + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return nil } func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { @@ -269,24 +271,34 @@ func (w WaitStatus) StopSignal() syscall.Signal { func (w WaitStatus) TrapCause() int { return -1 } -func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr) +//sys wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error) -func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { - r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage) - if e1 != 0 { - err = syscall.Errno(e1) +func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) { + var status _C_int + rpid, err := wait4(int32(pid), &status, options, rusage) + wpid := int(rpid) + if wpid == -1 { + return wpid, err + } + if wstatus != nil { + *wstatus = WaitStatus(status) } - return int(r0), err + return wpid, nil } -func gethostname() (name string, err uintptr) +//sys gethostname(buf []byte) (n int, err error) func Gethostname() (name string, err error) { - name, e1 := gethostname() - if e1 != 0 { - err = syscall.Errno(e1) + var buf [MaxHostNameLen]byte + n, err := gethostname(buf[:]) + if n != 0 { + return "", err } - return name, err + n = clen(buf[:]) + if n < 1 { + return "", EFAULT + } + return string(buf[:n]), nil } //sys utimes(path string, times *[2]Timeval) (err error) diff --git a/vendor/golang.org/x/sys/unix/types_solaris.go b/vendor/golang.org/x/sys/unix/types_solaris.go index 6ad50ea..c5d5c8f 100644 --- a/vendor/golang.org/x/sys/unix/types_solaris.go +++ b/vendor/golang.org/x/sys/unix/types_solaris.go @@ -22,6 +22,7 @@ package unix #define __USE_LEGACY_PROTOTYPES__ // iovec #include #include +#include #include #include #include @@ -81,6 +82,7 @@ const ( sizeofLong = C.sizeof_long sizeofLongLong = C.sizeof_longlong PathMax = C.PATH_MAX + MaxHostNameLen = C.MAXHOSTNAMELEN ) // Basic types diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 4326427..c0ecfc0 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -10,10 +10,13 @@ import ( "unsafe" ) +//go:cgo_import_dynamic libc_pipe pipe "libc.so" //go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so" //go:cgo_import_dynamic libc_getcwd getcwd "libc.so" //go:cgo_import_dynamic libc_getgroups getgroups "libc.so" //go:cgo_import_dynamic libc_setgroups setgroups "libc.so" +//go:cgo_import_dynamic libc_wait4 wait4 "libc.so" +//go:cgo_import_dynamic libc_gethostname gethostname "libc.so" //go:cgo_import_dynamic libc_utimes utimes "libc.so" //go:cgo_import_dynamic libc_utimensat utimensat "libc.so" //go:cgo_import_dynamic libc_fcntl fcntl "libc.so" @@ -125,10 +128,13 @@ import ( //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" //go:cgo_import_dynamic libc_sysconf sysconf "libc.so" +//go:linkname procpipe libc_pipe //go:linkname procgetsockname libc_getsockname //go:linkname procGetcwd libc_getcwd //go:linkname procgetgroups libc_getgroups //go:linkname procsetgroups libc_setgroups +//go:linkname procwait4 libc_wait4 +//go:linkname procgethostname libc_gethostname //go:linkname procutimes libc_utimes //go:linkname procutimensat libc_utimensat //go:linkname procfcntl libc_fcntl @@ -241,10 +247,13 @@ import ( //go:linkname procsysconf libc_sysconf var ( + procpipe, procgetsockname, procGetcwd, procgetgroups, procsetgroups, + procwait4, + procgethostname, procutimes, procutimensat, procfcntl, @@ -357,6 +366,15 @@ var ( procsysconf syscallFunc ) +func pipe(p *[2]_C_int) (n int, err error) { + r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe)), 1, uintptr(unsafe.Pointer(p)), 0, 0, 0, 0, 0) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) if e1 != 0 { @@ -395,6 +413,28 @@ func setgroups(ngid int, gid *_Gid_t) (err error) { return } +func wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwait4)), 4, uintptr(pid), uintptr(unsafe.Pointer(statusp)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int32(r0) + if e1 != 0 { + err = e1 + } + return +} + +func gethostname(buf []byte) (n int, err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgethostname)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0, 0, 0, 0) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + func utimes(path string, times *[2]Timeval) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index b3b928a..02777e4 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -1,6 +1,6 @@ // +build amd64,solaris // Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_solaris.go +// cgo -godefs types_solaris.go | go run mkpost.go package unix @@ -11,6 +11,7 @@ const ( sizeofLong = 0x8 sizeofLongLong = 0x8 PathMax = 0x400 + MaxHostNameLen = 0x100 ) type ( diff --git a/vendor/golang.org/x/text/internal/gen/code.go b/vendor/golang.org/x/text/internal/gen/code.go index ca917d2..2202c9f 100644 --- a/vendor/golang.org/x/text/internal/gen/code.go +++ b/vendor/golang.org/x/text/internal/gen/code.go @@ -187,6 +187,7 @@ func (w *CodeWriter) writeValue(v reflect.Value) { // WriteString writes a string literal. func (w *CodeWriter) WriteString(s string) { + s = strings.Replace(s, `\`, `\\`, -1) io.WriteString(w.Hash, s) // content hash w.Size += len(s) diff --git a/vendor/golang.org/x/text/internal/gen/gen.go b/vendor/golang.org/x/text/internal/gen/gen.go index dfaa278..9eb2987 100644 --- a/vendor/golang.org/x/text/internal/gen/gen.go +++ b/vendor/golang.org/x/text/internal/gen/gen.go @@ -22,6 +22,7 @@ import ( "bytes" "flag" "fmt" + "go/build" "go/format" "io" "io/ioutil" @@ -30,6 +31,7 @@ import ( "os" "path" "path/filepath" + "sync" "unicode" "golang.org/x/text/unicode/cldr" @@ -48,12 +50,6 @@ var ( cldrVersion = flag.String("cldr", getEnv("CLDR_VERSION", cldr.Version), "cldr version to use") - // Allow an environment variable to specify the local directory. - // go generate doesn't allow specifying arguments; this is a useful - // alternative to specifying a local mirror. - localDir = flag.String("local", - os.Getenv("UNICODE_DIR"), - "directory containing local data files; for debugging only.") ) func getEnv(name, def string) string { @@ -87,9 +83,12 @@ func CLDRVersion() string { return *cldrVersion } -// IsLocal reports whether the user specified a local directory. +// IsLocal reports whether data files are available locally. func IsLocal() bool { - return *localDir != "" + if _, err := os.Stat(localReadmeFile()); err != nil { + return false + } + return true } // OpenUCDFile opens the requested UCD file. The file is specified relative to @@ -124,29 +123,78 @@ func OpenIANAFile(path string) io.ReadCloser { return Open(*iana, "iana", path) } +var ( + dirMutex sync.Mutex + localDir string +) + +const permissions = 0755 + +func localReadmeFile() string { + p, err := build.Import("golang.org/x/text", "", build.FindOnly) + if err != nil { + log.Fatalf("Could not locate package: %v", err) + } + return filepath.Join(p.Dir, "DATA", "README") +} + +func getLocalDir() string { + dirMutex.Lock() + defer dirMutex.Unlock() + + readme := localReadmeFile() + dir := filepath.Dir(readme) + if _, err := os.Stat(readme); err != nil { + if err := os.MkdirAll(dir, permissions); err != nil { + log.Fatalf("Could not create directory: %v", err) + } + ioutil.WriteFile(readme, []byte(readmeTxt), permissions) + } + return dir +} + +const readmeTxt = `Generated by golang.org/x/text/internal/gen. DO NOT EDIT. + +This directory contains downloaded files used to generate the various tables +in the golang.org/x/text subrepo. + +Note that the language subtag repo (iana/assignments/language-subtag-registry) +and all other times in the iana subdirectory are not versioned and will need +to be periodically manually updated. The easiest way to do this is to remove +the entire iana directory. This is mostly of concern when updating the language +package. +` + // Open opens subdir/path if a local directory is specified and the file exists, // where subdir is a directory relative to the local root, or fetches it from // urlRoot/path otherwise. It will call log.Fatal if there are any errors. func Open(urlRoot, subdir, path string) io.ReadCloser { - if *localDir != "" { - path = filepath.FromSlash(path) - if f, err := os.Open(filepath.Join(*localDir, subdir, path)); err == nil { - return f - } - } - return get(urlRoot, path) + file := filepath.Join(getLocalDir(), subdir, filepath.FromSlash(path)) + return open(file, urlRoot, path) } func openUnicode(path string) io.ReadCloser { - if *localDir != "" { - path = filepath.FromSlash(path) - f, err := os.Open(filepath.Join(*localDir, path)) - if err != nil { - log.Fatal(err) - } + file := filepath.Join(getLocalDir(), filepath.FromSlash(path)) + return open(file, *url, path) +} + +// TODO: automatically periodically update non-versioned files. + +func open(file, urlRoot, path string) io.ReadCloser { + if f, err := os.Open(file); err == nil { return f } - return get(*url, path) + r := get(urlRoot, path) + defer r.Close() + b, err := ioutil.ReadAll(r) + if err != nil { + log.Fatalf("Could not download file: %v", err) + } + os.MkdirAll(filepath.Dir(file), permissions) + if err := ioutil.WriteFile(file, b, permissions); err != nil { + log.Fatalf("Could not create file: %v", err) + } + return ioutil.NopCloser(bytes.NewReader(b)) } func get(root, path string) io.ReadCloser { diff --git a/vendor/golang.org/x/text/internal/ucd/ucd.go b/vendor/golang.org/x/text/internal/ucd/ucd.go index 2b0d1a1..60b27d5 100644 --- a/vendor/golang.org/x/text/internal/ucd/ucd.go +++ b/vendor/golang.org/x/text/internal/ucd/ucd.go @@ -78,6 +78,14 @@ func Part(f func(p *Parser)) Option { } } +// The CommentHandler option passes comments that are on a line by itself to +// a given handler. +func CommentHandler(f func(s string)) Option { + return func(p *Parser) { + p.commentHandler = f + } +} + // A Parser parses Unicode Character Database (UCD) files. type Parser struct { scanner *bufio.Scanner @@ -92,7 +100,8 @@ type Parser struct { parsedRange bool rangeStart, rangeEnd rune - partHandler func(p *Parser) + partHandler func(p *Parser) + commentHandler func(s string) } func (p *Parser) setError(err error) { @@ -138,7 +147,13 @@ func (p *Parser) Next() bool { for p.scanner.Scan() { b := p.scanner.Bytes() - if len(b) == 0 || b[0] == '#' { + if len(b) == 0 { + continue + } + if b[0] == '#' { + if p.commentHandler != nil { + p.commentHandler(strings.TrimSpace(string(b[1:]))) + } continue } diff --git a/vendor/golang.org/x/text/transform/transform.go b/vendor/golang.org/x/text/transform/transform.go index 0c2f730..fe47b9b 100644 --- a/vendor/golang.org/x/text/transform/transform.go +++ b/vendor/golang.org/x/text/transform/transform.go @@ -24,6 +24,10 @@ var ( // complete the transformation. ErrShortSrc = errors.New("transform: short source buffer") + // ErrEndOfSpan means that the input and output (the transformed input) + // are not identical. + ErrEndOfSpan = errors.New("transform: input and output are not identical") + // errInconsistentByteCount means that Transform returned success (nil // error) but also returned nSrc inconsistent with the src argument. errInconsistentByteCount = errors.New("transform: inconsistent byte count returned") @@ -60,6 +64,41 @@ type Transformer interface { Reset() } +// SpanningTransformer extends the Transformer interface with a Span method +// that determines how much of the input already conforms to the Transformer. +type SpanningTransformer interface { + Transformer + + // Span returns a position in src such that transforming src[:n] results in + // identical output src[:n] for these bytes. It does not necessarily return + // the largest such n. The atEOF argument tells whether src represents the + // last bytes of the input. + // + // Callers should always account for the n bytes consumed before + // considering the error err. + // + // A nil error means that all input bytes are known to be identical to the + // output produced by the Transformer. A nil error can be be returned + // regardless of whether atEOF is true. If err is nil, then then n must + // equal len(src); the converse is not necessarily true. + // + // ErrEndOfSpan means that the Transformer output may differ from the + // input after n bytes. Note that n may be len(src), meaning that the output + // would contain additional bytes after otherwise identical output. + // ErrShortSrc means that src had insufficient data to determine whether the + // remaining bytes would change. Other than the error conditions listed + // here, implementations are free to report other errors that arise. + // + // Calling Span can modify the Transformer state as a side effect. In + // effect, it does the transformation just as calling Transform would, only + // without copying to a destination buffer and only up to a point it can + // determine the input and output bytes are the same. This is obviously more + // limited than calling Transform, but can be more efficient in terms of + // copying and allocating buffers. Calls to Span and Transform may be + // interleaved. + Span(src []byte, atEOF bool) (n int, err error) +} + // NopResetter can be embedded by implementations of Transformer to add a nop // Reset method. type NopResetter struct{} @@ -278,6 +317,10 @@ func (nop) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { return n, n, err } +func (nop) Span(src []byte, atEOF bool) (n int, err error) { + return len(src), nil +} + type discard struct{ NopResetter } func (discard) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { @@ -289,8 +332,8 @@ var ( // by consuming all bytes and writing nothing. Discard Transformer = discard{} - // Nop is a Transformer that copies src to dst. - Nop Transformer = nop{} + // Nop is a SpanningTransformer that copies src to dst. + Nop SpanningTransformer = nop{} ) // chain is a sequence of links. A chain with N Transformers has N+1 links and @@ -358,6 +401,8 @@ func (c *chain) Reset() { } } +// TODO: make chain use Span (is going to be fun to implement!) + // Transform applies the transformers of c in sequence. func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { // Set up src and dst in the chain. @@ -448,8 +493,7 @@ func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err erro return dstL.n, srcL.p, err } -// RemoveFunc returns a Transformer that removes from the input all runes r for -// which f(r) is true. Illegal bytes in the input are replaced by RuneError. +// Deprecated: use runes.Remove instead. func RemoveFunc(f func(r rune) bool) Transformer { return removeF(f) } diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go index eb5596f..bba8ce9 100644 --- a/vendor/golang.org/x/text/unicode/norm/normalize.go +++ b/vendor/golang.org/x/text/unicode/norm/normalize.go @@ -8,7 +8,11 @@ // Package norm contains types and functions for normalizing Unicode strings. package norm // import "golang.org/x/text/unicode/norm" -import "unicode/utf8" +import ( + "unicode/utf8" + + "golang.org/x/text/transform" +) // A Form denotes a canonical representation of Unicode code points. // The Unicode-defined normalization and equivalence forms are: @@ -263,6 +267,34 @@ func (f Form) QuickSpan(b []byte) int { return n } +// Span implements transform.SpanningTransformer. It returns a boundary n such +// that b[0:n] == f(b[0:n]). It is not guaranteed to return the largest such n. +func (f Form) Span(b []byte, atEOF bool) (n int, err error) { + n, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), atEOF) + if n < len(b) { + if !ok { + err = transform.ErrEndOfSpan + } else { + err = transform.ErrShortSrc + } + } + return n, err +} + +// SpanString returns a boundary n such that s[0:n] == f(s[0:n]). +// It is not guaranteed to return the largest such n. +func (f Form) SpanString(s string, atEOF bool) (n int, err error) { + n, ok := formTable[f].quickSpan(inputString(s), 0, len(s), atEOF) + if n < len(s) { + if !ok { + err = transform.ErrEndOfSpan + } else { + err = transform.ErrShortSrc + } + } + return n, err +} + // quickSpan returns a boundary n such that src[0:n] == f(src[0:n]) and // whether any non-normalized parts were found. If atEOF is false, n will // not point past the last segment if this segment might be become @@ -321,7 +353,7 @@ func (f *formInfo) quickSpan(src input, i, end int, atEOF bool) (n int, ok bool) return lastSegStart, false } -// QuickSpanString returns a boundary n such that b[0:n] == f(s[0:n]). +// QuickSpanString returns a boundary n such that s[0:n] == f(s[0:n]). // It is not guaranteed to return the largest such n. func (f Form) QuickSpanString(s string) int { n, _ := formTable[f].quickSpan(inputString(s), 0, len(s), true) diff --git a/vendor/google.golang.org/api/gensupport/json.go b/vendor/google.golang.org/api/gensupport/json.go index dd7bcd2..53331b7 100644 --- a/vendor/google.golang.org/api/gensupport/json.go +++ b/vendor/google.golang.org/api/gensupport/json.go @@ -12,13 +12,13 @@ import ( ) // MarshalJSON returns a JSON encoding of schema containing only selected fields. -// A field is selected if: -// * it has a non-empty value, or -// * its field name is present in forceSendFields, and -// * it is not a nil pointer or nil interface. +// A field is selected if any of the following is true: +// * it has a non-empty value +// * its field name is present in forceSendFields and it is not a nil pointer or nil interface +// * its field name is present in nullFields. // The JSON key for each selected field is taken from the field's json: struct tag. -func MarshalJSON(schema interface{}, forceSendFields []string) ([]byte, error) { - if len(forceSendFields) == 0 { +func MarshalJSON(schema interface{}, forceSendFields, nullFields []string) ([]byte, error) { + if len(forceSendFields) == 0 && len(nullFields) == 0 { return json.Marshal(schema) } @@ -26,15 +26,19 @@ func MarshalJSON(schema interface{}, forceSendFields []string) ([]byte, error) { for _, f := range forceSendFields { mustInclude[f] = struct{}{} } + useNull := make(map[string]struct{}) + for _, f := range nullFields { + useNull[f] = struct{}{} + } - dataMap, err := schemaToMap(schema, mustInclude) + dataMap, err := schemaToMap(schema, mustInclude, useNull) if err != nil { return nil, err } return json.Marshal(dataMap) } -func schemaToMap(schema interface{}, mustInclude map[string]struct{}) (map[string]interface{}, error) { +func schemaToMap(schema interface{}, mustInclude, useNull map[string]struct{}) (map[string]interface{}, error) { m := make(map[string]interface{}) s := reflect.ValueOf(schema) st := s.Type() @@ -54,6 +58,14 @@ func schemaToMap(schema interface{}, mustInclude map[string]struct{}) (map[strin v := s.Field(i) f := st.Field(i) + + if _, ok := useNull[f.Name]; ok { + if !isEmptyValue(v) { + return nil, fmt.Errorf("field %q in NullFields has non-empty value", f.Name) + } + m[tag.apiName] = nil + continue + } if !includeField(v, f, mustInclude) { continue } diff --git a/vendor/google.golang.org/api/internal/settings.go b/vendor/google.golang.org/api/internal/settings.go index eb9300c..976280b 100644 --- a/vendor/google.golang.org/api/internal/settings.go +++ b/vendor/google.golang.org/api/internal/settings.go @@ -11,11 +11,12 @@ import ( // DialSettings holds information needed to establish a connection with a // Google API service. type DialSettings struct { - Endpoint string - Scopes []string - TokenSource oauth2.TokenSource - UserAgent string - HTTPClient *http.Client - GRPCDialOpts []grpc.DialOption - GRPCConn *grpc.ClientConn + Endpoint string + Scopes []string + ServiceAccountJSONFilename string // if set, TokenSource is ignored. + TokenSource oauth2.TokenSource + UserAgent string + HTTPClient *http.Client + GRPCDialOpts []grpc.DialOption + GRPCConn *grpc.ClientConn } diff --git a/vendor/google.golang.org/api/iterator/iterator.go b/vendor/google.golang.org/api/iterator/iterator.go new file mode 100644 index 0000000..0640c82 --- /dev/null +++ b/vendor/google.golang.org/api/iterator/iterator.go @@ -0,0 +1,231 @@ +// 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 iterator provides support for standard Google API iterators. +// See https://github.com/GoogleCloudPlatform/gcloud-golang/wiki/Iterator-Guidelines. +package iterator + +import ( + "errors" + "fmt" + "reflect" +) + +// Done is returned by an iterator's Next method when the iteration is +// complete; when there are no more items to return. +var Done = errors.New("no more items in iterator") + +// We don't support mixed calls to Next and NextPage because they play +// with the paging state in incompatible ways. +var errMixed = errors.New("iterator: Next and NextPage called on same iterator") + +// PageInfo contains information about an iterator's paging state. +type PageInfo struct { + // Token is the token used to retrieve the next page of items from the + // API. You may set Token immediately after creating an iterator to + // begin iteration at a particular point. If Token is the empty string, + // the iterator will begin with the first eligible item. + // + // The result of setting Token after the first call to Next is undefined. + // + // After the underlying API method is called to retrieve a page of items, + // Token is set to the next-page token in the response. + Token string + + // MaxSize is the maximum number of items returned by a call to the API. + // Set MaxSize as a hint to optimize the buffering behavior of the iterator. + // If zero, the page size is determined by the underlying service. + // + // Use Pager to retrieve a page of a specific, exact size. + MaxSize int + + // The error state of the iterator. Manipulated by PageInfo.next and Pager. + // This is a latch: it starts as nil, and once set should never change. + err error + + // If true, no more calls to fetch should be made. Set to true when fetch + // returns an empty page token. The iterator is Done when this is true AND + // the buffer is empty. + atEnd bool + + // Function that fetches a page from the underlying service. It should pass + // the pageSize and pageToken arguments to the service, fill the buffer + // with the results from the call, and return the next-page token returned + // by the service. The function must not remove any existing items from the + // buffer. If the underlying RPC takes an int32 page size, pageSize should + // be silently truncated. + fetch func(pageSize int, pageToken string) (nextPageToken string, err error) + + // Function that clears the iterator's buffer, returning any currently buffered items. + bufLen func() int + + // Function that returns the buffer, after setting the buffer variable to nil. + takeBuf func() interface{} + + // Set to true on first call to PageInfo.next or Pager.NextPage. Used to check + // for calls to both Next and NextPage with the same iterator. + nextCalled, nextPageCalled bool +} + +// NewPageInfo exposes internals for iterator implementations. +// It is not a stable interface. +var NewPageInfo = newPageInfo + +// If an iterator can support paging, its iterator-creating method should call +// this (via the NewPageInfo variable above). +// +// The fetch, bufLen and takeBuf arguments provide access to the +// iterator's internal slice of buffered items. They behave as described in +// PageInfo, above. +// +// The return value is the PageInfo.next method bound to the returned PageInfo value. +// (Returning it avoids exporting PageInfo.next.) +func newPageInfo(fetch func(int, string) (string, error), bufLen func() int, takeBuf func() interface{}) (*PageInfo, func() error) { + pi := &PageInfo{ + fetch: fetch, + bufLen: bufLen, + takeBuf: takeBuf, + } + return pi, pi.next +} + +// Remaining returns the number of items available before the iterator makes another API call. +func (pi *PageInfo) Remaining() int { return pi.bufLen() } + +// next provides support for an iterator's Next function. An iterator's Next +// should return the error returned by next if non-nil; else it can assume +// there is at least one item in its buffer, and it should return that item and +// remove it from the buffer. +func (pi *PageInfo) next() error { + pi.nextCalled = true + if pi.err != nil { // Once we get an error, always return it. + // TODO(jba): fix so users can retry on transient errors? Probably not worth it. + return pi.err + } + if pi.nextPageCalled { + pi.err = errMixed + return pi.err + } + // Loop until we get some items or reach the end. + for pi.bufLen() == 0 && !pi.atEnd { + if err := pi.fill(pi.MaxSize); err != nil { + pi.err = err + return pi.err + } + if pi.Token == "" { + pi.atEnd = true + } + } + // Either the buffer is non-empty or pi.atEnd is true (or both). + if pi.bufLen() == 0 { + // The buffer is empty and pi.atEnd is true, i.e. the service has no + // more items. + pi.err = Done + } + return pi.err +} + +// Call the service to fill the buffer, using size and pi.Token. Set pi.Token to the +// next-page token returned by the call. +// If fill returns a non-nil error, the buffer will be empty. +func (pi *PageInfo) fill(size int) error { + tok, err := pi.fetch(size, pi.Token) + if err != nil { + pi.takeBuf() // clear the buffer + return err + } + pi.Token = tok + return nil +} + +// Pageable is implemented by iterators that support paging. +type Pageable interface { + // PageInfo returns paging information associated with the iterator. + PageInfo() *PageInfo +} + +// Pager supports retrieving iterator items a page at a time. +type Pager struct { + pageInfo *PageInfo + pageSize int +} + +// NewPager returns a pager that uses iter. Calls to its NextPage method will +// obtain exactly pageSize items, unless fewer remain. The pageToken argument +// indicates where to start the iteration. Pass the empty string to start at +// the beginning, or pass a token retrieved from a call to Pager.NextPage. +// +// If you use an iterator with a Pager, you must not call Next on the iterator. +func NewPager(iter Pageable, pageSize int, pageToken string) *Pager { + p := &Pager{ + pageInfo: iter.PageInfo(), + pageSize: pageSize, + } + p.pageInfo.Token = pageToken + if pageSize <= 0 { + p.pageInfo.err = errors.New("iterator: page size must be positive") + } + return p +} + +// NextPage retrieves a sequence of items from the iterator and appends them +// to slicep, which must be a pointer to a slice of the iterator's item type. +// Exactly p.pageSize items will be appended, unless fewer remain. +// +// The first return value is the page token to use for the next page of items. +// If empty, there are no more pages. Aside from checking for the end of the +// iteration, the returned page token is only needed if the iteration is to be +// resumed a later time, in another context (possibly another process). +// +// The second return value is non-nil if an error occurred. It will never be +// the special iterator sentinel value Done. To recognize the end of the +// iteration, compare nextPageToken to the empty string. +// +// It is possible for NextPage to return a single zero-length page along with +// an empty page token when there are no more items in the iteration. +func (p *Pager) NextPage(slicep interface{}) (nextPageToken string, err error) { + p.pageInfo.nextPageCalled = true + if p.pageInfo.err != nil { + return "", p.pageInfo.err + } + if p.pageInfo.nextCalled { + p.pageInfo.err = errMixed + return "", p.pageInfo.err + } + if p.pageInfo.bufLen() > 0 { + return "", errors.New("must call NextPage with an empty buffer") + } + // The buffer must be empty here, so takeBuf is a no-op. We call it just to get + // the buffer's type. + wantSliceType := reflect.PtrTo(reflect.ValueOf(p.pageInfo.takeBuf()).Type()) + if slicep == nil { + return "", errors.New("nil passed to Pager.NextPage") + } + vslicep := reflect.ValueOf(slicep) + if vslicep.Type() != wantSliceType { + return "", fmt.Errorf("slicep should be of type %s, got %T", wantSliceType, slicep) + } + for p.pageInfo.bufLen() < p.pageSize { + if err := p.pageInfo.fill(p.pageSize - p.pageInfo.bufLen()); err != nil { + p.pageInfo.err = err + return "", p.pageInfo.err + } + if p.pageInfo.Token == "" { + break + } + } + e := vslicep.Elem() + e.Set(reflect.AppendSlice(e, reflect.ValueOf(p.pageInfo.takeBuf()))) + return p.pageInfo.Token, nil +} diff --git a/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go b/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go index 6b18fad..b1a7694 100644 --- a/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go +++ b/vendor/google.golang.org/api/oauth2/v2/oauth2-gen.go @@ -131,12 +131,20 @@ type Jwk struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Keys") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Jwk) MarshalJSON() ([]byte, error) { type noMethod Jwk raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } type JwkKeys struct { @@ -159,12 +167,20 @@ type JwkKeys struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Alg") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *JwkKeys) MarshalJSON() ([]byte, error) { type noMethod JwkKeys raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } type Tokeninfo struct { @@ -212,12 +228,20 @@ type Tokeninfo struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "AccessType") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Tokeninfo) MarshalJSON() ([]byte, error) { type noMethod Tokeninfo raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } type Userinfoplus struct { @@ -270,12 +294,20 @@ type Userinfoplus struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Email") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Userinfoplus) MarshalJSON() ([]byte, error) { type noMethod Userinfoplus raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // method id "oauth2.getCertForOpenIdConnect": diff --git a/vendor/google.golang.org/api/option/option.go b/vendor/google.golang.org/api/option/option.go index 556a6df..b935e6d 100644 --- a/vendor/google.golang.org/api/option/option.go +++ b/vendor/google.golang.org/api/option/option.go @@ -26,6 +26,21 @@ func (w withTokenSource) Apply(o *internal.DialSettings) { o.TokenSource = w.ts } +// WithServiceAccountFile returns a ClientOption that uses a Google service +// account credentials file to authenticate. +// Use WithTokenSource with a token source created from +// golang.org/x/oauth2/google.JWTConfigFromJSON +// if reading the file from disk is not an option. +func WithServiceAccountFile(filename string) ClientOption { + return withServiceAccountFile(filename) +} + +type withServiceAccountFile string + +func (w withServiceAccountFile) Apply(o *internal.DialSettings) { + o.ServiceAccountJSONFilename = string(w) +} + // WithEndpoint returns a ClientOption that overrides the default endpoint // to be used for a service. func WithEndpoint(url string) ClientOption { diff --git a/vendor/google.golang.org/api/storage/v1/storage-api.json b/vendor/google.golang.org/api/storage/v1/storage-api.json index 8d9118b..69bdf27 100644 --- a/vendor/google.golang.org/api/storage/v1/storage-api.json +++ b/vendor/google.golang.org/api/storage/v1/storage-api.json @@ -1,11 +1,11 @@ { "kind": "discovery#restDescription", - "etag": "\"C5oy1hgQsABtYOYIOXWcR3BgYqU/gtcWNCypj7VTDxrk1rvvuniNHZo\"", + "etag": "\"C5oy1hgQsABtYOYIOXWcR3BgYqU/HhsBn9wwz5D-d92BzzyinZOo-SY\"", "discoveryVersion": "v1", "id": "storage:v1", "name": "storage", "version": "v1", - "revision": "20160802", + "revision": "20160923", "title": "Cloud Storage JSON API", "description": "Stores and retrieves potentially large, immutable data objects.", "ownerDomain": "google.com", @@ -150,15 +150,6 @@ "$ref": "ObjectAccessControl" } }, - "encryption": { - "type": "object", - "description": "Encryption configuration used by default for newly inserted objects, when no encryption config is specified.", - "properties": { - "default_kms_key_name": { - "type": "string" - } - } - }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the bucket." @@ -621,10 +612,6 @@ "description": "The kind of item this is. For objects, this is always storage#object.", "default": "storage#object" }, - "kmsKeyName": { - "type": "string", - "description": "Cloud KMS Key used to encrypt this object, if the object is encrypted by such a key." - }, "md5Hash": { "type": "string", "description": "MD5 hash of the data; encoded using base64. For more information about using the MD5 hash, see Hashes and ETags: Best Practices." @@ -713,7 +700,13 @@ }, "entity": { "type": "string", - "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com." + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + } }, "entityId": { "type": "string", @@ -725,7 +718,7 @@ }, "generation": { "type": "string", - "description": "The content generation of the object.", + "description": "The content generation of the object, if applied to an object.", "format": "int64" }, "id": { @@ -739,7 +732,7 @@ }, "object": { "type": "string", - "description": "The name of the object." + "description": "The name of the object, if applied to an object." }, "projectTeam": { "type": "object", @@ -757,7 +750,13 @@ }, "role": { "type": "string", - "description": "The access permission for the entity." + "description": "The access permission for the entity.", + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + } }, "selfLink": { "type": "string", @@ -774,7 +773,7 @@ "type": "array", "description": "The list of items.", "items": { - "type": "any" + "$ref": "ObjectAccessControl" } }, "kind": { @@ -1971,11 +1970,6 @@ "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" - }, - "kmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" } }, "parameterOrder": [ @@ -2314,11 +2308,6 @@ "format": "int64", "location": "query" }, - "kmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" - }, "name": { "type": "string", "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", @@ -2570,11 +2559,6 @@ "required": true, "location": "path" }, - "destinationKmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" - }, "destinationObject": { "type": "string", "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", diff --git a/vendor/google.golang.org/api/storage/v1/storage-gen.go b/vendor/google.golang.org/api/storage/v1/storage-gen.go index a74cad2..a7b6982 100644 --- a/vendor/google.golang.org/api/storage/v1/storage-gen.go +++ b/vendor/google.golang.org/api/storage/v1/storage-gen.go @@ -169,10 +169,6 @@ type Bucket struct { // when no ACL is provided. DefaultObjectAcl []*ObjectAccessControl `json:"defaultObjectAcl,omitempty"` - // Encryption: Encryption configuration used by default for newly - // inserted objects, when no encryption config is specified. - Encryption *BucketEncryption `json:"encryption,omitempty"` - // Etag: HTTP 1.1 Entity tag for the bucket. Etag string `json:"etag,omitempty"` @@ -245,12 +241,20 @@ type Bucket struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Acl") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Bucket) MarshalJSON() ([]byte, error) { type noMethod Bucket raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } type BucketCors struct { @@ -280,32 +284,20 @@ type BucketCors struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "MaxAgeSeconds") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketCors) MarshalJSON() ([]byte, error) { type noMethod BucketCors raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) -} - -// BucketEncryption: Encryption configuration used by default for newly -// inserted objects, when no encryption config is specified. -type BucketEncryption struct { - DefaultKmsKeyName string `json:"default_kms_key_name,omitempty"` - - // ForceSendFields is a list of field names (e.g. "DefaultKmsKeyName") - // to unconditionally include in API requests. By default, fields with - // empty values are omitted from API requests. However, any non-pointer, - // non-interface field appearing in ForceSendFields will be sent to the - // server regardless of whether the field is empty or not. This may be - // used to include empty fields in Patch requests. - ForceSendFields []string `json:"-"` -} - -func (s *BucketEncryption) MarshalJSON() ([]byte, error) { - type noMethod BucketEncryption - raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketLifecycle: The bucket's lifecycle configuration. See lifecycle @@ -322,12 +314,20 @@ type BucketLifecycle struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Rule") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketLifecycle) MarshalJSON() ([]byte, error) { type noMethod BucketLifecycle raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } type BucketLifecycleRule struct { @@ -344,12 +344,20 @@ type BucketLifecycleRule struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Action") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketLifecycleRule) MarshalJSON() ([]byte, error) { type noMethod BucketLifecycleRule raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketLifecycleRuleAction: The action to take. @@ -364,12 +372,20 @@ type BucketLifecycleRuleAction struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Type") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketLifecycleRuleAction) MarshalJSON() ([]byte, error) { type noMethod BucketLifecycleRuleAction raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketLifecycleRuleCondition: The condition(s) under which the action @@ -401,12 +417,20 @@ type BucketLifecycleRuleCondition struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Age") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketLifecycleRuleCondition) MarshalJSON() ([]byte, error) { type noMethod BucketLifecycleRuleCondition raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketLogging: The bucket's logging configuration, which defines the @@ -427,12 +451,20 @@ type BucketLogging struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "LogBucket") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketLogging) MarshalJSON() ([]byte, error) { type noMethod BucketLogging raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketOwner: The owner of the bucket. This is always the project @@ -451,12 +483,20 @@ type BucketOwner struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Entity") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketOwner) MarshalJSON() ([]byte, error) { type noMethod BucketOwner raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketVersioning: The bucket's versioning configuration. @@ -472,12 +512,20 @@ type BucketVersioning struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Enabled") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketVersioning) MarshalJSON() ([]byte, error) { type noMethod BucketVersioning raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketWebsite: The bucket's website configuration, controlling how @@ -503,12 +551,21 @@ type BucketWebsite struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "MainPageSuffix") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` } func (s *BucketWebsite) MarshalJSON() ([]byte, error) { type noMethod BucketWebsite raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketAccessControl: An access-control entry. @@ -572,12 +629,20 @@ type BucketAccessControl struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bucket") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketAccessControl) MarshalJSON() ([]byte, error) { type noMethod BucketAccessControl raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketAccessControlProjectTeam: The project team associated with the @@ -596,12 +661,20 @@ type BucketAccessControlProjectTeam struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ProjectNumber") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketAccessControlProjectTeam) MarshalJSON() ([]byte, error) { type noMethod BucketAccessControlProjectTeam raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // BucketAccessControls: An access-control list. @@ -624,12 +697,20 @@ type BucketAccessControls struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *BucketAccessControls) MarshalJSON() ([]byte, error) { type noMethod BucketAccessControls raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // Buckets: A list of buckets. @@ -657,12 +738,20 @@ type Buckets struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Buckets) MarshalJSON() ([]byte, error) { type noMethod Buckets raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // Channel: An notification channel used to watch for resource changes. @@ -715,12 +804,20 @@ type Channel struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Address") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Channel) MarshalJSON() ([]byte, error) { type noMethod Channel raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ComposeRequest: A Compose request. @@ -742,12 +839,20 @@ type ComposeRequest struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Destination") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *ComposeRequest) MarshalJSON() ([]byte, error) { type noMethod ComposeRequest raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } type ComposeRequestSourceObjects struct { @@ -769,12 +874,20 @@ type ComposeRequestSourceObjects struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Generation") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *ComposeRequestSourceObjects) MarshalJSON() ([]byte, error) { type noMethod ComposeRequestSourceObjects raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ComposeRequestSourceObjectsObjectPreconditions: Conditions that must @@ -793,12 +906,21 @@ type ComposeRequestSourceObjectsObjectPreconditions struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "IfGenerationMatch") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` } func (s *ComposeRequestSourceObjectsObjectPreconditions) MarshalJSON() ([]byte, error) { type noMethod ComposeRequestSourceObjectsObjectPreconditions raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // Object: An object. @@ -856,10 +978,6 @@ type Object struct { // storage#object. Kind string `json:"kind,omitempty"` - // KmsKeyName: Cloud KMS Key used to encrypt this object, if the object - // is encrypted by such a key. - KmsKeyName string `json:"kmsKeyName,omitempty"` - // Md5Hash: MD5 hash of the data; encoded using base64. For more // information about using the MD5 hash, see Hashes and ETags: Best // Practices. @@ -917,12 +1035,20 @@ type Object struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Acl") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Object) MarshalJSON() ([]byte, error) { type noMethod Object raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ObjectCustomerEncryption: Metadata of customer-supplied encryption @@ -941,12 +1067,21 @@ type ObjectCustomerEncryption struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EncryptionAlgorithm") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` } func (s *ObjectCustomerEncryption) MarshalJSON() ([]byte, error) { type noMethod ObjectCustomerEncryption raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ObjectOwner: The owner of the object. This will always be the @@ -965,12 +1100,20 @@ type ObjectOwner struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Entity") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *ObjectOwner) MarshalJSON() ([]byte, error) { type noMethod ObjectOwner raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ObjectAccessControl: An access-control entry. @@ -1007,7 +1150,8 @@ type ObjectAccessControl struct { // Etag: HTTP 1.1 Entity tag for the access-control entry. Etag string `json:"etag,omitempty"` - // Generation: The content generation of the object. + // Generation: The content generation of the object, if applied to an + // object. Generation int64 `json:"generation,omitempty,string"` // Id: The ID of the access-control entry. @@ -1017,7 +1161,7 @@ type ObjectAccessControl struct { // this is always storage#objectAccessControl. Kind string `json:"kind,omitempty"` - // Object: The name of the object. + // Object: The name of the object, if applied to an object. Object string `json:"object,omitempty"` // ProjectTeam: The project team associated with the entity, if any. @@ -1040,12 +1184,20 @@ type ObjectAccessControl struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bucket") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *ObjectAccessControl) MarshalJSON() ([]byte, error) { type noMethod ObjectAccessControl raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ObjectAccessControlProjectTeam: The project team associated with the @@ -1064,18 +1216,26 @@ type ObjectAccessControlProjectTeam struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ProjectNumber") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *ObjectAccessControlProjectTeam) MarshalJSON() ([]byte, error) { type noMethod ObjectAccessControlProjectTeam raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // ObjectAccessControls: An access-control list. type ObjectAccessControls struct { // Items: The list of items. - Items []interface{} `json:"items,omitempty"` + Items []*ObjectAccessControl `json:"items,omitempty"` // Kind: The kind of item this is. For lists of object access control // entries, this is always storage#objectAccessControls. @@ -1092,12 +1252,20 @@ type ObjectAccessControls struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *ObjectAccessControls) MarshalJSON() ([]byte, error) { type noMethod ObjectAccessControls raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // Objects: A list of objects. @@ -1129,12 +1297,20 @@ type Objects struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *Objects) MarshalJSON() ([]byte, error) { type noMethod Objects raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // RewriteResponse: A rewrite response. @@ -1176,12 +1352,20 @@ type RewriteResponse struct { // server regardless of whether the field is empty or not. This may be // used to include empty fields in Patch requests. ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Done") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` } func (s *RewriteResponse) MarshalJSON() ([]byte, error) { type noMethod RewriteResponse raw := noMethod(*s) - return gensupport.MarshalJSON(raw, s.ForceSendFields) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } // method id "storage.bucketAccessControls.delete": @@ -4947,16 +5131,6 @@ func (c *ObjectsComposeCall) IfMetagenerationMatch(ifMetagenerationMatch int64) return c } -// KmsKeyName sets the optional parameter "kmsKeyName": Resource name of -// the Cloud KMS key, of the form -// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, -// that will be used to encrypt the object. Overrides the object -// metadata's kms_key_name value, if any. -func (c *ObjectsComposeCall) KmsKeyName(kmsKeyName string) *ObjectsComposeCall { - c.urlParams_.Set("kmsKeyName", kmsKeyName) - return c -} - // Fields allows partial responses to be retrieved. See // https://developers.google.com/gdata/docs/2.0/basics#PartialResponse // for more information. @@ -5100,11 +5274,6 @@ func (c *ObjectsComposeCall) Do(opts ...googleapi.CallOption) (*Object, error) { // "format": "int64", // "location": "query", // "type": "string" - // }, - // "kmsKeyName": { - // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - // "location": "query", - // "type": "string" // } // }, // "path": "b/{destinationBucket}/o/{destinationObject}/compose", @@ -5980,16 +6149,6 @@ func (c *ObjectsInsertCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch in return c } -// KmsKeyName sets the optional parameter "kmsKeyName": Resource name of -// the Cloud KMS key, of the form -// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, -// that will be used to encrypt the object. Overrides the object -// metadata's kms_key_name value, if any. -func (c *ObjectsInsertCall) KmsKeyName(kmsKeyName string) *ObjectsInsertCall { - c.urlParams_.Set("kmsKeyName", kmsKeyName) - return c -} - // Name sets the optional parameter "name": Name of the object. Required // when the object metadata is not otherwise provided. Overrides the // object metadata's name value, if any. For information about how to @@ -6261,11 +6420,6 @@ func (c *ObjectsInsertCall) Do(opts ...googleapi.CallOption) (*Object, error) { // "location": "query", // "type": "string" // }, - // "kmsKeyName": { - // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - // "location": "query", - // "type": "string" - // }, // "name": { // "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", // "location": "query", @@ -6862,17 +7016,6 @@ func (r *ObjectsService) Rewrite(sourceBucket string, sourceObject string, desti return c } -// DestinationKmsKeyName sets the optional parameter -// "destinationKmsKeyName": Resource name of the Cloud KMS key, of the -// form -// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, -// that will be used to encrypt the object. Overrides the object -// metadata's kms_key_name value, if any. -func (c *ObjectsRewriteCall) DestinationKmsKeyName(destinationKmsKeyName string) *ObjectsRewriteCall { - c.urlParams_.Set("destinationKmsKeyName", destinationKmsKeyName) - return c -} - // DestinationPredefinedAcl sets the optional parameter // "destinationPredefinedAcl": Apply a predefined set of access controls // to the destination object. @@ -7102,11 +7245,6 @@ func (c *ObjectsRewriteCall) Do(opts ...googleapi.CallOption) (*RewriteResponse, // "required": true, // "type": "string" // }, - // "destinationKmsKeyName": { - // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - // "location": "query", - // "type": "string" - // }, // "destinationObject": { // "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", // "location": "path", diff --git a/vendor/google.golang.org/api/transport/dial.go b/vendor/google.golang.org/api/transport/dial.go index a7d058b..c054460 100644 --- a/vendor/google.golang.org/api/transport/dial.go +++ b/vendor/google.golang.org/api/transport/dial.go @@ -20,6 +20,7 @@ package transport import ( "errors" "fmt" + "io/ioutil" "net/http" "golang.org/x/net/context" @@ -48,6 +49,13 @@ func NewHTTPClient(ctx context.Context, opts ...option.ClientOption) (*http.Clie if o.HTTPClient != nil { return o.HTTPClient, o.Endpoint, nil } + if o.ServiceAccountJSONFilename != "" { + ts, err := serviceAcctTokenSource(ctx, o.ServiceAccountJSONFilename, o.Scopes...) + if err != nil { + return nil, "", err + } + o.TokenSource = ts + } if o.TokenSource == nil { var err error o.TokenSource, err = google.DefaultTokenSource(ctx, o.Scopes...) @@ -74,6 +82,13 @@ func DialGRPC(ctx context.Context, opts ...option.ClientOption) (*grpc.ClientCon if o.GRPCConn != nil { return o.GRPCConn, nil } + if o.ServiceAccountJSONFilename != "" { + ts, err := serviceAcctTokenSource(ctx, o.ServiceAccountJSONFilename, o.Scopes...) + if err != nil { + return nil, err + } + o.TokenSource = ts + } if o.TokenSource == nil { var err error o.TokenSource, err = google.DefaultTokenSource(ctx, o.Scopes...) @@ -95,3 +110,15 @@ func DialGRPC(ctx context.Context, opts ...option.ClientOption) (*grpc.ClientCon } return grpc.DialContext(ctx, o.Endpoint, grpcOpts...) } + +func serviceAcctTokenSource(ctx context.Context, filename string, scope ...string) (oauth2.TokenSource, error) { + data, err := ioutil.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("cannot read service account file: %v", err) + } + cfg, err := google.JWTConfigFromJSON(data, scope...) + if err != nil { + return nil, fmt.Errorf("google.JWTConfigFromJSON: %v", err) + } + return cfg.TokenSource(ctx), nil +} diff --git a/vendor/google.golang.org/appengine/README.md b/vendor/google.golang.org/appengine/README.md index 1efd955..b6b11d9 100644 --- a/vendor/google.golang.org/appengine/README.md +++ b/vendor/google.golang.org/appengine/README.md @@ -66,6 +66,8 @@ This list summarises the differences: * `appengine.BackendHostname` and `appengine.BackendInstance` were for the deprecated backends feature. Use `appengine.ModuleHostname`and `appengine.ModuleName` instead. * Most of `appengine/file` and parts of `appengine/blobstore` are deprecated. - Use [Google Cloud Storage](https://godoc.org/google.golang.org/cloud/storage) instead. + Use [Google Cloud Storage](https://godoc.org/cloud.google.com/go/storage) if the + feature you require is not present in the new + [blobstore package](https://google.golang.org/appengine/blobstore). * `appengine/socket` is not required on App Engine flexible environment / Managed VMs. Use the standard `net` package instead. diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go index ec5aa59..e9c56d4 100644 --- a/vendor/google.golang.org/appengine/internal/api.go +++ b/vendor/google.golang.org/appengine/internal/api.go @@ -60,6 +60,9 @@ var ( Dial: limitDial, }, } + + defaultTicketOnce sync.Once + defaultTicket string ) func apiURL() *url.URL { @@ -266,6 +269,19 @@ func WithContext(parent netcontext.Context, req *http.Request) netcontext.Contex return withContext(parent, c) } +func getDefaultTicket() string { + defaultTicketOnce.Do(func() { + appID := partitionlessAppID() + escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1) + majVersion := VersionID(nil) + if i := strings.Index(majVersion, "."); i > 0 { + majVersion = majVersion[:i] + } + defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID()) + }) + return defaultTicket +} + func BackgroundContext() netcontext.Context { ctxs.Lock() defer ctxs.Unlock() @@ -275,13 +291,7 @@ func BackgroundContext() netcontext.Context { } // Compute background security ticket. - appID := partitionlessAppID() - escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1) - majVersion := VersionID(nil) - if i := strings.Index(majVersion, "."); i > 0 { - majVersion = majVersion[:i] - } - ticket := fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID()) + ticket := getDefaultTicket() ctxs.bg = &context{ req: &http.Request{ @@ -475,6 +485,10 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) } ticket := c.req.Header.Get(ticketHeader) + // Fall back to use background ticket when the request ticket is not available in Flex. + if ticket == "" { + ticket = getDefaultTicket() + } req := &remotepb.Request{ ServiceName: &service, Method: &method, diff --git a/vendor/google.golang.org/cloud/AUTHORS b/vendor/google.golang.org/cloud/AUTHORS deleted file mode 100644 index c364af1..0000000 --- a/vendor/google.golang.org/cloud/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -# This is the official list of cloud authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS files. -# See the latter for an explanation. - -# Names should be added to this file as: -# Name or Organization -# The email address is not required for organizations. - -Filippo Valsorda -Google Inc. -Ingo Oeser -Palm Stone Games, Inc. -Paweł Knap -Péter Szilágyi -Tyler Treat diff --git a/vendor/google.golang.org/cloud/CONTRIBUTING.md b/vendor/google.golang.org/cloud/CONTRIBUTING.md deleted file mode 100644 index 135a1a1..0000000 --- a/vendor/google.golang.org/cloud/CONTRIBUTING.md +++ /dev/null @@ -1,115 +0,0 @@ -# Contributing - -1. Sign one of the contributor license agreements below. -1. `go get golang.org/x/review/git-codereview` to install the code reviewing tool. -1. Get the cloud package by running `go get -d google.golang.org/cloud`. - 1. If you have already checked out the source, make sure that the remote git - origin is https://code.googlesource.com/gocloud: - - git remote set-url origin https://code.googlesource.com/gocloud -1. Make sure your auth is configured correctly by visiting - https://code.googlesource.com, clicking "Generate Password", and following - the directions. -1. Make changes and create a change by running `git codereview change `, -provide a commit message, and use `git codereview mail` to create a Gerrit CL. -1. Keep amending to the change and mail as your receive feedback. - -## Integration Tests - -In addition to the unit tests, you may run the integration test suite. - -To run the integrations tests, creating and configuration of a project in the -Google Developers Console is required. Once you create a project, set the -following environment variables to be able to run the against the actual APIs. - -- **GCLOUD_TESTS_GOLANG_PROJECT_ID**: Developers Console project's ID (e.g. bamboo-shift-455) -- **GCLOUD_TESTS_GOLANG_KEY**: The path to the JSON key file. - -Create a storage bucket with the same name as the project ID set in **GCLOUD_TESTS_GOLANG_PROJECT_ID**. -The storage integration test will create and delete some objects in this bucket. - -Install the [gcloud command-line tool][gcloudcli] to your machine and use it -to create the indexes used in the datastore integration tests with indexes -found in `datastore/testdata/index.yaml`: - -From the project's root directory: - -``` sh -# Set the default project in your env -$ gcloud config set project $GCLOUD_TESTS_GOLANG_PROJECT_ID - -# Authenticate the gcloud tool with your account -$ gcloud auth login - -# Create the indexes -$ gcloud preview datastore create-indexes datastore/testdata/index.yaml - -``` - -Once you've set the environment variables, you can run the integration tests by -running: - -``` sh -$ go test -v google.golang.org/cloud/... -``` - -## Contributor License Agreements - -Before we can accept your pull requests you'll need to sign a Contributor -License Agreement (CLA): - -- **If you are an individual writing original source code** and **you own the -- intellectual property**, then you'll need to sign an [individual CLA][indvcla]. -- **If you work for a company that wants to allow you to contribute your work**, -then you'll need to sign a [corporate CLA][corpcla]. - -You can sign these electronically (just scroll to the bottom). After that, -we'll be able to accept your pull requests. - -## Contributor Code of Conduct - -As contributors and maintainers of this project, -and in the interest of fostering an open and welcoming community, -we pledge to respect all people who contribute through reporting issues, -posting feature requests, updating documentation, -submitting pull requests or patches, and other activities. - -We are committed to making participation in this project -a harassment-free experience for everyone, -regardless of level of experience, gender, gender identity and expression, -sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, -such as physical or electronic -addresses, without explicit permission -* Other unethical or unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct. -By adopting this Code of Conduct, -project maintainers commit themselves to fairly and consistently -applying these principles to every aspect of managing this project. -Project maintainers who do not follow or enforce the Code of Conduct -may be permanently removed from the project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior -may be reported by opening an issue -or contacting one or more of the project maintainers. - -This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, -available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) - -[gcloudcli]: https://developers.google.com/cloud/sdk/gcloud/ -[indvcla]: https://developers.google.com/open-source/cla/individual -[corpcla]: https://developers.google.com/open-source/cla/corporate diff --git a/vendor/google.golang.org/cloud/CONTRIBUTORS b/vendor/google.golang.org/cloud/CONTRIBUTORS deleted file mode 100644 index cfae12c..0000000 --- a/vendor/google.golang.org/cloud/CONTRIBUTORS +++ /dev/null @@ -1,31 +0,0 @@ -# People who have agreed to one of the CLAs and can contribute patches. -# The AUTHORS file lists the copyright holders; this file -# lists people. For example, Google employees are listed here -# but not in AUTHORS, because Google holds the copyright. -# -# https://developers.google.com/open-source/cla/individual -# https://developers.google.com/open-source/cla/corporate -# -# Names should be added to this file as: -# Name - -# Keep the list alphabetically sorted. - -Andreas Litt -Andrew Gerrand -Brad Fitzpatrick -Burcu Dogan -Dave Day -David Sansome -David Symonds -Filippo Valsorda -Glenn Lewis -Ingo Oeser -Johan Euphrosine -Luna Duclos -Michael McGreevy -Omar Jarjur -Paweł Knap -Péter Szilágyi -Toby Burress -Tyler Treat diff --git a/vendor/google.golang.org/cloud/LICENSE b/vendor/google.golang.org/cloud/LICENSE deleted file mode 100644 index a4c5efd..0000000 --- a/vendor/google.golang.org/cloud/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 Google 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. diff --git a/vendor/google.golang.org/cloud/README.md b/vendor/google.golang.org/cloud/README.md deleted file mode 100644 index de29fb9..0000000 --- a/vendor/google.golang.org/cloud/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# Google Cloud for Go - -**NOTE:** This repo exists solely to transition to the new import paths at - cloud.google.com/go. It will be removed on September 12, 2016. Only emergency - pull requests will be accepted. - -To migrate off this repo, change import paths beginning -`google.golang.org/cloud` to `cloud.google.com/go`, except for the options in -the `google.golang.org/cloud` package itself, which are now at -`google.golang.org/api/option`. See details [here](https://groups.google.com/forum/#!topic/google-api-go-announce/nXY-DYZGqz8). - - -[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-golang.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-golang) -[![GoDoc](https://godoc.org/google.golang.org/cloud?status.svg)](https://godoc.org/google.golang.org/cloud) - -``` go -import "google.golang.org/cloud" -``` - -**NOTE:** These packages are under development, and may occasionally make -backwards-incompatible changes. - -**NOTE:** Github repo is a mirror of [https://code.googlesource.com/gocloud](https://code.googlesource.com/gocloud). - -Go packages for Google Cloud Platform services. Supported APIs are: - -Google API | Status | Package --------------------------------|--------------|----------------------------------------------------------- -[Datastore][cloud-datastore] | beta | [`google.golang.org/cloud/datastore`][cloud-datastore-ref] -[Storage][cloud-storage] | beta | [`google.golang.org/cloud/storage`][cloud-storage-ref] -[Pub/Sub][cloud-pubsub] | experimental | [`google.golang.org/cloud/pubsub`][cloud-pubsub-ref] -[Bigtable][cloud-bigtable] | stable | [`google.golang.org/cloud/bigtable`][cloud-bigtable-ref] -[BigQuery][cloud-bigquery] | experimental | [`google.golang.org/cloud/bigquery`][cloud-bigquery-ref] -[Logging][cloud-logging] | experimental | [`google.golang.org/cloud/logging`][cloud-logging-ref] - -> **Experimental status**: the API is still being actively developed. As a -> result, it might change in backward-incompatible ways and is not recommended -> for production use. -> -> **Beta status**: the API is largely complete, but still has outstanding -> features and bugs to be addressed. There may be minor backwards-incompatible -> changes where necessary. -> -> **Stable status**: the API is mature and ready for production use. We will -> continue addressing bugs and feature requests. - -Documentation and examples are available at -https://godoc.org/google.golang.org/cloud - -Visit or join the -[google-api-go-announce group](https://groups.google.com/forum/#!forum/google-api-go-announce) -for updates on these packages. - -## Go Versions Supported - -We support the two most recent major versions of Go. If Google App Engine uses -an older version, we support that as well. You can see which versions are -currently supported by looking at the lines following `go:` in -[`.travis.yml`](.travis.yml). - -## Authorization - -By default, each API will use [Google Application Default Credentials][default-creds] -for authorization credentials used in calling the API endpoints. This will allow your -application to run in many environments without requiring explicit configuration. - -Manually-configured authorization can be achieved using the -[`golang.org/x/oauth2`](https://godoc.org/golang.org/x/oauth2) package to -create an `oauth2.TokenSource`. This token source can be passed to the `NewClient` -function for the relevant API using a -[`cloud.WithTokenSource`](https://godoc.org/google.golang.org/cloud#WithTokenSource) -option. - -## Google Cloud Datastore [![GoDoc](https://godoc.org/google.golang.org/cloud/datastore?status.svg)](https://godoc.org/google.golang.org/cloud/datastore) - -[Google Cloud Datastore][cloud-datastore] ([docs][cloud-datastore-docs]) is a fully- -managed, schemaless database for storing non-relational data. Cloud Datastore -automatically scales with your users and supports ACID transactions, high availability -of reads and writes, strong consistency for reads and ancestor queries, and eventual -consistency for all other queries. - -Follow the [activation instructions][cloud-datastore-activation] to use the Google -Cloud Datastore API with your project. - -First create a `datastore.Client` to use throughout your application: - -```go -client, err := datastore.NewClient(ctx, "my-project-id") -if err != nil { - log.Fatalln(err) -} -``` - -Then use that client to interact with the API: - -```go -type Post struct { - Title string - Body string `datastore:",noindex"` - PublishedAt time.Time -} -keys := []*datastore.Key{ - datastore.NewKey(ctx, "Post", "post1", 0, nil), - datastore.NewKey(ctx, "Post", "post2", 0, nil), -} -posts := []*Post{ - {Title: "Post 1", Body: "...", PublishedAt: time.Now()}, - {Title: "Post 2", Body: "...", PublishedAt: time.Now()}, -} -if _, err := client.PutMulti(ctx, keys, posts); err != nil { - log.Fatal(err) -} -``` - -## Google Cloud Storage [![GoDoc](https://godoc.org/google.golang.org/cloud/storage?status.svg)](https://godoc.org/google.golang.org/cloud/storage) - -[Google Cloud Storage][cloud-storage] ([docs][cloud-storage-docs]) allows you to store -data on Google infrastructure with very high reliability, performance and availability, -and can be used to distribute large data objects to users via direct download. - -https://godoc.org/google.golang.org/cloud/storage - -First create a `storage.Client` to use throughout your application: - -```go -client, err := storage.NewClient(ctx) -if err != nil { - log.Fatal(err) -} -``` - -```go -// Read the object1 from bucket. -rc, err := client.Bucket("bucket").Object("object1").NewReader(ctx) -if err != nil { - log.Fatal(err) -} -defer rc.Close() -body, err := ioutil.ReadAll(rc) -if err != nil { - log.Fatal(err) -} -``` - -## Google Cloud Pub/Sub [![GoDoc](https://godoc.org/google.golang.org/cloud/pubsub?status.svg)](https://godoc.org/google.golang.org/cloud/pubsub) - -[Google Cloud Pub/Sub][cloud-pubsub] ([docs][cloud-pubsub-docs]) allows you to connect -your services with reliable, many-to-many, asynchronous messaging hosted on Google's -infrastructure. Cloud Pub/Sub automatically scales as you need it and provides a foundation -for building your own robust, global services. - -```go -// Publish "hello world" on topic1. -msgIDs, err := pubsub.Publish(ctx, "topic1", &pubsub.Message{ - Data: []byte("hello world"), -}) -if err != nil { - log.Println(err) -} -// Pull messages via subscription1. -msgs, err := pubsub.Pull(ctx, "subscription1", 1) -if err != nil { - log.Println(err) -} -``` - -## Contributing - -Contributions are welcome. Please, see the -[CONTRIBUTING](https://github.com/GoogleCloudPlatform/gcloud-golang/blob/master/CONTRIBUTING.md) -document for details. We're using Gerrit for our code reviews. Please don't open pull -requests against this repo, new pull requests will be automatically closed. - -Please note that this project is released with a Contributor Code of Conduct. -By participating in this project you agree to abide by its terms. -See [Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/gcloud-golang/blob/master/CONTRIBUTING.md#contributor-code-of-conduct) -for more information. - -[cloud-datastore]: https://cloud.google.com/datastore/ -[cloud-datastore-ref]: https://godoc.org/google.golang.org/cloud/datastore -[cloud-datastore-docs]: https://cloud.google.com/datastore/docs -[cloud-datastore-activation]: https://cloud.google.com/datastore/docs/activate - -[cloud-pubsub]: https://cloud.google.com/pubsub/ -[cloud-pubsub-ref]: https://godoc.org/google.golang.org/cloud/pubsub -[cloud-pubsub-docs]: https://cloud.google.com/pubsub/docs - -[cloud-storage]: https://cloud.google.com/storage/ -[cloud-storage-ref]: https://godoc.org/google.golang.org/cloud/storage -[cloud-storage-docs]: https://cloud.google.com/storage/docs/overview -[cloud-storage-create-bucket]: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets - -[cloud-bigtable]: https://cloud.google.com/bigtable/ -[cloud-bigtable-ref]: https://godoc.org/google.golang.org/cloud/bigtable - -[cloud-bigquery]: https://cloud.google.com/bigquery/ -[cloud-bigquery-ref]: https://godoc.org/google.golang.org/cloud/bigquery - -[cloud-logging]: https://cloud.google.com/logging/ -[cloud-logging-ref]: https://godoc.org/google.golang.org/cloud/logging - -[default-creds]: https://developers.google.com/identity/protocols/application-default-credentials diff --git a/vendor/google.golang.org/cloud/cloud.go b/vendor/google.golang.org/cloud/cloud.go deleted file mode 100644 index 98be1f4..0000000 --- a/vendor/google.golang.org/cloud/cloud.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 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 cloud contains Google Cloud Platform APIs related types -// and common functions. -package cloud // import "google.golang.org/cloud" - -import ( - "net/http" - - "golang.org/x/net/context" - "google.golang.org/cloud/internal" -) - -// NewContext returns a new context that uses the provided http.Client. -// Provided http.Client is responsible to authorize and authenticate -// the requests made to the Google Cloud APIs. -// It mutates the client's original Transport to append the cloud -// package's user-agent to the outgoing requests. -// You can obtain the project ID from the Google Developers Console, -// https://console.developers.google.com. -func NewContext(projID string, c *http.Client) context.Context { - if c == nil { - panic("invalid nil *http.Client passed to NewContext") - } - return WithContext(context.Background(), projID, c) -} - -// WithContext returns a new context in a similar way NewContext does, -// but initiates the new context with the specified parent. -func WithContext(parent context.Context, projID string, c *http.Client) context.Context { - // TODO(bradfitz): delete internal.Transport. It's too wrappy for what it does. - // Do User-Agent some other way. - if c == nil { - panic("invalid nil *http.Client passed to WithContext") - } - if _, ok := c.Transport.(*internal.Transport); !ok { - base := c.Transport - if base == nil { - base = http.DefaultTransport - } - c.Transport = &internal.Transport{Base: base} - } - return internal.WithContext(parent, projID, c) -} diff --git a/vendor/google.golang.org/cloud/compute/metadata/metadata.go b/vendor/google.golang.org/cloud/compute/metadata/metadata.go deleted file mode 100644 index b791790..0000000 --- a/vendor/google.golang.org/cloud/compute/metadata/metadata.go +++ /dev/null @@ -1,438 +0,0 @@ -// Copyright 2014 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 metadata provides access to Google Compute Engine (GCE) -// metadata and API service accounts. -// -// This package is a wrapper around the GCE metadata service, -// as documented at https://developers.google.com/compute/docs/metadata. -package metadata // import "google.golang.org/cloud/compute/metadata" - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "runtime" - "strings" - "sync" - "time" - - "golang.org/x/net/context" - "golang.org/x/net/context/ctxhttp" - - "google.golang.org/cloud/internal" -) - -const ( - // metadataIP is the documented metadata server IP address. - metadataIP = "169.254.169.254" - - // metadataHostEnv is the environment variable specifying the - // GCE metadata hostname. If empty, the default value of - // metadataIP ("169.254.169.254") is used instead. - // This is variable name is not defined by any spec, as far as - // I know; it was made up for the Go package. - metadataHostEnv = "GCE_METADATA_HOST" -) - -type cachedValue struct { - k string - trim bool - mu sync.Mutex - v string -} - -var ( - projID = &cachedValue{k: "project/project-id", trim: true} - projNum = &cachedValue{k: "project/numeric-project-id", trim: true} - instID = &cachedValue{k: "instance/id", trim: true} -) - -var ( - metaClient = &http.Client{ - Transport: &internal.Transport{ - Base: &http.Transport{ - Dial: (&net.Dialer{ - Timeout: 2 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - ResponseHeaderTimeout: 2 * time.Second, - }, - }, - } - subscribeClient = &http.Client{ - Transport: &internal.Transport{ - Base: &http.Transport{ - Dial: (&net.Dialer{ - Timeout: 2 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - }, - }, - } -) - -// NotDefinedError is returned when requested metadata is not defined. -// -// The underlying string is the suffix after "/computeMetadata/v1/". -// -// This error is not returned if the value is defined to be the empty -// string. -type NotDefinedError string - -func (suffix NotDefinedError) Error() string { - return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) -} - -// Get returns a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// -// If the GCE_METADATA_HOST environment variable is not defined, a default of -// 169.254.169.254 will be used instead. -// -// If the requested metadata is not defined, the returned error will -// be of type NotDefinedError. -func Get(suffix string) (string, error) { - val, _, err := getETag(metaClient, suffix) - return val, err -} - -// getETag returns a value from the metadata service as well as the associated -// ETag using the provided client. This func is otherwise equivalent to Get. -func getETag(client *http.Client, suffix string) (value, etag string, err error) { - // Using a fixed IP makes it very difficult to spoof the metadata service in - // a container, which is an important use-case for local testing of cloud - // deployments. To enable spoofing of the metadata service, the environment - // variable GCE_METADATA_HOST is first inspected to decide where metadata - // requests shall go. - host := os.Getenv(metadataHostEnv) - if host == "" { - // Using 169.254.169.254 instead of "metadata" here because Go - // binaries built with the "netgo" tag and without cgo won't - // know the search suffix for "metadata" is - // ".google.internal", and this IP address is documented as - // being stable anyway. - host = metadataIP - } - url := "http://" + host + "/computeMetadata/v1/" + suffix - req, _ := http.NewRequest("GET", url, nil) - req.Header.Set("Metadata-Flavor", "Google") - res, err := client.Do(req) - if err != nil { - return "", "", err - } - defer res.Body.Close() - if res.StatusCode == http.StatusNotFound { - return "", "", NotDefinedError(suffix) - } - if res.StatusCode != 200 { - return "", "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url) - } - all, err := ioutil.ReadAll(res.Body) - if err != nil { - return "", "", err - } - return string(all), res.Header.Get("Etag"), nil -} - -func getTrimmed(suffix string) (s string, err error) { - s, err = Get(suffix) - s = strings.TrimSpace(s) - return -} - -func (c *cachedValue) get() (v string, err error) { - defer c.mu.Unlock() - c.mu.Lock() - if c.v != "" { - return c.v, nil - } - if c.trim { - v, err = getTrimmed(c.k) - } else { - v, err = Get(c.k) - } - if err == nil { - c.v = v - } - return -} - -var ( - onGCEOnce sync.Once - onGCE bool -) - -// OnGCE reports whether this process is running on Google Compute Engine. -func OnGCE() bool { - onGCEOnce.Do(initOnGCE) - return onGCE -} - -func initOnGCE() { - onGCE = testOnGCE() -} - -func testOnGCE() bool { - // The user explicitly said they're on GCE, so trust them. - if os.Getenv(metadataHostEnv) != "" { - return true - } - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - resc := make(chan bool, 2) - - // Try two strategies in parallel. - // See https://github.com/GoogleCloudPlatform/gcloud-golang/issues/194 - go func() { - res, err := ctxhttp.Get(ctx, metaClient, "http://"+metadataIP) - if err != nil { - resc <- false - return - } - defer res.Body.Close() - resc <- res.Header.Get("Metadata-Flavor") == "Google" - }() - - go func() { - addrs, err := net.LookupHost("metadata.google.internal") - if err != nil || len(addrs) == 0 { - resc <- false - return - } - resc <- strsContains(addrs, metadataIP) - }() - - tryHarder := systemInfoSuggestsGCE() - if tryHarder { - res := <-resc - if res { - // The first strategy succeeded, so let's use it. - return true - } - // Wait for either the DNS or metadata server probe to - // contradict the other one and say we are running on - // GCE. Give it a lot of time to do so, since the system - // info already suggests we're running on a GCE BIOS. - timer := time.NewTimer(5 * time.Second) - defer timer.Stop() - select { - case res = <-resc: - return res - case <-timer.C: - // Too slow. Who knows what this system is. - return false - } - } - - // There's no hint from the system info that we're running on - // GCE, so use the first probe's result as truth, whether it's - // true or false. The goal here is to optimize for speed for - // users who are NOT running on GCE. We can't assume that - // either a DNS lookup or an HTTP request to a blackholed IP - // address is fast. Worst case this should return when the - // metaClient's Transport.ResponseHeaderTimeout or - // Transport.Dial.Timeout fires (in two seconds). - return <-resc -} - -// systemInfoSuggestsGCE reports whether the local system (without -// doing network requests) suggests that we're running on GCE. If this -// returns true, testOnGCE tries a bit harder to reach its metadata -// server. -func systemInfoSuggestsGCE() bool { - if runtime.GOOS != "linux" { - // We don't have any non-Linux clues available, at least yet. - return false - } - slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name") - name := strings.TrimSpace(string(slurp)) - return name == "Google" || name == "Google Compute Engine" -} - -// Subscribe subscribes to a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// The suffix may contain query parameters. -// -// Subscribe calls fn with the latest metadata value indicated by the provided -// suffix. If the metadata value is deleted, fn is called with the empty string -// and ok false. Subscribe blocks until fn returns a non-nil error or the value -// is deleted. Subscribe returns the error value returned from the last call to -// fn, which may be nil when ok == false. -func Subscribe(suffix string, fn func(v string, ok bool) error) error { - const failedSubscribeSleep = time.Second * 5 - - // First check to see if the metadata value exists at all. - val, lastETag, err := getETag(subscribeClient, suffix) - if err != nil { - return err - } - - if err := fn(val, true); err != nil { - return err - } - - ok := true - if strings.ContainsRune(suffix, '?') { - suffix += "&wait_for_change=true&last_etag=" - } else { - suffix += "?wait_for_change=true&last_etag=" - } - for { - val, etag, err := getETag(subscribeClient, suffix+url.QueryEscape(lastETag)) - if err != nil { - if _, deleted := err.(NotDefinedError); !deleted { - time.Sleep(failedSubscribeSleep) - continue // Retry on other errors. - } - ok = false - } - lastETag = etag - - if err := fn(val, ok); err != nil || !ok { - return err - } - } -} - -// ProjectID returns the current instance's project ID string. -func ProjectID() (string, error) { return projID.get() } - -// NumericProjectID returns the current instance's numeric project ID. -func NumericProjectID() (string, error) { return projNum.get() } - -// InternalIP returns the instance's primary internal IP address. -func InternalIP() (string, error) { - return getTrimmed("instance/network-interfaces/0/ip") -} - -// ExternalIP returns the instance's primary external (public) IP address. -func ExternalIP() (string, error) { - return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") -} - -// Hostname returns the instance's hostname. This will be of the form -// ".c..internal". -func Hostname() (string, error) { - return getTrimmed("instance/hostname") -} - -// InstanceTags returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -func InstanceTags() ([]string, error) { - var s []string - j, err := Get("instance/tags") - if err != nil { - return nil, err - } - if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { - return nil, err - } - return s, nil -} - -// InstanceID returns the current VM's numeric instance ID. -func InstanceID() (string, error) { - return instID.get() -} - -// InstanceName returns the current VM's instance ID string. -func InstanceName() (string, error) { - host, err := Hostname() - if err != nil { - return "", err - } - return strings.Split(host, ".")[0], nil -} - -// Zone returns the current VM's zone, such as "us-central1-b". -func Zone() (string, error) { - zone, err := getTrimmed("instance/zone") - // zone is of the form "projects//zones/". - if err != nil { - return "", err - } - return zone[strings.LastIndex(zone, "/")+1:], nil -} - -// InstanceAttributes returns the list of user-defined attributes, -// assigned when initially creating a GCE VM instance. The value of an -// attribute can be obtained with InstanceAttributeValue. -func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") } - -// ProjectAttributes returns the list of user-defined attributes -// applying to the project as a whole, not just this VM. The value of -// an attribute can be obtained with ProjectAttributeValue. -func ProjectAttributes() ([]string, error) { return lines("project/attributes/") } - -func lines(suffix string) ([]string, error) { - j, err := Get(suffix) - if err != nil { - return nil, err - } - s := strings.Split(strings.TrimSpace(j), "\n") - for i := range s { - s[i] = strings.TrimSpace(s[i]) - } - return s, nil -} - -// InstanceAttributeValue returns the value of the provided VM -// instance attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// InstanceAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func InstanceAttributeValue(attr string) (string, error) { - return Get("instance/attributes/" + attr) -} - -// ProjectAttributeValue returns the value of the provided -// project attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// ProjectAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func ProjectAttributeValue(attr string) (string, error) { - return Get("project/attributes/" + attr) -} - -// Scopes returns the service account scopes for the given account. -// The account may be empty or the string "default" to use the instance's -// main account. -func Scopes(serviceAccount string) ([]string, error) { - if serviceAccount == "" { - serviceAccount = "default" - } - return lines("instance/service-accounts/" + serviceAccount + "/scopes") -} - -func strsContains(ss []string, s string) bool { - for _, v := range ss { - if v == s { - return true - } - } - return false -} diff --git a/vendor/google.golang.org/cloud/internal/cloud.go b/vendor/google.golang.org/cloud/internal/cloud.go deleted file mode 100644 index 5942880..0000000 --- a/vendor/google.golang.org/cloud/internal/cloud.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2014 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 provides support for the cloud packages. -// -// Users should not import this package directly. -package internal - -import ( - "fmt" - "net/http" - "sync" - - "golang.org/x/net/context" -) - -type contextKey struct{} - -func WithContext(parent context.Context, projID string, c *http.Client) context.Context { - if c == nil { - panic("nil *http.Client passed to WithContext") - } - if projID == "" { - panic("empty project ID passed to WithContext") - } - return context.WithValue(parent, contextKey{}, &cloudContext{ - ProjectID: projID, - HTTPClient: c, - }) -} - -const userAgent = "gcloud-golang/0.1" - -type cloudContext struct { - ProjectID string - HTTPClient *http.Client - - mu sync.Mutex // guards svc - svc map[string]interface{} // e.g. "storage" => *rawStorage.Service -} - -// Service returns the result of the fill function if it's never been -// called before for the given name (which is assumed to be an API -// service name, like "datastore"). If it has already been cached, the fill -// func is not run. -// It's safe for concurrent use by multiple goroutines. -func Service(ctx context.Context, name string, fill func(*http.Client) interface{}) interface{} { - return cc(ctx).service(name, fill) -} - -func (c *cloudContext) service(name string, fill func(*http.Client) interface{}) interface{} { - c.mu.Lock() - defer c.mu.Unlock() - - if c.svc == nil { - c.svc = make(map[string]interface{}) - } else if v, ok := c.svc[name]; ok { - return v - } - v := fill(c.HTTPClient) - c.svc[name] = v - return v -} - -// Transport is an http.RoundTripper that appends -// Google Cloud client's user-agent to the original -// request's user-agent header. -type Transport struct { - // Base is the actual http.RoundTripper - // requests will use. It must not be nil. - Base http.RoundTripper -} - -// RoundTrip appends a user-agent to the existing user-agent -// header and delegates the request to the base http.RoundTripper. -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - req = cloneRequest(req) - ua := req.Header.Get("User-Agent") - if ua == "" { - ua = userAgent - } else { - ua = fmt.Sprintf("%s %s", ua, userAgent) - } - req.Header.Set("User-Agent", ua) - return t.Base.RoundTrip(req) -} - -// cloneRequest returns a clone of the provided *http.Request. -// The clone is a shallow copy of the struct and its Header map. -func cloneRequest(r *http.Request) *http.Request { - // shallow copy of the struct - r2 := new(http.Request) - *r2 = *r - // deep copy of the Header - r2.Header = make(http.Header) - for k, s := range r.Header { - r2.Header[k] = s - } - return r2 -} - -func ProjID(ctx context.Context) string { - return cc(ctx).ProjectID -} - -func HTTPClient(ctx context.Context) *http.Client { - return cc(ctx).HTTPClient -} - -// cc returns the internal *cloudContext (cc) state for a context.Context. -// It panics if the user did it wrong. -func cc(ctx context.Context) *cloudContext { - if c, ok := ctx.Value(contextKey{}).(*cloudContext); ok { - return c - } - panic("invalid context.Context type; it should be created with cloud.NewContext") -} diff --git a/vendor/google.golang.org/cloud/internal/transport/dial.go b/vendor/google.golang.org/cloud/internal/transport/dial.go deleted file mode 100644 index f554953..0000000 --- a/vendor/google.golang.org/cloud/internal/transport/dial.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2015 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 transport - -import ( - "fmt" - "net/http" - - "golang.org/x/net/context" - "google.golang.org/api/option" - "google.golang.org/api/transport" - "google.golang.org/cloud" - "google.golang.org/grpc" -) - -// ErrHTTP is returned when on a non-200 HTTP response. -type ErrHTTP struct { - StatusCode int - Body []byte - err error -} - -func (e *ErrHTTP) Error() string { - if e.err == nil { - return fmt.Sprintf("error during call, http status code: %v %s", e.StatusCode, e.Body) - } - return e.err.Error() -} - -// NewHTTPClient returns an HTTP client for use communicating with a Google cloud -// service, configured with the given ClientOptions. It also returns the endpoint -// for the service as specified in the options. -func NewHTTPClient(ctx context.Context, opt ...cloud.ClientOption) (*http.Client, string, error) { - o := make([]option.ClientOption, 0, len(opt)) - for _, opt := range opt { - o = append(o, opt.Resolve()) - } - return transport.NewHTTPClient(ctx, o...) -} - -// DialGRPC returns a GRPC connection for use communicating with a Google cloud -// service, configured with the given ClientOptions. -func DialGRPC(ctx context.Context, opt ...cloud.ClientOption) (*grpc.ClientConn, error) { - o := make([]option.ClientOption, 0, len(opt)) - for _, opt := range opt { - o = append(o, opt.Resolve()) - } - return transport.DialGRPC(ctx, o...) -} diff --git a/vendor/google.golang.org/cloud/key.json.enc b/vendor/google.golang.org/cloud/key.json.enc deleted file mode 100644 index 2f673a8..0000000 Binary files a/vendor/google.golang.org/cloud/key.json.enc and /dev/null differ diff --git a/vendor/google.golang.org/cloud/option.go b/vendor/google.golang.org/cloud/option.go deleted file mode 100644 index c012c73..0000000 --- a/vendor/google.golang.org/cloud/option.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2015 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 cloud - -import ( - "net/http" - - "golang.org/x/oauth2" - "google.golang.org/api/option" - "google.golang.org/grpc" -) - -// ClientOption is used when construct clients for each cloud service. -type ClientOption interface { - // Resolve returns the equivalent option from the - // google.golang.org/api/option package. - Resolve() option.ClientOption -} - -type wrapOpt struct { - o option.ClientOption -} - -func (w wrapOpt) Resolve() option.ClientOption { - return w.o -} - -// WithTokenSource returns a ClientOption that specifies an OAuth2 token -// source to be used as the basis for authentication. -func WithTokenSource(s oauth2.TokenSource) ClientOption { - return wrapOpt{option.WithTokenSource(s)} -} - -// WithEndpoint returns a ClientOption that overrides the default endpoint -// to be used for a service. -func WithEndpoint(url string) ClientOption { - return wrapOpt{option.WithEndpoint(url)} -} - -// WithScopes returns a ClientOption that overrides the default OAuth2 scopes -// to be used for a service. -func WithScopes(scope ...string) ClientOption { - return wrapOpt{option.WithScopes(scope...)} -} - -// WithUserAgent returns a ClientOption that sets the User-Agent. -func WithUserAgent(ua string) ClientOption { - return wrapOpt{option.WithUserAgent(ua)} -} - -// WithBaseHTTP returns a ClientOption that specifies the HTTP client to -// use as the basis of communications. This option may only be used with -// services that support HTTP as their communication transport. -func WithBaseHTTP(client *http.Client) ClientOption { - return wrapOpt{option.WithHTTPClient(client)} -} - -// WithBaseGRPC returns a ClientOption that specifies the gRPC client -// connection to use as the basis of communications. This option many only be -// used with services that support gRPC as their communication transport. -func WithBaseGRPC(conn *grpc.ClientConn) ClientOption { - return wrapOpt{option.WithGRPCConn(conn)} -} - -// WithGRPCDialOption returns a ClientOption that appends a new grpc.DialOption -// to an underlying gRPC dial. It does not work with WithBaseGRPC. -func WithGRPCDialOption(o grpc.DialOption) ClientOption { - return wrapOpt{option.WithGRPCDialOption(o)} -} - -// WithGRPCConnectionPool returns a ClientOption that creates a pool of gRPC -// connections that requests will be balanced between. -// This is an EXPERIMENTAL API and may be changed or removed in the future. -func WithGRPCConnectionPool(size int) ClientOption { - return wrapOpt{option.WithGRPCConnectionPool(size)} -} diff --git a/vendor/google.golang.org/cloud/storage/acl.go b/vendor/google.golang.org/cloud/storage/acl.go deleted file mode 100644 index e4d968b..0000000 --- a/vendor/google.golang.org/cloud/storage/acl.go +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2014 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 storage - -import ( - "fmt" - - "golang.org/x/net/context" - raw "google.golang.org/api/storage/v1" -) - -// ACLRole is the level of access to grant. -type ACLRole string - -const ( - RoleOwner ACLRole = "OWNER" - RoleReader ACLRole = "READER" -) - -// ACLEntity refers to a user or group. -// They are sometimes referred to as grantees. -// -// It could be in the form of: -// "user-", "user-", "group-", "group-", -// "domain-" and "project-team-". -// -// Or one of the predefined constants: AllUsers, AllAuthenticatedUsers. -type ACLEntity string - -const ( - AllUsers ACLEntity = "allUsers" - AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers" -) - -// ACLRule represents a grant for a role to an entity (user, group or team) for a Google Cloud Storage object or bucket. -type ACLRule struct { - Entity ACLEntity - Role ACLRole -} - -// ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object. -type ACLHandle struct { - c *Client - bucket string - object string - isDefault bool -} - -// Delete permanently deletes the ACL entry for the given entity. -func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) error { - if a.object != "" { - return a.objectDelete(ctx, entity) - } - if a.isDefault { - return a.bucketDefaultDelete(ctx, entity) - } - return a.bucketDelete(ctx, entity) -} - -// Set sets the permission level for the given entity. -func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) error { - if a.object != "" { - return a.objectSet(ctx, entity, role) - } - if a.isDefault { - return a.bucketDefaultSet(ctx, entity, role) - } - return a.bucketSet(ctx, entity, role) -} - -// List retrieves ACL entries. -func (a *ACLHandle) List(ctx context.Context) ([]ACLRule, error) { - if a.object != "" { - return a.objectList(ctx) - } - if a.isDefault { - return a.bucketDefaultList(ctx) - } - return a.bucketList(ctx) -} - -func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) { - acls, err := a.c.raw.DefaultObjectAccessControls.List(a.bucket).Context(ctx).Do() - if err != nil { - return nil, fmt.Errorf("storage: error listing default object ACL for bucket %q: %v", a.bucket, err) - } - return toACLRules(acls.Items), nil -} - -func (a *ACLHandle) bucketDefaultSet(ctx context.Context, entity ACLEntity, role ACLRole) error { - acl := &raw.ObjectAccessControl{ - Bucket: a.bucket, - Entity: string(entity), - Role: string(role), - } - _, err := a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl).Context(ctx).Do() - if err != nil { - return fmt.Errorf("storage: error updating default ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) - } - return nil -} - -func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error { - err := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity)).Context(ctx).Do() - if err != nil { - return fmt.Errorf("storage: error deleting default ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) - } - return nil -} - -func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) { - acls, err := a.c.raw.BucketAccessControls.List(a.bucket).Context(ctx).Do() - if err != nil { - return nil, fmt.Errorf("storage: error listing bucket ACL for bucket %q: %v", a.bucket, err) - } - r := make([]ACLRule, len(acls.Items)) - for i, v := range acls.Items { - r[i].Entity = ACLEntity(v.Entity) - r[i].Role = ACLRole(v.Role) - } - return r, nil -} - -func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error { - acl := &raw.BucketAccessControl{ - Bucket: a.bucket, - Entity: string(entity), - Role: string(role), - } - _, err := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl).Context(ctx).Do() - if err != nil { - return fmt.Errorf("storage: error updating bucket ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) - } - return nil -} - -func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error { - err := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity)).Context(ctx).Do() - if err != nil { - return fmt.Errorf("storage: error deleting bucket ACL entry for bucket %q, entity %q: %v", a.bucket, entity, err) - } - return nil -} - -func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) { - acls, err := a.c.raw.ObjectAccessControls.List(a.bucket, a.object).Context(ctx).Do() - if err != nil { - return nil, fmt.Errorf("storage: error listing object ACL for bucket %q, file %q: %v", a.bucket, a.object, err) - } - return toACLRules(acls.Items), nil -} - -func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole) error { - acl := &raw.ObjectAccessControl{ - Bucket: a.bucket, - Entity: string(entity), - Role: string(role), - } - _, err := a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl).Context(ctx).Do() - if err != nil { - return fmt.Errorf("storage: error updating object ACL entry for bucket %q, file %q, entity %q: %v", a.bucket, a.object, entity, err) - } - return nil -} - -func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error { - err := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity)).Context(ctx).Do() - if err != nil { - return fmt.Errorf("storage: error deleting object ACL entry for bucket %q, file %q, entity %q: %v", a.bucket, a.object, entity, err) - } - return nil -} - -func toACLRules(items []interface{}) []ACLRule { - r := make([]ACLRule, 0, len(items)) - for _, v := range items { - if m, ok := v.(map[string]interface{}); ok { - entity, ok1 := m["entity"].(string) - role, ok2 := m["role"].(string) - if ok1 && ok2 { - r = append(r, ACLRule{Entity: ACLEntity(entity), Role: ACLRole(role)}) - } - } - } - return r -} diff --git a/vendor/google.golang.org/cloud/storage/reader.go b/vendor/google.golang.org/cloud/storage/reader.go deleted file mode 100644 index 9e21648..0000000 --- a/vendor/google.golang.org/cloud/storage/reader.go +++ /dev/null @@ -1,55 +0,0 @@ -// 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 storage - -import ( - "io" -) - -// Reader reads a Cloud Storage object. -type Reader struct { - body io.ReadCloser - remain, size int64 - contentType string -} - -func (r *Reader) Close() error { - return r.body.Close() -} - -func (r *Reader) Read(p []byte) (int, error) { - n, err := r.body.Read(p) - if r.remain != -1 { - r.remain -= int64(n) - } - return n, err -} - -// Size returns the size of the object in bytes. -// The returned value is always the same and is not affected by -// calls to Read or Close. -func (r *Reader) Size() int64 { - return r.size -} - -// Remain returns the number of bytes left to read, or -1 if unknown. -func (r *Reader) Remain() int64 { - return r.remain -} - -// ContentType returns the content type of the object. -func (r *Reader) ContentType() string { - return r.contentType -} diff --git a/vendor/google.golang.org/cloud/storage/storage.go b/vendor/google.golang.org/cloud/storage/storage.go deleted file mode 100644 index 85dca80..0000000 --- a/vendor/google.golang.org/cloud/storage/storage.go +++ /dev/null @@ -1,1204 +0,0 @@ -// Copyright 2014 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 storage contains a Google Cloud Storage client. -// -// This package is experimental and may make backwards-incompatible changes. -package storage // import "google.golang.org/cloud/storage" - -import ( - "bytes" - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/base64" - "encoding/pem" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "reflect" - "strconv" - "strings" - "time" - "unicode/utf8" - - "google.golang.org/cloud" - "google.golang.org/cloud/internal/transport" - - "golang.org/x/net/context" - "google.golang.org/api/googleapi" - raw "google.golang.org/api/storage/v1" -) - -var ( - ErrBucketNotExist = errors.New("storage: bucket doesn't exist") - ErrObjectNotExist = errors.New("storage: object doesn't exist") - - // Done is returned by iterators in this package when they have no more items. - Done = errors.New("storage: no more results") -) - -const userAgent = "gcloud-golang-storage/20151204" - -const ( - // ScopeFullControl grants permissions to manage your - // data and permissions in Google Cloud Storage. - ScopeFullControl = raw.DevstorageFullControlScope - - // ScopeReadOnly grants permissions to - // view your data in Google Cloud Storage. - ScopeReadOnly = raw.DevstorageReadOnlyScope - - // ScopeReadWrite grants permissions to manage your - // data in Google Cloud Storage. - ScopeReadWrite = raw.DevstorageReadWriteScope -) - -// AdminClient is a client type for performing admin operations on a project's -// buckets. -// -// Deprecated: Client has all of AdminClient's methods. -type AdminClient struct { - c *Client - projectID string -} - -// NewAdminClient creates a new AdminClient for a given project. -// -// Deprecated: use NewClient instead. -func NewAdminClient(ctx context.Context, projectID string, opts ...cloud.ClientOption) (*AdminClient, error) { - c, err := NewClient(ctx, opts...) - if err != nil { - return nil, err - } - return &AdminClient{ - c: c, - projectID: projectID, - }, nil -} - -// Close closes the AdminClient. -func (c *AdminClient) Close() error { - return c.c.Close() -} - -// Create creates a Bucket in the project. -// If attrs is nil the API defaults will be used. -// -// Deprecated: use BucketHandle.Create instead. -func (c *AdminClient) CreateBucket(ctx context.Context, bucketName string, attrs *BucketAttrs) error { - return c.c.Bucket(bucketName).Create(ctx, c.projectID, attrs) -} - -// Delete deletes a Bucket in the project. -// -// Deprecated: use BucketHandle.Delete instead. -func (c *AdminClient) DeleteBucket(ctx context.Context, bucketName string) error { - return c.c.Bucket(bucketName).Delete(ctx) -} - -// Client is a client for interacting with Google Cloud Storage. -type Client struct { - hc *http.Client - raw *raw.Service -} - -// NewClient creates a new Google Cloud Storage client. -// The default scope is ScopeFullControl. To use a different scope, like ScopeReadOnly, use cloud.WithScopes. -func NewClient(ctx context.Context, opts ...cloud.ClientOption) (*Client, error) { - o := []cloud.ClientOption{ - cloud.WithScopes(ScopeFullControl), - cloud.WithUserAgent(userAgent), - } - opts = append(o, opts...) - hc, _, err := transport.NewHTTPClient(ctx, opts...) - if err != nil { - return nil, fmt.Errorf("dialing: %v", err) - } - rawService, err := raw.New(hc) - if err != nil { - return nil, fmt.Errorf("storage client: %v", err) - } - return &Client{ - hc: hc, - raw: rawService, - }, nil -} - -// Close closes the Client. -func (c *Client) Close() error { - c.hc = nil - return nil -} - -// BucketHandle provides operations on a Google Cloud Storage bucket. -// Use Client.Bucket to get a handle. -type BucketHandle struct { - acl *ACLHandle - defaultObjectACL *ACLHandle - - c *Client - name string -} - -// Bucket returns a BucketHandle, which provides operations on the named bucket. -// This call does not perform any network operations. -// -// name must contain only lowercase letters, numbers, dashes, underscores, and -// dots. The full specification for valid bucket names can be found at: -// https://cloud.google.com/storage/docs/bucket-naming -func (c *Client) Bucket(name string) *BucketHandle { - return &BucketHandle{ - c: c, - name: name, - acl: &ACLHandle{ - c: c, - bucket: name, - }, - defaultObjectACL: &ACLHandle{ - c: c, - bucket: name, - isDefault: true, - }, - } -} - -// 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 { - var bkt *raw.Bucket - if attrs != nil { - bkt = attrs.toRawBucket() - } else { - bkt = &raw.Bucket{} - } - bkt.Name = b.name - req := b.c.raw.Buckets.Insert(projectID, bkt) - _, err := req.Context(ctx).Do() - return err -} - -// Delete deletes the Bucket. -func (b *BucketHandle) Delete(ctx context.Context) error { - req := b.c.raw.Buckets.Delete(b.name) - return req.Context(ctx).Do() -} - -// ACL returns an ACLHandle, which provides access to the bucket's access control list. -// This controls who can list, create or overwrite the objects in a bucket. -// This call does not perform any network operations. -func (c *BucketHandle) ACL() *ACLHandle { - return c.acl -} - -// DefaultObjectACL returns an ACLHandle, which provides access to the bucket's default object ACLs. -// These ACLs are applied to newly created objects in this bucket that do not have a defined ACL. -// This call does not perform any network operations. -func (c *BucketHandle) DefaultObjectACL() *ACLHandle { - return c.defaultObjectACL -} - -// Object returns an ObjectHandle, which provides operations on the named object. -// This call does not perform any network operations. -// -// name must consist entirely of valid UTF-8-encoded runes. The full specification -// for valid object names can be found at: -// https://cloud.google.com/storage/docs/bucket-naming -func (b *BucketHandle) Object(name string) *ObjectHandle { - return &ObjectHandle{ - c: b.c, - bucket: b.name, - object: name, - acl: &ACLHandle{ - c: b.c, - bucket: b.name, - object: name, - }, - } -} - -// TODO(jbd): Add storage.buckets.list. -// TODO(jbd): Add storage.buckets.update. - -// TODO(jbd): Add storage.objects.watch. - -// Attrs returns the metadata for the bucket. -func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) { - resp, err := b.c.raw.Buckets.Get(b.name).Projection("full").Context(ctx).Do() - if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { - return nil, ErrBucketNotExist - } - if err != nil { - return nil, err - } - return newBucket(resp), nil -} - -// List lists objects from the bucket. You can specify a query -// to filter the results. If q is nil, no filtering is applied. -// -// Deprecated. Use BucketHandle.Objects instead. -func (b *BucketHandle) List(ctx context.Context, q *Query) (*ObjectList, error) { - it := b.Objects(ctx, q) - attrs, pres, err := it.NextPage() - if err != nil && err != Done { - return nil, err - } - objects := &ObjectList{ - Results: attrs, - Prefixes: pres, - } - if it.NextPageToken() != "" { - objects.Next = &it.query - } - return objects, nil -} - -func (b *BucketHandle) Objects(ctx context.Context, q *Query) *ObjectIterator { - it := &ObjectIterator{ - ctx: ctx, - bucket: b, - } - if q != nil { - it.query = *q - } - return it -} - -type ObjectIterator struct { - ctx context.Context - bucket *BucketHandle - query Query - pageSize int32 - objs []*ObjectAttrs - prefixes []string - err error -} - -// Next returns the next result. Its second return value is Done if there are -// no more results. Once Next returns Done, all subsequent calls will return -// Done. -// -// Internally, Next retrieves results in bulk. You can call SetPageSize as a -// performance hint to affect how many results are retrieved in a single RPC. -// -// SetPageToken should not be called when using Next. -// -// Next and NextPage should not be used with the same iterator. -// -// If Query.Delimiter is non-empty, Next returns an error. Use NextPage when using delimiters. -func (it *ObjectIterator) Next() (*ObjectAttrs, error) { - if it.query.Delimiter != "" { - return nil, errors.New("cannot use ObjectIterator.Next with a delimiter") - } - for len(it.objs) == 0 { // "for", not "if", to handle empty pages - if it.err != nil { - return nil, it.err - } - it.nextPage() - if it.err != nil { - it.objs = nil - return nil, it.err - } - if it.query.Cursor == "" { - it.err = Done - } - } - o := it.objs[0] - it.objs = it.objs[1:] - return o, nil -} - -const DefaultPageSize = 1000 - -// NextPage returns the next page of results, both objects (as *ObjectAttrs) -// and prefixes. Prefixes will be nil if query.Delimiter is empty. -// -// NextPage will return exactly the number of results (the total of objects and -// prefixes) specified by the last call to SetPageSize, unless there are not -// enough results available. If no page size was specified, it uses -// DefaultPageSize. -// -// NextPage may return a second return value of Done along with the last page -// of results. -// -// After NextPage returns Done, all subsequent calls to NextPage will return -// (nil, Done). -// -// Next and NextPage should not be used with the same iterator. -func (it *ObjectIterator) NextPage() (objs []*ObjectAttrs, prefixes []string, err error) { - defer it.SetPageSize(it.pageSize) // restore value at entry - if it.pageSize <= 0 { - it.pageSize = DefaultPageSize - } - for len(objs)+len(prefixes) < int(it.pageSize) { - it.pageSize -= int32(len(objs) + len(prefixes)) - it.nextPage() - if it.err != nil { - return nil, nil, it.err - } - objs = append(objs, it.objs...) - prefixes = append(prefixes, it.prefixes...) - if it.query.Cursor == "" { - it.err = Done - return objs, prefixes, it.err - } - } - return objs, prefixes, it.err -} - -// nextPage gets the next page of results by making a single call to the underlying method. -// It sets it.objs, it.prefixes, it.query.Cursor, and it.err. It never sets it.err to Done. -func (it *ObjectIterator) nextPage() { - if it.err != nil { - return - } - req := it.bucket.c.raw.Objects.List(it.bucket.name) - req.Projection("full") - req.Delimiter(it.query.Delimiter) - req.Prefix(it.query.Prefix) - req.Versions(it.query.Versions) - req.PageToken(it.query.Cursor) - if it.pageSize > 0 { - req.MaxResults(int64(it.pageSize)) - } - resp, err := req.Context(it.ctx).Do() - if err != nil { - it.err = err - return - } - it.query.Cursor = resp.NextPageToken - it.objs = nil - for _, item := range resp.Items { - it.objs = append(it.objs, newObject(item)) - } - it.prefixes = resp.Prefixes -} - -// SetPageSize sets the page size for all subsequent calls to NextPage. -// NextPage will return exactly this many items if they are present. -func (it *ObjectIterator) SetPageSize(pageSize int32) { - it.pageSize = pageSize -} - -// SetPageToken sets the page token for the next call to NextPage, to resume -// the iteration from a previous point. -func (it *ObjectIterator) SetPageToken(t string) { - it.query.Cursor = t -} - -// NextPageToken returns a page token that can be used with SetPageToken to -// resume iteration from the next page. It returns the empty string if there -// are no more pages. For an example, see SetPageToken. -func (it *ObjectIterator) NextPageToken() string { - return it.query.Cursor -} - -// SignedURLOptions allows you to restrict the access to the signed URL. -type SignedURLOptions struct { - // GoogleAccessID represents the authorizer of the signed URL generation. - // It is typically the Google service account client email address from - // the Google Developers Console in the form of "xxx@developer.gserviceaccount.com". - // Required. - GoogleAccessID string - - // PrivateKey is the Google service account private key. It is obtainable - // from the Google Developers Console. - // At https://console.developers.google.com/project//apiui/credential, - // create a service account client ID or reuse one of your existing service account - // credentials. Click on the "Generate new P12 key" to generate and download - // a new private key. Once you download the P12 file, use the following command - // to convert it into a PEM file. - // - // $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes - // - // Provide the contents of the PEM file as a byte slice. - // Exactly one of PrivateKey or SignBytes must be non-nil. - PrivateKey []byte - - // SignBytes is a function for implementing custom signing. - // If your application is running on Google App Engine, you can use appengine's internal signing function: - // ctx := appengine.NewContext(request) - // acc, _ := appengine.ServiceAccount(ctx) - // url, err := SignedURL("bucket", "object", &SignedURLOptions{ - // GoogleAccessID: acc, - // SignBytes: func(b []byte) ([]byte, error) { - // _, signedBytes, err := appengine.SignBytes(ctx, b) - // return signedBytes, err - // }, - // // etc. - // }) - // - // Exactly one of PrivateKey or SignBytes must be non-nil. - SignBytes func([]byte) ([]byte, error) - - // Method is the HTTP method to be used with the signed URL. - // Signed URLs can be used with GET, HEAD, PUT, and DELETE requests. - // Required. - Method string - - // Expires is the expiration time on the signed URL. It must be - // a datetime in the future. - // Required. - Expires time.Time - - // ContentType is the content type header the client must provide - // to use the generated signed URL. - // Optional. - ContentType string - - // Headers is a list of extention headers the client must provide - // in order to use the generated signed URL. - // Optional. - Headers []string - - // MD5 is the base64 encoded MD5 checksum of the file. - // If provided, the client should provide the exact value on the request - // header in order to use the signed URL. - // Optional. - MD5 []byte -} - -// SignedURL returns a URL for the specified object. Signed URLs allow -// the users access to a restricted resource for a limited time without having a -// Google account or signing in. For more information about the signed -// URLs, see https://cloud.google.com/storage/docs/accesscontrol#Signed-URLs. -func SignedURL(bucket, name string, opts *SignedURLOptions) (string, error) { - if opts == nil { - return "", errors.New("storage: missing required SignedURLOptions") - } - if opts.GoogleAccessID == "" { - return "", errors.New("storage: missing required GoogleAccessID") - } - if (opts.PrivateKey == nil) == (opts.SignBytes == nil) { - return "", errors.New("storage: exactly one of PrivateKey or SignedBytes must be set") - } - if opts.Method == "" { - return "", errors.New("storage: missing required method option") - } - if opts.Expires.IsZero() { - return "", errors.New("storage: missing required expires option") - } - - signBytes := opts.SignBytes - if opts.PrivateKey != nil { - key, err := parseKey(opts.PrivateKey) - if err != nil { - return "", err - } - signBytes = func(b []byte) ([]byte, error) { - sum := sha256.Sum256(b) - return rsa.SignPKCS1v15( - rand.Reader, - key, - crypto.SHA256, - sum[:], - ) - } - } else { - signBytes = opts.SignBytes - } - - u := &url.URL{ - Path: fmt.Sprintf("/%s/%s", bucket, name), - } - - buf := &bytes.Buffer{} - fmt.Fprintf(buf, "%s\n", opts.Method) - fmt.Fprintf(buf, "%s\n", opts.MD5) - fmt.Fprintf(buf, "%s\n", opts.ContentType) - fmt.Fprintf(buf, "%d\n", opts.Expires.Unix()) - fmt.Fprintf(buf, "%s", strings.Join(opts.Headers, "\n")) - fmt.Fprintf(buf, "%s", u.String()) - - b, err := signBytes(buf.Bytes()) - if err != nil { - return "", err - } - encoded := base64.StdEncoding.EncodeToString(b) - u.Scheme = "https" - u.Host = "storage.googleapis.com" - q := u.Query() - q.Set("GoogleAccessId", opts.GoogleAccessID) - q.Set("Expires", fmt.Sprintf("%d", opts.Expires.Unix())) - q.Set("Signature", string(encoded)) - u.RawQuery = q.Encode() - return u.String(), nil -} - -// 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 - conds []Condition -} - -// ACL provides access to the object's access control list. -// This controls who can read and write this object. -// This call does not perform any network operations. -func (o *ObjectHandle) ACL() *ACLHandle { - return o.acl -} - -// WithConditions returns a copy of o using the provided conditions. -func (o *ObjectHandle) WithConditions(conds ...Condition) *ObjectHandle { - o2 := *o - o2.conds = conds - 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) { - if !utf8.ValidString(o.object) { - return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) - } - call := o.c.raw.Objects.Get(o.bucket, o.object).Projection("full").Context(ctx) - if err := applyConds("Attrs", o.conds, call); err != nil { - return nil, err - } - obj, err := call.Do() - if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { - return nil, ErrObjectNotExist - } - if err != nil { - return nil, err - } - return newObject(obj), nil -} - -// Update updates an object with the provided attributes. -// All zero-value attributes are ignored. -// ErrObjectNotExist will be returned if the object is not found. -func (o *ObjectHandle) Update(ctx context.Context, attrs ObjectAttrs) (*ObjectAttrs, error) { - if !utf8.ValidString(o.object) { - return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) - } - call := o.c.raw.Objects.Patch(o.bucket, o.object, attrs.toRawObject(o.bucket)).Projection("full").Context(ctx) - if err := applyConds("Update", o.conds, call); err != nil { - return nil, err - } - obj, err := call.Do() - if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound { - return nil, ErrObjectNotExist - } - if err != nil { - return nil, err - } - return newObject(obj), nil -} - -// Delete deletes the single specified object. -func (o *ObjectHandle) Delete(ctx context.Context) error { - if !utf8.ValidString(o.object) { - return fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) - } - call := o.c.raw.Objects.Delete(o.bucket, o.object).Context(ctx) - if err := applyConds("Delete", o.conds, call); err != nil { - return err - } - err := call.Do() - switch e := err.(type) { - case nil: - return nil - case *googleapi.Error: - if e.Code == http.StatusNotFound { - return ErrObjectNotExist - } - } - return err -} - -// CopyTo copies the object to the given dst. -// The copied object's attributes are overwritten by attrs if non-nil. -func (o *ObjectHandle) CopyTo(ctx context.Context, dst *ObjectHandle, attrs *ObjectAttrs) (*ObjectAttrs, error) { - // TODO(djd): move bucket/object name validation to a single helper func. - if o.bucket == "" || dst.bucket == "" { - return nil, errors.New("storage: the source and destination bucket names must both be non-empty") - } - if o.object == "" || dst.object == "" { - return nil, errors.New("storage: the source and destination object names must both be non-empty") - } - if !utf8.ValidString(o.object) { - return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) - } - if !utf8.ValidString(dst.object) { - return nil, fmt.Errorf("storage: dst name %q is not valid UTF-8", dst.object) - } - var rawObject *raw.Object - if attrs != nil { - attrs.Name = dst.object - if attrs.ContentType == "" { - return nil, errors.New("storage: attrs.ContentType must be non-empty") - } - rawObject = attrs.toRawObject(dst.bucket) - } - call := o.c.raw.Objects.Copy(o.bucket, o.object, dst.bucket, dst.object, rawObject).Projection("full").Context(ctx) - if err := applyConds("CopyTo destination", dst.conds, call); err != nil { - return nil, err - } - if err := applyConds("CopyTo source", toSourceConds(o.conds), call); err != nil { - return nil, err - } - obj, err := call.Do() - if err != nil { - return nil, err - } - return newObject(obj), nil -} - -// NewReader creates a new Reader to read the contents of the -// object. -// ErrObjectNotExist will be returned if the object is not found. -func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) { - return o.NewRangeReader(ctx, 0, -1) -} - -// NewRangeReader reads part of an object, reading at most length bytes -// starting at the given offset. If length is negative, the object is read -// until the end. -func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, length int64) (*Reader, error) { - if !utf8.ValidString(o.object) { - return nil, fmt.Errorf("storage: object name %q is not valid UTF-8", o.object) - } - if offset < 0 { - return nil, fmt.Errorf("storage: invalid offset %d < 0", offset) - } - u := &url.URL{ - Scheme: "https", - Host: "storage.googleapis.com", - Path: fmt.Sprintf("/%s/%s", o.bucket, o.object), - } - verb := "GET" - if length == 0 { - verb = "HEAD" - } - req, err := http.NewRequest(verb, u.String(), nil) - if err != nil { - return nil, err - } - if err := applyConds("NewReader", o.conds, objectsGetCall{req}); err != nil { - return nil, err - } - if length < 0 && offset > 0 { - req.Header.Set("Range", fmt.Sprintf("bytes=%d-", offset)) - } else if length > 0 { - req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+length-1)) - } - res, err := o.c.hc.Do(req) - if err != nil { - return nil, err - } - if res.StatusCode == http.StatusNotFound { - res.Body.Close() - return nil, ErrObjectNotExist - } - if res.StatusCode < 200 || res.StatusCode > 299 { - body, _ := ioutil.ReadAll(res.Body) - res.Body.Close() - return nil, &googleapi.Error{ - Code: res.StatusCode, - Header: res.Header, - Body: string(body), - } - } - if offset > 0 && length != 0 && res.StatusCode != http.StatusPartialContent { - res.Body.Close() - return nil, errors.New("storage: partial request not satisfied") - } - clHeader := res.Header.Get("X-Goog-Stored-Content-Length") - cl, err := strconv.ParseInt(clHeader, 10, 64) - if err != nil { - return nil, fmt.Errorf("storage: can't parse content length %q: %v", clHeader, err) - } - remain := res.ContentLength - body := res.Body - if length == 0 { - remain = 0 - body.Close() - body = emptyBody - } - return &Reader{ - body: body, - size: cl, - remain: remain, - contentType: res.Header.Get("Content-Type"), - }, nil -} - -var emptyBody = ioutil.NopCloser(strings.NewReader("")) - -// NewWriter returns a storage Writer that writes to the GCS object -// associated with this ObjectHandle. -// -// A new object will be created if an object with this name already exists. -// Otherwise any previous object with the same name will be replaced. -// The object will not be available (and any previous object will remain) -// until Close has been called. -// -// Attributes can be set on the object by modifying the returned Writer's -// ObjectAttrs field before the first call to Write. If no ContentType -// attribute is specified, the content type will be automatically sniffed -// using net/http.DetectContentType. -// -// It is the caller's responsibility to call Close when writing is done. -func (o *ObjectHandle) NewWriter(ctx context.Context) *Writer { - return &Writer{ - ctx: ctx, - o: o, - donec: make(chan struct{}), - ObjectAttrs: ObjectAttrs{Name: o.object}, - } -} - -// parseKey converts the binary contents of a private key file -// to an *rsa.PrivateKey. It detects whether the private key is in a -// PEM container or not. If so, it extracts the the private key -// from PEM container before conversion. It only supports PEM -// containers with no passphrase. -func parseKey(key []byte) (*rsa.PrivateKey, error) { - if block, _ := pem.Decode(key); block != nil { - key = block.Bytes - } - parsedKey, err := x509.ParsePKCS8PrivateKey(key) - if err != nil { - parsedKey, err = x509.ParsePKCS1PrivateKey(key) - if err != nil { - return nil, err - } - } - parsed, ok := parsedKey.(*rsa.PrivateKey) - if !ok { - return nil, errors.New("oauth2: private key is invalid") - } - return parsed, nil -} - -// BucketAttrs represents the metadata for a Google Cloud Storage bucket. -type BucketAttrs struct { - // Name is the name of the bucket. - Name string - - // ACL is the list of access control rules on the bucket. - ACL []ACLRule - - // DefaultObjectACL is the list of access controls to - // apply to new objects when no object ACL is provided. - DefaultObjectACL []ACLRule - - // Location is the location of the bucket. It defaults to "US". - Location string - - // MetaGeneration is the metadata generation of the bucket. - MetaGeneration int64 - - // StorageClass is the storage class of the bucket. This defines - // how objects in the bucket are stored and determines the SLA - // and the cost of storage. Typical values are "STANDARD" and - // "DURABLE_REDUCED_AVAILABILITY". Defaults to "STANDARD". - StorageClass string - - // Created is the creation time of the bucket. - Created time.Time -} - -func newBucket(b *raw.Bucket) *BucketAttrs { - if b == nil { - return nil - } - bucket := &BucketAttrs{ - Name: b.Name, - Location: b.Location, - MetaGeneration: b.Metageneration, - StorageClass: b.StorageClass, - Created: convertTime(b.TimeCreated), - } - acl := make([]ACLRule, len(b.Acl)) - for i, rule := range b.Acl { - acl[i] = ACLRule{ - Entity: ACLEntity(rule.Entity), - Role: ACLRole(rule.Role), - } - } - bucket.ACL = acl - objACL := make([]ACLRule, len(b.DefaultObjectAcl)) - for i, rule := range b.DefaultObjectAcl { - objACL[i] = ACLRule{ - Entity: ACLEntity(rule.Entity), - Role: ACLRole(rule.Role), - } - } - bucket.DefaultObjectACL = objACL - return bucket -} - -func toRawObjectACL(oldACL []ACLRule) []*raw.ObjectAccessControl { - var acl []*raw.ObjectAccessControl - if len(oldACL) > 0 { - acl = make([]*raw.ObjectAccessControl, len(oldACL)) - for i, rule := range oldACL { - acl[i] = &raw.ObjectAccessControl{ - Entity: string(rule.Entity), - Role: string(rule.Role), - } - } - } - return acl -} - -// toRawBucket copies the editable attribute from b to the raw library's Bucket type. -func (b *BucketAttrs) toRawBucket() *raw.Bucket { - var acl []*raw.BucketAccessControl - if len(b.ACL) > 0 { - acl = make([]*raw.BucketAccessControl, len(b.ACL)) - for i, rule := range b.ACL { - acl[i] = &raw.BucketAccessControl{ - Entity: string(rule.Entity), - Role: string(rule.Role), - } - } - } - dACL := toRawObjectACL(b.DefaultObjectACL) - return &raw.Bucket{ - Name: b.Name, - DefaultObjectAcl: dACL, - Location: b.Location, - StorageClass: b.StorageClass, - Acl: acl, - } -} - -// toRawObject copies the editable attributes from o to the raw library's Object type. -func (o ObjectAttrs) toRawObject(bucket string) *raw.Object { - acl := toRawObjectACL(o.ACL) - return &raw.Object{ - Bucket: bucket, - Name: o.Name, - ContentType: o.ContentType, - ContentEncoding: o.ContentEncoding, - ContentLanguage: o.ContentLanguage, - CacheControl: o.CacheControl, - ContentDisposition: o.ContentDisposition, - Acl: acl, - Metadata: o.Metadata, - } -} - -// ObjectAttrs represents the metadata for a Google Cloud Storage (GCS) object. -type ObjectAttrs struct { - // Bucket is the name of the bucket containing this GCS object. - // This field is read-only. - Bucket string - - // Name is the name of the object within the bucket. - // This field is read-only. - Name string - - // ContentType is the MIME type of the object's content. - ContentType string - - // ContentLanguage is the content language of the object's content. - ContentLanguage string - - // CacheControl is the Cache-Control header to be sent in the response - // headers when serving the object data. - CacheControl string - - // ACL is the list of access control rules for the object. - ACL []ACLRule - - // Owner is the owner of the object. This field is read-only. - // - // If non-zero, it is in the form of "user-". - Owner string - - // Size is the length of the object's content. This field is read-only. - Size int64 - - // ContentEncoding is the encoding of the object's content. - ContentEncoding string - - // ContentDisposition is the optional Content-Disposition header of the object - // sent in the response headers. - ContentDisposition string - - // MD5 is the MD5 hash of the object's content. This field is read-only. - MD5 []byte - - // CRC32C is the CRC32 checksum of the object's content using - // the Castagnoli93 polynomial. This field is read-only. - CRC32C uint32 - - // MediaLink is an URL to the object's content. This field is read-only. - MediaLink string - - // Metadata represents user-provided metadata, in key/value pairs. - // It can be nil if no metadata is provided. - Metadata map[string]string - - // Generation is the generation number of the object's content. - // This field is read-only. - Generation int64 - - // MetaGeneration is the version of the metadata for this - // object at this generation. This field is used for preconditions - // and for detecting changes in metadata. A metageneration number - // is only meaningful in the context of a particular generation - // of a particular object. This field is read-only. - MetaGeneration int64 - - // StorageClass is the storage class of the bucket. - // This value defines how objects in the bucket are stored and - // determines the SLA and the cost of storage. Typical values are - // "STANDARD" and "DURABLE_REDUCED_AVAILABILITY". - // It defaults to "STANDARD". This field is read-only. - StorageClass string - - // Created is the time the object was created. This field is read-only. - Created time.Time - - // Deleted is the time the object was deleted. - // If not deleted, it is the zero value. This field is read-only. - Deleted time.Time - - // Updated is the creation or modification time of the object. - // For buckets with versioning enabled, changing an object's - // metadata does not change this property. This field is read-only. - Updated time.Time -} - -// convertTime converts a time in RFC3339 format to time.Time. -// If any error occurs in parsing, the zero-value time.Time is silently returned. -func convertTime(t string) time.Time { - var r time.Time - if t != "" { - r, _ = time.Parse(time.RFC3339, t) - } - return r -} - -func newObject(o *raw.Object) *ObjectAttrs { - if o == nil { - return nil - } - acl := make([]ACLRule, len(o.Acl)) - for i, rule := range o.Acl { - acl[i] = ACLRule{ - Entity: ACLEntity(rule.Entity), - Role: ACLRole(rule.Role), - } - } - owner := "" - if o.Owner != nil { - owner = o.Owner.Entity - } - md5, _ := base64.StdEncoding.DecodeString(o.Md5Hash) - var crc32c uint32 - d, err := base64.StdEncoding.DecodeString(o.Crc32c) - if err == nil && len(d) == 4 { - crc32c = uint32(d[0])<<24 + uint32(d[1])<<16 + uint32(d[2])<<8 + uint32(d[3]) - } - 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), - } -} - -// Query represents a query to filter objects from a bucket. -type Query struct { - // Delimiter returns results in a directory-like fashion. - // Results will contain only objects whose names, aside from the - // prefix, do not contain delimiter. Objects whose names, - // aside from the prefix, contain delimiter will have their name, - // truncated after the delimiter, returned in prefixes. - // Duplicate prefixes are omitted. - // Optional. - Delimiter string - - // Prefix is the prefix filter to query objects - // whose names begin with this prefix. - // Optional. - Prefix string - - // Versions indicates whether multiple versions of the same - // object will be included in the results. - Versions bool - - // Cursor is a previously-returned page token - // representing part of the larger set of results to view. - // Optional. - Cursor string - - // MaxResults is the maximum number of items plus prefixes - // to return. As duplicate prefixes are omitted, - // fewer total results may be returned than requested. - // The default page limit is used if it is negative or zero. - // - // Deprecated. Use ObjectIterator.SetPageSize. - MaxResults int -} - -// ObjectList represents a list of objects returned from a bucket List call. -type ObjectList struct { - // Results represent a list of object results. - Results []*ObjectAttrs - - // Next is the continuation query to retrieve more - // results with the same filtering criteria. If there - // are no more results to retrieve, it is nil. - Next *Query - - // Prefixes represents prefixes of objects - // matching-but-not-listed up to and including - // the requested delimiter. - Prefixes []string -} - -// contentTyper implements ContentTyper to enable an -// io.ReadCloser to specify its MIME type. -type contentTyper struct { - io.Reader - t string -} - -func (c *contentTyper) ContentType() string { - return c.t -} - -// A Condition constrains methods to act on specific generations of -// resources. -// -// Not all conditions or combinations of conditions are applicable to -// all methods. -type Condition interface { - // method is the high-level ObjectHandle method name, for - // error messages. call is the call object to modify. - modifyCall(method string, call interface{}) error -} - -// applyConds modifies the provided call using the conditions in conds. -// call is something that quacks like a *raw.WhateverCall. -func applyConds(method string, conds []Condition, call interface{}) error { - for _, cond := range conds { - if err := cond.modifyCall(method, call); err != nil { - return err - } - } - return nil -} - -// toSourceConds returns a slice of Conditions derived from Conds that instead -// function on the equivalent Source methods of a call. -func toSourceConds(conds []Condition) []Condition { - out := make([]Condition, 0, len(conds)) - for _, c := range conds { - switch c := c.(type) { - case genCond: - var m string - if strings.HasPrefix(c.method, "If") { - m = "IfSource" + c.method[2:] - } else { - m = "Source" + c.method - } - out = append(out, genCond{method: m, val: c.val}) - default: - // NOTE(djd): If the message from unsupportedCond becomes - // confusing, we'll need to find a way for Conditions to - // identify themselves. - out = append(out, unsupportedCond{}) - } - } - return out -} - -func Generation(gen int64) Condition { return genCond{"Generation", gen} } -func IfGenerationMatch(gen int64) Condition { return genCond{"IfGenerationMatch", gen} } -func IfGenerationNotMatch(gen int64) Condition { return genCond{"IfGenerationNotMatch", gen} } -func IfMetaGenerationMatch(gen int64) Condition { return genCond{"IfMetagenerationMatch", gen} } -func IfMetaGenerationNotMatch(gen int64) Condition { return genCond{"IfMetagenerationNotMatch", gen} } - -type genCond struct { - method string - val int64 -} - -func (g genCond) modifyCall(srcMethod string, call interface{}) error { - rv := reflect.ValueOf(call) - meth := rv.MethodByName(g.method) - if !meth.IsValid() { - return fmt.Errorf("%s: condition %s not supported", srcMethod, g.method) - } - meth.Call([]reflect.Value{reflect.ValueOf(g.val)}) - return nil -} - -type unsupportedCond struct{} - -func (unsupportedCond) modifyCall(srcMethod string, call interface{}) error { - return fmt.Errorf("%s: condition not supported", srcMethod) -} - -func appendParam(req *http.Request, k, v string) { - sep := "" - if req.URL.RawQuery != "" { - sep = "&" - } - req.URL.RawQuery += sep + url.QueryEscape(k) + "=" + url.QueryEscape(v) -} - -// objectsGetCall wraps an *http.Request for an object fetch call, but adds the methods -// that modifyCall searches for by name. (the same names as the raw, auto-generated API) -type objectsGetCall struct{ req *http.Request } - -func (c objectsGetCall) Generation(gen int64) { - appendParam(c.req, "generation", fmt.Sprint(gen)) -} -func (c objectsGetCall) IfGenerationMatch(gen int64) { - appendParam(c.req, "ifGenerationMatch", fmt.Sprint(gen)) -} -func (c objectsGetCall) IfGenerationNotMatch(gen int64) { - appendParam(c.req, "ifGenerationNotMatch", fmt.Sprint(gen)) -} -func (c objectsGetCall) IfMetagenerationMatch(gen int64) { - appendParam(c.req, "ifMetagenerationMatch", fmt.Sprint(gen)) -} -func (c objectsGetCall) IfMetagenerationNotMatch(gen int64) { - appendParam(c.req, "ifMetagenerationNotMatch", fmt.Sprint(gen)) -} diff --git a/vendor/google.golang.org/cloud/storage/writer.go b/vendor/google.golang.org/cloud/storage/writer.go deleted file mode 100644 index 60937c0..0000000 --- a/vendor/google.golang.org/cloud/storage/writer.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2014 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 storage - -import ( - "fmt" - "io" - "unicode/utf8" - - "golang.org/x/net/context" - "google.golang.org/api/googleapi" - raw "google.golang.org/api/storage/v1" -) - -// A Writer writes a Cloud Storage object. -type Writer struct { - // ObjectAttrs are optional attributes to set on the object. Any attributes - // must be initialized before the first Write call. Nil or zero-valued - // attributes are ignored. - ObjectAttrs - - ctx context.Context - o *ObjectHandle - - opened bool - pw *io.PipeWriter - - donec chan struct{} // closed after err and obj are set. - err error - obj *ObjectAttrs -} - -func (w *Writer) open() error { - attrs := w.ObjectAttrs - // Check the developer didn't change the object Name (this is unfortunate, but - // we don't want to store an object under the wrong name). - if attrs.Name != w.o.object { - return fmt.Errorf("storage: Writer.Name %q does not match object name %q", attrs.Name, w.o.object) - } - if !utf8.ValidString(attrs.Name) { - return fmt.Errorf("storage: object name %q is not valid UTF-8", attrs.Name) - } - pr, pw := io.Pipe() - w.pw = pw - w.opened = true - - var mediaOpts []googleapi.MediaOption - if c := attrs.ContentType; c != "" { - mediaOpts = append(mediaOpts, googleapi.ContentType(c)) - } - - go func() { - defer close(w.donec) - - call := w.o.c.raw.Objects.Insert(w.o.bucket, attrs.toRawObject(w.o.bucket)). - Media(pr, mediaOpts...). - Projection("full"). - Context(w.ctx) - - var resp *raw.Object - err := applyConds("NewWriter", w.o.conds, call) - if err == nil { - resp, err = call.Do() - } - if err != nil { - w.err = err - pr.CloseWithError(w.err) - return - } - w.obj = newObject(resp) - }() - return nil -} - -// Write appends to w. -func (w *Writer) Write(p []byte) (n int, err error) { - if w.err != nil { - return 0, w.err - } - if !w.opened { - if err := w.open(); err != nil { - return 0, err - } - } - return w.pw.Write(p) -} - -// Close completes the write operation and flushes any buffered data. -// If Close doesn't return an error, metadata about the written object -// can be retrieved by calling Object. -func (w *Writer) Close() error { - if !w.opened { - if err := w.open(); err != nil { - return err - } - } - if err := w.pw.Close(); err != nil { - return err - } - <-w.donec - return w.err -} - -// CloseWithError aborts the write operation with the provided error. -// CloseWithError always returns nil. -func (w *Writer) CloseWithError(err error) error { - if !w.opened { - return nil - } - return w.pw.CloseWithError(err) -} - -// ObjectAttrs returns metadata about a successfully-written object. -// It's only valid to call it after Close returns nil. -func (w *Writer) Attrs() *ObjectAttrs { - return w.obj -} diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go index 419e214..e217a20 100644 --- a/vendor/google.golang.org/grpc/balancer.go +++ b/vendor/google.golang.org/grpc/balancer.go @@ -38,6 +38,7 @@ import ( "sync" "golang.org/x/net/context" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/naming" ) @@ -52,6 +53,14 @@ type Address struct { Metadata interface{} } +// BalancerConfig specifies the configurations for Balancer. +type BalancerConfig struct { + // DialCreds is the transport credential the Balancer implementation can + // use to dial to a remote load balancer server. The Balancer implementations + // can ignore this if it does not need to talk to another party securely. + DialCreds credentials.TransportCredentials +} + // BalancerGetOptions configures a Get call. // This is the EXPERIMENTAL API and may be changed or extended in the future. type BalancerGetOptions struct { @@ -66,11 +75,11 @@ type Balancer interface { // Start does the initialization work to bootstrap a Balancer. For example, // this function may start the name resolution and watch the updates. It will // be called when dialing. - Start(target string) error + Start(target string, config BalancerConfig) error // Up informs the Balancer that gRPC has a connection to the server at // addr. It returns down which is called once the connection to addr gets // lost or closed. - // TODO: It is not clear how to construct and take advantage the meaningful error + // TODO: It is not clear how to construct and take advantage of the meaningful error // parameter for down. Need realistic demands to guide. Up(addr Address) (down func(error)) // Get gets the address of a server for the RPC corresponding to ctx. @@ -205,7 +214,12 @@ func (rr *roundRobin) watchAddrUpdates() error { return nil } -func (rr *roundRobin) Start(target string) error { +func (rr *roundRobin) Start(target string, config BalancerConfig) error { + rr.mu.Lock() + defer rr.mu.Unlock() + if rr.done { + return ErrClientConnClosing + } if rr.r == nil { // If there is no name resolver installed, it is not needed to // do name resolution. In this case, target is added into rr.addrs diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index a257f01..11dce44 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -270,31 +270,47 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * if cc.dopts.bs == nil { cc.dopts.bs = DefaultBackoffConfig } - - var ( - ok bool - addrs []Address - ) - if cc.dopts.balancer == nil { - // Connect to target directly if balancer is nil. - addrs = append(addrs, Address{Addr: target}) + creds := cc.dopts.copts.TransportCredentials + if creds != nil && creds.Info().ServerName != "" { + cc.authority = creds.Info().ServerName } else { - if err := cc.dopts.balancer.Start(target); err != nil { - return nil, err + colonPos := strings.LastIndex(target, ":") + if colonPos == -1 { + colonPos = len(target) } - ch := cc.dopts.balancer.Notify() - if ch == nil { - // There is no name resolver installed. + cc.authority = target[:colonPos] + } + var ok bool + waitC := make(chan error, 1) + go func() { + var addrs []Address + if cc.dopts.balancer == nil { + // Connect to target directly if balancer is nil. addrs = append(addrs, Address{Addr: target}) } else { - addrs, ok = <-ch - if !ok || len(addrs) == 0 { - return nil, errNoAddr + var credsClone credentials.TransportCredentials + if creds != nil { + credsClone = creds.Clone() + } + config := BalancerConfig{ + DialCreds: credsClone, + } + if err := cc.dopts.balancer.Start(target, config); err != nil { + waitC <- err + return + } + ch := cc.dopts.balancer.Notify() + if ch == nil { + // There is no name resolver installed. + addrs = append(addrs, Address{Addr: target}) + } else { + addrs, ok = <-ch + if !ok || len(addrs) == 0 { + waitC <- errNoAddr + return + } } } - } - waitC := make(chan error, 1) - go func() { for _, a := range addrs { if err := cc.resetAddrConn(a, false, nil); err != nil { waitC <- err @@ -322,11 +338,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * if ok { go cc.lbWatcher() } - colonPos := strings.LastIndex(target, ":") - if colonPos == -1 { - colonPos = len(target) - } - cc.authority = target[:colonPos] return cc, nil } @@ -680,7 +691,7 @@ func (ac *addrConn) resetTransport(closeTransport bool) error { if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() { return err } - grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, ac.addr) + grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %v", err, ac.addr) ac.mu.Lock() if ac.state == Shutdown { // ac.tearDown(...) has been invoked. diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 13be457..5555ef0 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -72,7 +72,7 @@ type PerRPCCredentials interface { } // ProtocolInfo provides information regarding the gRPC wire protocol version, -// security protocol, security protocol version in use, etc. +// security protocol, security protocol version in use, server name, etc. type ProtocolInfo struct { // ProtocolVersion is the gRPC wire protocol version. ProtocolVersion string @@ -80,6 +80,8 @@ type ProtocolInfo struct { SecurityProtocol string // SecurityVersion is the security protocol version. SecurityVersion string + // ServerName is the user-configured server name. + ServerName string } // AuthInfo defines the common interface for the auth information the users are interested in. @@ -107,6 +109,12 @@ type TransportCredentials interface { ServerHandshake(net.Conn) (net.Conn, AuthInfo, error) // Info provides the ProtocolInfo of this TransportCredentials. Info() ProtocolInfo + // Clone makes a copy of this TransportCredentials. + Clone() TransportCredentials + // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server. + // gRPC internals also use it to override the virtual hosting name if it is set. + // It must be called before dialing. Currently, this is only used by grpclb. + OverrideServerName(string) error } // TLSInfo contains the auth information for a TLS authenticated connection. @@ -130,19 +138,10 @@ func (c tlsCreds) Info() ProtocolInfo { return ProtocolInfo{ SecurityProtocol: "tls", SecurityVersion: "1.2", + ServerName: c.config.ServerName, } } -// GetRequestMetadata returns nil, nil since TLS credentials does not have -// metadata. -func (c *tlsCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { - return nil, nil -} - -func (c *tlsCreds) RequireTransportSecurity() bool { - return true -} - func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) { // use local cfg to avoid clobbering ServerName if using multiple endpoints cfg := cloneTLSConfig(c.config) @@ -179,6 +178,15 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) return conn, TLSInfo{conn.ConnectionState()}, nil } +func (c *tlsCreds) Clone() TransportCredentials { + return NewTLS(c.config) +} + +func (c *tlsCreds) OverrideServerName(serverNameOverride string) error { + c.config.ServerName = serverNameOverride + return nil +} + // NewTLS uses c to construct a TransportCredentials based on TLS. func NewTLS(c *tls.Config) TransportCredentials { tc := &tlsCreds{cloneTLSConfig(c)} @@ -187,12 +195,16 @@ func NewTLS(c *tls.Config) TransportCredentials { } // NewClientTLSFromCert constructs a TLS from the input certificate for client. -func NewClientTLSFromCert(cp *x509.CertPool, serverName string) TransportCredentials { - return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}) +// serverNameOverride is for testing only. If set to a non empty string, +// it will override the virtual host name of authority (e.g. :authority header field) in requests. +func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials { + return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}) } // NewClientTLSFromFile constructs a TLS from the input certificate file for client. -func NewClientTLSFromFile(certFile, serverName string) (TransportCredentials, error) { +// serverNameOverride is for testing only. If set to a non empty string, +// it will override the virtual host name of authority (e.g. :authority header field) in requests. +func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) { b, err := ioutil.ReadFile(certFile) if err != nil { return nil, err @@ -201,7 +213,7 @@ func NewClientTLSFromFile(certFile, serverName string) (TransportCredentials, er if !cp.AppendCertsFromPEM(b) { return nil, fmt.Errorf("credentials: failed to append certificates") } - return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}), nil + return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil } // NewServerTLSFromCert constructs a TLS from the input certificate for server. diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index 954c0f7..3c0ca7a 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -117,10 +117,17 @@ func (md MD) Len() int { // Copy returns a copy of md. func (md MD) Copy() MD { + return Join(md) +} + +// Join joins any number of MDs into a single MD. +// The order of values for each key is determined by the order in which +// the MDs containing those values are presented to Join. +func Join(mds ...MD) MD { out := MD{} - for k, v := range md { - for _, i := range v { - out[k] = append(out[k], i) + for _, md := range mds { + for k, v := range md { + out[k] = append(out[k], v...) } } return out diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 2524dd2..debbd79 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -873,25 +873,28 @@ func SendHeader(ctx context.Context, md metadata.MD) error { } stream, ok := transport.StreamFromContext(ctx) if !ok { - return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx) + return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx) } t := stream.ServerTransport() if t == nil { grpclog.Fatalf("grpc: SendHeader: %v has no ServerTransport to send header metadata.", stream) } - return t.WriteHeader(stream, md) + if err := t.WriteHeader(stream, md); err != nil { + return toRPCErr(err) + } + return nil } // SetTrailer sets the trailer metadata that will be sent when an RPC returns. -// It may be called at most once from a unary RPC handler. The ctx is the RPC -// handler's Context or one derived from it. +// When called more than once, all the provided metadata will be merged. +// The ctx is the RPC handler's Context or one derived from it. func SetTrailer(ctx context.Context, md metadata.MD) error { if md.Len() == 0 { return nil } stream, ok := transport.StreamFromContext(ctx) if !ok { - return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx) + return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx) } return stream.SetTrailer(md) } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index e1b4759..68d777b 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -414,8 +414,8 @@ type ServerStream interface { // after SendProto. It fails if called multiple times or if // called after SendProto. SendHeader(metadata.MD) error - // SetTrailer sets the trailer metadata which will be sent with the - // RPC status. + // SetTrailer sets the trailer metadata which will be sent with the RPC status. + // When called more than once, all the provided metadata will be merged. SetTrailer(metadata.MD) Stream } diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go index 4892faa..3c18554 100644 --- a/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/transport/http2_client.go @@ -252,8 +252,10 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { s.windowHandler = func(n int) { t.updateWindow(s, uint32(n)) } - // Make a stream be able to cancel the pending operations by itself. - s.ctx, s.cancel = context.WithCancel(ctx) + // The client side stream context should have exactly the same life cycle with the user provided context. + // That means, s.ctx should be read-only. And s.ctx is done iff ctx is done. + // So we use the original context here instead of creating a copy. + s.ctx = ctx s.dec = &recvBufferReader{ ctx: s.ctx, goAway: s.goAway, @@ -265,16 +267,6 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { // NewStream creates a stream and register it into the transport as "active" // streams. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { - // Record the timeout value on the context. - var timeout time.Duration - if dl, ok := ctx.Deadline(); ok { - timeout = dl.Sub(time.Now()) - } - select { - case <-ctx.Done(): - return nil, ContextErr(ctx.Err()) - default: - } pr := &peer.Peer{ Addr: t.conn.RemoteAddr(), } @@ -381,9 +373,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea if callHdr.SendCompress != "" { t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress}) } - if timeout > 0 { + if dl, ok := ctx.Deadline(); ok { + // Send out timeout regardless its value. The server can detect timeout context by itself. + timeout := dl.Sub(time.Now()) t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)}) } + for k, v := range authData { // Capital header names are illegal in HTTP/2. k = strings.ToLower(k) @@ -852,6 +847,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { state.processHeaderField(hf) } if state.err != nil { + s.mu.Lock() + if !s.headerDone { + close(s.headerChan) + s.headerDone = true + } + s.mu.Unlock() s.write(recvMsg{err: state.err}) // Something wrong. Stops reading even when there is remaining. return diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go index b024594..a3c68d4 100644 --- a/vendor/google.golang.org/grpc/transport/http_util.go +++ b/vendor/google.golang.org/grpc/transport/http_util.go @@ -253,6 +253,9 @@ func div(d, r time.Duration) int64 { // TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it. func encodeTimeout(t time.Duration) string { + if t <= 0 { + return "0n" + } if d := div(t, time.Nanosecond); d <= maxTimeoutValue { return strconv.FormatInt(d, 10) + "n" } @@ -349,7 +352,7 @@ func decodeGrpcMessageUnchecked(msg string) string { for i := 0; i < lenMsg; i++ { c := msg[i] if c == percentByte && i+2 < lenMsg { - parsed, err := strconv.ParseInt(msg[i+1:i+3], 16, 8) + parsed, err := strconv.ParseUint(msg[i+1:i+3], 16, 8) if err != nil { buf.WriteByte(c) } else { diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go index f4d8daf..3d6b6a6 100644 --- a/vendor/google.golang.org/grpc/transport/transport.go +++ b/vendor/google.golang.org/grpc/transport/transport.go @@ -39,7 +39,6 @@ package transport // import "google.golang.org/grpc/transport" import ( "bytes" - "errors" "fmt" "io" "net" @@ -169,7 +168,8 @@ type Stream struct { // nil for client side Stream. st ServerTransport // ctx is the associated context of the stream. - ctx context.Context + ctx context.Context + // cancel is always nil for client side Stream. cancel context.CancelFunc // done is closed when the final status arrives. done chan struct{} @@ -286,19 +286,12 @@ func (s *Stream) StatusDesc() string { return s.statusDesc } -// ErrIllegalTrailerSet indicates that the trailer has already been set or it -// is too late to do so. -var ErrIllegalTrailerSet = errors.New("transport: trailer has been set") - // SetTrailer sets the trailer metadata which will be sent with the RPC status -// by the server. This can only be called at most once. Server side only. +// by the server. This can be called multiple times. Server side only. func (s *Stream) SetTrailer(md metadata.MD) error { s.mu.Lock() defer s.mu.Unlock() - if s.trailer != nil { - return ErrIllegalTrailerSet - } - s.trailer = md.Copy() + s.trailer = metadata.Join(s.trailer, md) return nil } diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md index 7b8bd86..1884de6 100644 --- a/vendor/gopkg.in/yaml.v2/README.md +++ b/vendor/gopkg.in/yaml.v2/README.md @@ -42,7 +42,7 @@ The package API for yaml v2 will remain stable as described in [gopkg.in](https: License ------- -The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details. +The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. Example diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go index 085cddc..b13ab9f 100644 --- a/vendor/gopkg.in/yaml.v2/decode.go +++ b/vendor/gopkg.in/yaml.v2/decode.go @@ -251,7 +251,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { // // If n holds a null value, prepare returns before doing anything. func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { - if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") { + if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) { return out, false, false } again := true diff --git a/vendor/vendor.json b/vendor/vendor.json index d71754f..bbe3b5f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -19,172 +19,178 @@ "revision": "" }, { - "checksumSHA1": "U0dcMjJghtkeDI0oFpZa0pMt8yI=", + "checksumSHA1": "ZLRh6zW4/DnVsGpgtt+ZiIaEFKc=", "path": "cloud.google.com/go/compute/metadata", - "revision": "de848b02a4b8d92be5baa2a7ecb17c8ce0194d06", - "revisionTime": "2016-08-31T20:50:42Z" + "revision": "5af4269f950e91e917bab77f1138139023c868c2", + "revisionTime": "2016-10-07T18:02:40Z" }, { "checksumSHA1": "hiJXjkFEGy+sDFf6O58Ocdy9Rnk=", "path": "cloud.google.com/go/internal", - "revision": "de848b02a4b8d92be5baa2a7ecb17c8ce0194d06", - "revisionTime": "2016-08-31T20:50:42Z" + "revision": "5af4269f950e91e917bab77f1138139023c868c2", + "revisionTime": "2016-10-07T18:02:40Z" }, { - "checksumSHA1": "mocMTDVyOtc9Q4qXF6zuJpivR9c=", + "checksumSHA1": "2KjLp82zorcecUxEeoUqIWZtf1E=", + "path": "cloud.google.com/go/storage", + "revision": "5af4269f950e91e917bab77f1138139023c868c2", + "revisionTime": "2016-10-07T18:02:40Z" + }, + { + "checksumSHA1": "dq1GRxE/Qsvp1pawHFQ3vaFoYX4=", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "ppmwInOtC5Mj/dBBWVxL0KPEI0I=", + "checksumSHA1": "+q4vdl3l1Wom8K1wfIpJ4jlFsbY=", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "H/tMKHZU+Qka6RtYiGB50s2uA0s=", + "checksumSHA1": "/232RBWA3KnT7U+wciPS2+wmvR0=", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "gNWirlrTfSLbOe421hISBAhTqa4=", + "checksumSHA1": "c1N3Loy3AS9zD+m5CzpPNAED39U=", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "dNZNaOPfBPnzE2CBnfhXXZ9g9jU=", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "KQiUK/zr3mqnAXD7x/X55/iNme0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "4Ipx+5xN0gso+cENC2MHMWmQlR4=", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "nCMd1XKjgV21bEl7J8VZFqTV8PE=", + "checksumSHA1": "DwhFsNluCFEwqzyp3hbJR3q2Wqs=", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "U0SthWum+t9ACanK7SDJOg3dO6M=", + "checksumSHA1": "8E0fEBUJY/1lJOyVxzTxMGQGInk=", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "NyUg1P8ZS/LHAAQAk/4C5O4X3og=", + "checksumSHA1": "5Ac22YMTBmrX/CXaEIXzWljr8UY=", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "44uohX3kLsfZHHOqunr+qJnSCdw=", + "checksumSHA1": "BXuya7NrVg2BtHOM4ED5zAwDkg4=", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "7lla+sckQeF18wORAGuU2fFMlp4=", + "checksumSHA1": "OgyO1NRszPKURsDpob+zxUR157A=", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "Bm6UrYb2QCzpYseLwwgw6aetgRc=", "path": "github.com/aws/aws-sdk-go/private/endpoints", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "isoix7lTx4qIq2zI2xFADtti5SI=", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "5xzix1R8prUyWxgLnzUQoxTsfik=", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "TW/7U+/8ormL7acf6z2rv2hDD+s=", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "Y6Db2GGfGD9LPpcJIPj8vXE8BbQ=", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "eUEkjyMPAuekKBE4ou+nM9tXEas=", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", "path": "github.com/aws/aws-sdk-go/private/waiter", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "imxJucuPrgaPRMPtAgsu+Y7soB4=", + "checksumSHA1": "bTI27l3ylL0rGFLnFGkaBTnG1lE=", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "nH/itbdeFHpl4ysegdtgww9bFSA=", + "checksumSHA1": "jqpZ6GIYgpVv5yihtUcLtpBq3iw=", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "6ac30507cca29249f4d49af45a8efc98b84088ee", - "revisionTime": "2016-09-01T22:26:51Z" + "revision": "c0d7d3282e4c14991a4814de7eae4774e388de61", + "revisionTime": "2016-10-07T22:43:33Z" }, { - "checksumSHA1": "5rPfda8jFccr3A6heL+JAmi9K9g=", + "checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=", "path": "github.com/davecgh/go-spew/spew", - "revision": "6cf5744a041a0022271cefed95ba843f6d87fd51", - "revisionTime": "2016-08-16T17:40:47Z" + "revision": "6d212800a42e8ab5c146b8ace3490ee17e5225f9", + "revisionTime": "2016-09-07T16:21:46Z" }, { "checksumSHA1": "KCWVxG+J8SxHGlGiUghe0KBGsa8=", @@ -193,14 +199,13 @@ "revisionTime": "2016-08-07T23:55:29Z" }, { - "checksumSHA1": "xgjI2W3RGiQwNlxsOW2V9fJ9kaM=", + "checksumSHA1": "e2o/P8ZZ8Iz+um6/nyLUEg7S2H8=", "path": "github.com/fsnotify/fsnotify", - "revision": "f12c6236fe7b5cf6bcf30e5935d08cb079d78334", - "revisionTime": "2016-08-16T05:15:41Z" + "revision": "944cff21b3baf3ced9a880365682152ba577d348", + "revisionTime": "2016-10-05T04:06:20Z" }, { "checksumSHA1": "cVyhKIRI2gQrgpn5qrBeAqErmWM=", - "origin": "github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini", "path": "github.com/go-ini/ini", "revision": "6e4869b434bd001f6983749881c7ead3545887d8", "revisionTime": "2016-08-27T06:11:18Z" @@ -212,16 +217,16 @@ "revisionTime": "2016-08-02T11:38:42Z" }, { - "checksumSHA1": "sZSeW3Dc6lUqm1CzMUdu3poimoA=", + "checksumSHA1": "qjr2SKQanbmna221z0Ce2n0hnDE=", "path": "github.com/golang/protobuf/proto", - "revision": "1f49d83d9aa00e6ce4fc8258c71cc7786aec968a", - "revisionTime": "2016-08-24T20:12:15Z" + "revision": "df1d3ca07d2d07bba352d5b73c4313b4e2a6203e", + "revisionTime": "2016-09-27T20:09:49Z" }, { - "checksumSHA1": "O2tnQv2UgKyWBMI60nWax8WLxsU=", + "checksumSHA1": "WsQM7/GEq4355WFQ4FMjutGnvNU=", "path": "github.com/google/go-github/github", - "revision": "6d1b527d46849e8fc9238298ebe86dced178609c", - "revisionTime": "2016-09-01T19:22:04Z" + "revision": "3e246d29992beb5a5d2fc253adebea86997c45b0", + "revisionTime": "2016-09-22T19:31:51Z" }, { "checksumSHA1": "yyAzHoiVLu+xywYI2BDyRq6sOqE=", @@ -236,10 +241,10 @@ "revisionTime": "2016-08-17T18:46:32Z" }, { - "checksumSHA1": "WM2EnJ5GBsHmT8W/fgvlZmfbEDw=", + "checksumSHA1": "bjWdAqudYNGaTnoj7Se1pEKqWF8=", "path": "github.com/gorilla/csrf", - "revision": "a8abe8abf66db8f4a9750d76ba95b4021a354757", - "revisionTime": "2016-09-01T05:58:16Z" + "revision": "bbe668740d1d0d07e117e840a4b704e06e719da7", + "revisionTime": "2016-10-02T18:00:12Z" }, { "checksumSHA1": "6/9VW/AyJyjRXLu+nbhqGYvOO2k=", @@ -248,22 +253,22 @@ "revisionTime": "2016-08-16T18:47:29Z" }, { - "checksumSHA1": "oDsOWp1nBMGpQ9gCFnczGADwZTE=", + "checksumSHA1": "urMd7A9QPAJYY0GZJL9qBhlUmD8=", "path": "github.com/gorilla/mux", - "revision": "0a192a193177452756c362c20087ddafcf6829c4", - "revisionTime": "2016-09-02T15:33:43Z" + "revision": "757bef944d0f21880861c2dd9c871ca543023cba", + "revisionTime": "2016-09-20T23:08:13Z" }, { - "checksumSHA1": "nZoAsxDHOA8fLilA56HKvezLqNU=", + "checksumSHA1": "veX5bpYOBjZZWMyWxXxys8EH9d8=", "path": "github.com/gorilla/securecookie", - "revision": "c13558c2b1c44da35e0eb043053609a5ba3a1f19", - "revisionTime": "2016-08-16T22:23:38Z" + "revision": "fa5329f913702981df43dcb2a380bac429c810b5", + "revisionTime": "2016-10-03T05:16:01Z" }, { - "checksumSHA1": "/bme7EZUgPHRcE433mhhCywTY0Y=", + "checksumSHA1": "f1dfF3vmO95G/hbwMYlFru/FfMo=", "path": "github.com/gorilla/sessions", - "revision": "7ab2742f1e374be6675e9a4eca54fe529221ae3a", - "revisionTime": "2016-09-01T06:18:54Z" + "revision": "ca9ada44574153444b00d3fd9c8559e4cc95f896", + "revisionTime": "2016-09-22T14:58:04Z" }, { "checksumSHA1": "cdOCt0Yb+hdErz8NAQqayxPmRsY=", @@ -292,78 +297,77 @@ { "checksumSHA1": "8OPDk+bKyRGJoKcS4QNw9F7dpE8=", "path": "github.com/hashicorp/hcl", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { - "checksumSHA1": "67DfevLBglV52Y2eAuhFc/xQni0=", + "checksumSHA1": "XQmjDva9JCGGkIecOgwtBEMCJhU=", "path": "github.com/hashicorp/hcl/hcl/ast", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { - "checksumSHA1": "l2oQxBsZRwn6eZjf+whXr8c9+8c=", + "checksumSHA1": "un4pN4yL5bl6LL3CgWacFbIeHVg=", "path": "github.com/hashicorp/hcl/hcl/parser", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { "checksumSHA1": "lgR7PSAZ0RtvAc9OCtCnNsF/x8g=", "path": "github.com/hashicorp/hcl/hcl/scanner", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { "checksumSHA1": "JlZmnzqdmFFyb1+2afLyR3BOE/8=", "path": "github.com/hashicorp/hcl/hcl/strconv", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { "checksumSHA1": "c6yprzj06ASwCo18TtbbNNBHljA=", "path": "github.com/hashicorp/hcl/hcl/token", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { - "checksumSHA1": "jQ45CCc1ed/nlV7bbSnx6z72q1M=", + "checksumSHA1": "fpQQdjFUZOoslYuFNKZMSO0N0ik=", "path": "github.com/hashicorp/hcl/json/parser", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { "checksumSHA1": "YdvFsNOMSWMLnY6fcliWQa0O5Fw=", "path": "github.com/hashicorp/hcl/json/scanner", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { "checksumSHA1": "fNlXQCQEnb+B3k5UDL/r15xtSJY=", "path": "github.com/hashicorp/hcl/json/token", - "revision": "ef8133da8cda503718a74741312bf50821e6de79", - "revisionTime": "2016-09-16T13:01:00Z" + "revision": "6f5bfed9a0a22222fbe4e731ae3481730ba41e93", + "revisionTime": "2016-10-08T07:35:57Z" }, { "checksumSHA1": "LaOQaDi4rc0QVgWtzDrQqa7hJgs=", "path": "github.com/hashicorp/vault/api", - "revision": "b2d2bb55d25f8b6ab70f4044c4ddb6bf1050eab6", - "revisionTime": "2016-10-05T21:17:33Z" + "revision": "80281c16fcaab7aa2ad0a67816c0bdc307476a80", + "revisionTime": "2016-10-07T15:06:01Z" }, { "checksumSHA1": "ft77GtqeZEeCXioGpF/s6DlGm/U=", "path": "github.com/hashicorp/vault/helper/compressutil", - "revision": "b2d2bb55d25f8b6ab70f4044c4ddb6bf1050eab6", - "revisionTime": "2016-10-05T21:17:33Z" + "revision": "80281c16fcaab7aa2ad0a67816c0bdc307476a80", + "revisionTime": "2016-10-07T15:06:01Z" }, { "checksumSHA1": "yUiSTPf0QUuL2r/81sjuytqBoeQ=", "path": "github.com/hashicorp/vault/helper/jsonutil", - "revision": "b2d2bb55d25f8b6ab70f4044c4ddb6bf1050eab6", - "revisionTime": "2016-10-05T21:17:33Z" + "revision": "80281c16fcaab7aa2ad0a67816c0bdc307476a80", + "revisionTime": "2016-10-07T15:06:01Z" }, { "checksumSHA1": "0ZrwvB6KoGPj2PoDNSEJwxQ6Mog=", - "origin": "github.com/aws/aws-sdk-go/vendor/github.com/jmespath/go-jmespath", "path": "github.com/jmespath/go-jmespath", "revision": "bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d", "revisionTime": "2016-08-03T19:07:31Z" @@ -377,14 +381,14 @@ { "checksumSHA1": "S6PDDQMYaKwLDIP/NsRYb4FRAqQ=", "path": "github.com/magiconair/properties", - "revision": "61b492c03cf472e0c6419be5899b8e0dc28b1b88", - "revisionTime": "2016-08-16T08:55:11Z" + "revision": "0723e352fa358f9322c938cc2dadda874e9151a9", + "revisionTime": "2016-09-08T09:36:58Z" }, { - "checksumSHA1": "KvUWnb+svMKP6VEKobmj9Y/sI4w=", + "checksumSHA1": "0YgW0+rmiIzLlvhIKlQ0s0olPg8=", "path": "github.com/mattn/go-sqlite3", - "revision": "b5c99a720374818b629fd1fbf6d2cbb4fb9a5644", - "revisionTime": "2016-08-21T07:55:01Z" + "revision": "e5a3c16c5c1d80b24f633e68aecd6b0702786d3d", + "revisionTime": "2016-10-04T16:01:36Z" }, { "checksumSHA1": "AXacfEchaUqT5RGmPmMXsOWRhv8=", @@ -393,10 +397,10 @@ "revisionTime": "2016-06-21T17:42:43Z" }, { - "checksumSHA1": "LUrnGREfnifW4WDMaavmc9MlLI0=", + "checksumSHA1": "HzhmHrGdk67cMJ2xt5ToPxhwLWk=", "path": "github.com/mitchellh/mapstructure", - "revision": "ca63d7c062ee3c9f34db231e352b60012b4fd0c1", - "revisionTime": "2016-08-08T18:12:53Z" + "revision": "a6ef2f080c66d0a2e94e97cf74f80f772855da63", + "revisionTime": "2016-10-06T23:39:02Z" }, { "checksumSHA1": "8Y05Pz7onrQPcVWW6JStSsYRh6E=", @@ -405,10 +409,10 @@ "revisionTime": "2016-01-24T19:35:03Z" }, { - "checksumSHA1": "E/zcLZZ8AqQx+QsiEc2ZF+lSa50=", + "checksumSHA1": "CtI2rBQw2rxHNIU+a0rcAf29Sco=", "path": "github.com/pelletier/go-toml", - "revision": "5a62685873ef617233ab5f1b825a6e4a758e16cf", - "revisionTime": "2016-08-23T07:47:07Z" + "revision": "45932ad32dfdd20826f5671da37a5f3ce9f26a8d", + "revisionTime": "2016-09-20T07:07:15Z" }, { "checksumSHA1": "F6aWtRaqjbiLqtReuNIgl08JqhI=", @@ -417,16 +421,16 @@ "revisionTime": "2016-01-18T05:35:52Z" }, { - "checksumSHA1": "Hky3u+8Rqum+wB5BHMj0A8ZmT4g=", + "checksumSHA1": "ynJSWoF6v+3zMnh9R0QmmG6iGV8=", "path": "github.com/pkg/errors", - "revision": "17b591df37844cde689f4d5813e5cea0927d8dd2", - "revisionTime": "2016-08-22T09:00:10Z" + "revision": "839d9e913e063e28dfd0e6c7b7512793e0a48be9", + "revisionTime": "2016-10-02T05:25:12Z" }, { - "checksumSHA1": "FJIb/zcGEYhYUo33wSzX3T6hwGU=", + "checksumSHA1": "k9SlQdp/DTB72G/u4aNecX/fFIg=", "path": "github.com/pkg/sftp", - "revision": "a71e8f580e3b622ebff585309160b1cc549ef4d2", - "revisionTime": "2016-07-21T23:14:53Z" + "revision": "4d0e916071f68db74f8a73926335f809396d6b42", + "revisionTime": "2016-09-30T22:07:58Z" }, { "checksumSHA1": "LuFv4/jlrmFNnDb/5SCSEPAM9vU=", @@ -455,26 +459,26 @@ { "checksumSHA1": "59wTbS4fE2282Q88NrBYImbFGbo=", "path": "github.com/spf13/afero", - "revision": "20500e2abd0d1f4564a499e83d11d6c73cd58c27", - "revisionTime": "2016-08-21T08:36:12Z" + "revision": "52e4a6cfac46163658bd4f123c49b6ee7dc75f78", + "revisionTime": "2016-09-19T21:01:14Z" }, { - "checksumSHA1": "S29tnboEqKV8/ghlvDzaqtJJD7E=", + "checksumSHA1": "u6B0SEgZ/TUEfIvF6w/HnFVQbII=", "path": "github.com/spf13/afero/mem", - "revision": "20500e2abd0d1f4564a499e83d11d6c73cd58c27", - "revisionTime": "2016-08-21T08:36:12Z" + "revision": "52e4a6cfac46163658bd4f123c49b6ee7dc75f78", + "revisionTime": "2016-09-19T21:01:14Z" }, { "checksumSHA1": "sLyAUiIT7V0DNVp6yBhW4Ms5BEs=", "path": "github.com/spf13/afero/sftp", - "revision": "20500e2abd0d1f4564a499e83d11d6c73cd58c27", - "revisionTime": "2016-08-21T08:36:12Z" + "revision": "52e4a6cfac46163658bd4f123c49b6ee7dc75f78", + "revisionTime": "2016-09-19T21:01:14Z" }, { - "checksumSHA1": "F5PKdeFzODdoAChY/aEiEDaNWtQ=", + "checksumSHA1": "M4qI7Ul0vf2uj3fF69DvRnwqfd0=", "path": "github.com/spf13/cast", - "revision": "e31f36ffc91a2ba9ddb72a4b6a607ff9b3d3cb63", - "revisionTime": "2016-07-30T09:20:37Z" + "revision": "2580bc98dc0e62908119e4737030cc2fdfc45e4c", + "revisionTime": "2016-09-26T08:42:49Z" }, { "checksumSHA1": "dkruahfhuLXXuyeCuRpsWlcRK+8=", @@ -483,22 +487,22 @@ "revisionTime": "2016-03-01T12:00:06Z" }, { - "checksumSHA1": "PmccVBlMZtlxd8WbeGewGq0TyDI=", + "checksumSHA1": "UVxLV6wxC8kPxlhShSfwWchKYJQ=", "path": "github.com/spf13/pflag", - "revision": "103ce5cd2042f2fe629c1957abb64ab3e7f50235", - "revisionTime": "2016-08-20T15:41:56Z" + "revision": "b83537d79690b75cac5e021b036ae16792bf0f20", + "revisionTime": "2016-10-06T16:53:40Z" }, { - "checksumSHA1": "AEhbo+ngM14A/E4LwHOspRTrpJk=", + "checksumSHA1": "mgd16Kh5W/YEw7lEovBxxnoOZ4A=", "path": "github.com/spf13/viper", - "revision": "16990631d4aa7e38f73dbbbf37fa13e67c648531", - "revisionTime": "2016-08-30T14:32:46Z" + "revision": "ec4eb2fa8549869ae7a2accd4fcc83d1c0555c15", + "revisionTime": "2016-10-08T08:00:18Z" }, { - "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", + "checksumSHA1": "Q2V7Zs3diLmLfmfbiuLpSxETSuY=", "path": "github.com/stretchr/testify/assert", - "revision": "d77da356e56a7428ad25149ca77381849a6a5232", - "revisionTime": "2016-06-15T09:26:46Z" + "revision": "976c720a22c8eb4eb6a0b4348ad85ad12491a506", + "revisionTime": "2016-09-25T22:06:09Z" }, { "checksumSHA1": "Mqb+Cn1S2ZN/nOfn8FDaAiXTdhU=", @@ -509,374 +513,356 @@ { "checksumSHA1": "BS9oue0y6JjMzz3spKlMTVmxZxo=", "path": "go4.org/wkfs", - "revision": "afaa0dd6bd8e33e9fb57caef777e8939a519b8ec", - "revisionTime": "2016-08-23T16:58:28Z" + "revision": "399a9d7bfe85437346a5ec4ef0450fc2f1084e61", + "revisionTime": "2016-09-23T17:06:11Z" }, { - "checksumSHA1": "b2rJCXYVgHeaVQmeCIJDsq8ljUo=", + "checksumSHA1": "VcZWSieqrSxETQY2EP97rg4kLAw=", "path": "go4.org/wkfs/gcs", - "revision": "afaa0dd6bd8e33e9fb57caef777e8939a519b8ec", - "revisionTime": "2016-08-23T16:58:28Z" + "revision": "399a9d7bfe85437346a5ec4ef0450fc2f1084e61", + "revisionTime": "2016-09-23T17:06:11Z" }, { "checksumSHA1": "h+pFYiRHBogczS8/F1NoN3Ata44=", "path": "golang.org/x/crypto/curve25519", - "revision": "9e590154d2353f3f5e1b24da7275686040dcf491", - "revisionTime": "2016-09-02T16:03:59Z" + "revision": "d172538b2cfce0c13cee31e647d0367aa8cd2486", + "revisionTime": "2015-06-02T14:54:44Z" }, { "checksumSHA1": "wGb//LjBPNxYHqk+dcLo7BjPXK8=", "path": "golang.org/x/crypto/ed25519", - "revision": "9e590154d2353f3f5e1b24da7275686040dcf491", - "revisionTime": "2016-09-02T16:03:59Z" + "revision": "d172538b2cfce0c13cee31e647d0367aa8cd2486", + "revisionTime": "2015-06-02T14:54:44Z" }, { "checksumSHA1": "LXFcVx8I587SnWmKycSDEq9yvK8=", "path": "golang.org/x/crypto/ed25519/internal/edwards25519", - "revision": "9e590154d2353f3f5e1b24da7275686040dcf491", - "revisionTime": "2016-09-02T16:03:59Z" + "revision": "d172538b2cfce0c13cee31e647d0367aa8cd2486", + "revisionTime": "2015-06-02T14:54:44Z" }, { - "checksumSHA1": "pXOcpeiBjX3zbVKeg0pvYnEmtqU=", + "checksumSHA1": "1LydpuiE3oBdkbYvSdKKwe9lsLs=", "path": "golang.org/x/crypto/ssh", - "revision": "9e590154d2353f3f5e1b24da7275686040dcf491", - "revisionTime": "2016-09-02T16:03:59Z" + "revision": "d172538b2cfce0c13cee31e647d0367aa8cd2486", + "revisionTime": "2015-06-02T14:54:44Z" }, { - "checksumSHA1": "dA/dc+Var3VnLrksziLa0Zli+YI=", + "checksumSHA1": "SJ3Ma3Ozavxpbh1usZWBCnzMKIc=", "path": "golang.org/x/crypto/ssh/agent", - "revision": "9e590154d2353f3f5e1b24da7275686040dcf491", - "revisionTime": "2016-09-02T16:03:59Z" + "revision": "d172538b2cfce0c13cee31e647d0367aa8cd2486", + "revisionTime": "2015-06-02T14:54:44Z" }, { "checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=", "path": "golang.org/x/net/context", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { "checksumSHA1": "WHc3uByvGaMcnSoI21fhzYgbOgg=", "path": "golang.org/x/net/context/ctxhttp", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { - "checksumSHA1": "UL3f1aJMhKAkxTl5kZnkrwyqP+M=", + "checksumSHA1": "TUt1YBoSgtklP3MKWuOJwXBrkRw=", "path": "golang.org/x/net/http2", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { - "checksumSHA1": "EYNaHp7XdLWRydUCE0amEkKAtgk=", + "checksumSHA1": "HzuGD7AwgC0p1az1WAQnEFnEk98=", "path": "golang.org/x/net/http2/hpack", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" + }, + { + "checksumSHA1": "GIGmSrYACByf5JDIP9ByBZksY80=", + "path": "golang.org/x/net/idna", + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { "checksumSHA1": "/k7k6eJDkxXx6K9Zpo/OwNm58XM=", "path": "golang.org/x/net/internal/timeseries", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { - "checksumSHA1": "yhndhWXMs/VSEDLks4dNyFMQStA=", + "checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=", "path": "golang.org/x/net/lex/httplex", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { - "checksumSHA1": "WpST9lFOHvWrjDVy0GJNqHe+R3E=", + "checksumSHA1": "4MMbG0LI3ghvWooRn36RmDrFIB0=", "path": "golang.org/x/net/trace", - "revision": "1358eff22f0dd0c54fc521042cc607f6ff4b531a", - "revisionTime": "2016-09-01T04:28:38Z" + "revision": "f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6", + "revisionTime": "2016-10-05T16:48:53Z" }, { "checksumSHA1": "XH7CgbL5Z8COUc+MKrYqS3FFosY=", "path": "golang.org/x/oauth2", - "revision": "3c3a985cb79f52a3190fbc056984415ca6763d01", - "revisionTime": "2016-08-26T23:14:08Z" + "revision": "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5", + "revisionTime": "2016-10-06T21:47:20Z" }, { "checksumSHA1": "Yokz/Wl4zeuOZG2ev8LuaLtMotE=", "path": "golang.org/x/oauth2/github", - "revision": "3c3a985cb79f52a3190fbc056984415ca6763d01", - "revisionTime": "2016-08-26T23:14:08Z" + "revision": "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5", + "revisionTime": "2016-10-06T21:47:20Z" }, { "checksumSHA1": "92TBjKPPMEcAfNqc2xWF8fSfZMg=", "path": "golang.org/x/oauth2/google", - "revision": "3c3a985cb79f52a3190fbc056984415ca6763d01", - "revisionTime": "2016-08-26T23:14:08Z" + "revision": "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5", + "revisionTime": "2016-10-06T21:47:20Z" }, { "checksumSHA1": "D3v/aqfB9swlaZcSksCoF+lbOqo=", "path": "golang.org/x/oauth2/internal", - "revision": "3c3a985cb79f52a3190fbc056984415ca6763d01", - "revisionTime": "2016-08-26T23:14:08Z" + "revision": "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5", + "revisionTime": "2016-10-06T21:47:20Z" }, { "checksumSHA1": "huVltYnXdRFDJLgp/ZP9IALzG7g=", "path": "golang.org/x/oauth2/jws", - "revision": "3c3a985cb79f52a3190fbc056984415ca6763d01", - "revisionTime": "2016-08-26T23:14:08Z" + "revision": "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5", + "revisionTime": "2016-10-06T21:47:20Z" }, { "checksumSHA1": "McqNj0/805YfYQJQGomeB0s+EcU=", "path": "golang.org/x/oauth2/jwt", - "revision": "3c3a985cb79f52a3190fbc056984415ca6763d01", - "revisionTime": "2016-08-26T23:14:08Z" + "revision": "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5", + "revisionTime": "2016-10-06T21:47:20Z" }, { - "checksumSHA1": "8fD/im5Kwvy3JgmxulDTambmE8w=", + "checksumSHA1": "u4rtURsE9Cn7TK4OPwH8axBMK6M=", "path": "golang.org/x/sys/unix", - "revision": "a646d33e2ee3172a661fc09bca23bb4889a41bc8", - "revisionTime": "2016-07-15T05:43:45Z" + "revision": "8d1157a435470616f975ff9bb013bea8d0962067", + "revisionTime": "2016-10-06T02:47:49Z" }, { - "checksumSHA1": "3JkLagg7UP4890bHn0Uld6GmO6M=", + "checksumSHA1": "ZgBUmCCorTWurKNFm5Vb/U5t0xw=", "path": "golang.org/x/text/internal/gen", - "revision": "ceefd2213ed29504fff30155163c8f59827734f3", - "revisionTime": "2016-08-31T08:18:28Z" + "revision": "ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0", + "revisionTime": "2016-09-29T15:02:56Z" }, { "checksumSHA1": "47nwiUyVBY2RKoEGXmCSvusY4Js=", "path": "golang.org/x/text/internal/triegen", - "revision": "ceefd2213ed29504fff30155163c8f59827734f3", - "revisionTime": "2016-08-31T08:18:28Z" + "revision": "ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0", + "revisionTime": "2016-09-29T15:02:56Z" }, { - "checksumSHA1": "LyT5byg0Dq4x3OcGt6EwIDgPUpc=", + "checksumSHA1": "H/0MDIWRnNYJPmfNCKmWm5aIGcA=", "path": "golang.org/x/text/internal/ucd", - "revision": "ceefd2213ed29504fff30155163c8f59827734f3", - "revisionTime": "2016-08-31T08:18:28Z" + "revision": "ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0", + "revisionTime": "2016-09-29T15:02:56Z" }, { - "checksumSHA1": "TZDHZj3zWDc5LKqpoLamOKt6Nmo=", + "checksumSHA1": "ziMb9+ANGRJSSIuxYdRbA+cDRBQ=", "path": "golang.org/x/text/transform", - "revision": "ceefd2213ed29504fff30155163c8f59827734f3", - "revisionTime": "2016-08-31T08:18:28Z" + "revision": "ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0", + "revisionTime": "2016-09-29T15:02:56Z" }, { "checksumSHA1": "n94g6qdzv0fgQFGelH4/HXOthl0=", "path": "golang.org/x/text/unicode/cldr", - "revision": "ceefd2213ed29504fff30155163c8f59827734f3", - "revisionTime": "2016-08-31T08:18:28Z" + "revision": "ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0", + "revisionTime": "2016-09-29T15:02:56Z" }, { - "checksumSHA1": "pDDMc5yLVQ2xeR9CajcgIJODPcw=", + "checksumSHA1": "Aj3JSVO324FCjEAGm4ZwmC79bbo=", "path": "golang.org/x/text/unicode/norm", - "revision": "ceefd2213ed29504fff30155163c8f59827734f3", - "revisionTime": "2016-08-31T08:18:28Z" + "revision": "ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0", + "revisionTime": "2016-09-29T15:02:56Z" }, { - "checksumSHA1": "awFDzMy1r/KM9mrqgCI9WqkxXc8=", + "checksumSHA1": "TFmTijDJtWhpUwG86ER0n2Xp+/U=", "path": "google.golang.org/api/gensupport", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { "checksumSHA1": "ia5kPSNOC45E23oF6A00m976BHY=", "path": "google.golang.org/api/googleapi", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { "checksumSHA1": "1K0JxrUfDqAB3MyRiU1LKjfHyf4=", "path": "google.golang.org/api/googleapi/internal/uritemplates", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { - "checksumSHA1": "yWFW1Xd2p+UaoIf7RjYnlheQ4CQ=", + "checksumSHA1": "kFHmY+4xvvjiLwhkuFg7ZIaGHmE=", "path": "google.golang.org/api/internal", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { - "checksumSHA1": "BeTdT/OfOx9pWTGG0e2Ybwl4vBg=", + "checksumSHA1": "slcGOTGSdukEPPSN81Q5WZGmhog=", + "path": "google.golang.org/api/iterator", + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" + }, + { + "checksumSHA1": "2veoulDfsbD5iUCMhnXAnPNHDNM=", "path": "google.golang.org/api/oauth2/v2", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { - "checksumSHA1": "Y8OqjpPlGzB4HBKJNndKyHMVWDw=", + "checksumSHA1": "Lc4yBmQAP9J3f8XYa9nH/D0FVhE=", "path": "google.golang.org/api/option", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { - "checksumSHA1": "ruNsGShXZvd73JcT7jT1qaISI7U=", + "checksumSHA1": "q6pXPo7akhYZw2DoZJNfpwjb1q0=", "path": "google.golang.org/api/storage/v1", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { - "checksumSHA1": "ugEt3+6BX701rmptMc3zy6/siq0=", + "checksumSHA1": "Ms24PFj1glBAb69TtGuq9qeqcYA=", "path": "google.golang.org/api/transport", - "revision": "66a8bc6d16488febe10aa767dce67cbf3e7dd21d", - "revisionTime": "2016-09-02T01:27:28Z" + "revision": "3cf64a039723963488f603d140d0aec154fdcd20", + "revisionTime": "2016-10-06T16:45:29Z" }, { - "checksumSHA1": "xduDNbu9zEufcDc8UNWHoLrip5w=", + "checksumSHA1": "OUlby05bSL50Wk1/hbu92mpKmvk=", "path": "google.golang.org/appengine", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { - "checksumSHA1": "4lEP/dEWOMb4r2Aehu0D9iBDgIU=", + "checksumSHA1": "Iq/i8Bsr/xrLXTT14mBcyLYOyrY=", "path": "google.golang.org/appengine/internal", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "x6Thdfyasqd68dWZWqzWWeIfAfI=", "path": "google.golang.org/appengine/internal/app_identity", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "TsNO8P0xUlLNyh3Ic/tzSp/fDWM=", "path": "google.golang.org/appengine/internal/base", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "5QsV5oLGSfKZqTCVXP6NRz5T4Tw=", "path": "google.golang.org/appengine/internal/datastore", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "Gep2T9zmVYV8qZfK2gu3zrmG6QE=", "path": "google.golang.org/appengine/internal/log", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "eLZVX1EHLclFtQnjDIszsdyWRHo=", "path": "google.golang.org/appengine/internal/modules", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "a1XY7rz3BieOVqVI2Et6rKiwQCk=", "path": "google.golang.org/appengine/internal/remote_api", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "VA88sOHmVuIslrbHaWx9yEvjGjM=", "path": "google.golang.org/appengine/internal/socket", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "QtAbHtHmDzcf6vOV9eqlCpKgjiw=", "path": "google.golang.org/appengine/internal/urlfetch", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "MharNMGnQusRPdmBYXDxz2cCHPU=", "path": "google.golang.org/appengine/socket", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { "checksumSHA1": "akOV9pYnCbcPA8wJUutSQVibdyg=", "path": "google.golang.org/appengine/urlfetch", - "revision": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05", - "revisionTime": "2016-08-19T23:33:10Z" - }, - { - "checksumSHA1": "lk+T/So1q5LmhqkyGjU3XhqR9zA=", - "path": "google.golang.org/cloud", - "revision": "12aa462581208c155e498dc13e14cabe6da24dc3", - "revisionTime": "2016-08-12T18:01:26Z" - }, - { - "checksumSHA1": "ve1xDNHaFXbKONJO7w312dCks+0=", - "path": "google.golang.org/cloud/compute/metadata", - "revision": "12aa462581208c155e498dc13e14cabe6da24dc3", - "revisionTime": "2016-08-12T18:01:26Z" - }, - { - "checksumSHA1": "U7dGDNwEHORvJFMoNSXErKE7ITg=", - "path": "google.golang.org/cloud/internal", - "revision": "12aa462581208c155e498dc13e14cabe6da24dc3", - "revisionTime": "2016-08-12T18:01:26Z" - }, - { - "checksumSHA1": "J9l4e+4WlvHLG3omP+xoxouwsKg=", - "path": "google.golang.org/cloud/internal/transport", - "revision": "12aa462581208c155e498dc13e14cabe6da24dc3", - "revisionTime": "2016-08-12T18:01:26Z" - }, - { - "checksumSHA1": "sMRh7U8exmiH2FeTxNVzMTiEhLs=", - "path": "google.golang.org/cloud/storage", - "revision": "12aa462581208c155e498dc13e14cabe6da24dc3", - "revisionTime": "2016-08-12T18:01:26Z" + "revision": "3f4dbbc0ec153a39878fd524ece9f39732bd4998", + "revisionTime": "2016-10-06T20:09:41Z" }, { - "checksumSHA1": "wMObd1dd4H5hoyd3Qz272deSWZ8=", + "checksumSHA1": "N0GmUbip6LljIQkixSZnQ7a76Fs=", "path": "google.golang.org/grpc", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "08icuA15HRkdYCt6H+Cs90RPQsY=", "path": "google.golang.org/grpc/codes", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { - "checksumSHA1": "sbiWvqfhNKqrDC/nv0W/FaO3EOA=", + "checksumSHA1": "Vd1MU+Ojs7GeS6jE52vlxtXvIrI=", "path": "google.golang.org/grpc/credentials", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "5R1jXc9mAXky9tPEuWMikTrwCgE=", "path": "google.golang.org/grpc/credentials/oauth", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "3Lt5hNAG8qJAYSsNghR5uA1zQns=", "path": "google.golang.org/grpc/grpclog", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "T3Q0p8kzvXFnRkMaK/G8mCv6mc0=", "path": "google.golang.org/grpc/internal", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { - "checksumSHA1": "rxtneb9jDjKPHNZhC5obfG++6bI=", + "checksumSHA1": "P64GkSdsTZ8Nxop5HYqZJ6e+iHs=", "path": "google.golang.org/grpc/metadata", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "4GSUFhOQ0kdFlBH4D5OTeKy78z0=", "path": "google.golang.org/grpc/naming", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "3RRoLeH6X2//7tVClOVzxW2bY+E=", "path": "google.golang.org/grpc/peer", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { - "checksumSHA1": "BOExBhs6EELb6rFF3qFEhiemN2c=", + "checksumSHA1": "dzbx9oVtSfVgNE3lTl+r5xOXxcw=", "path": "google.golang.org/grpc/transport", - "revision": "52f6504dc290bd928a8139ba94e3ab32ed9a6273", - "revisionTime": "2016-09-02T22:12:15Z" + "revision": "2131fedea9b3fe419b5c06200a674cdbc7bf986d", + "revisionTime": "2016-10-08T00:11:57Z" }, { "checksumSHA1": "1D8GzeoFGUs5FZOoyC2DpQg8c5Y=", @@ -909,10 +895,10 @@ "revisionTime": "2016-08-18T02:01:20Z" }, { - "checksumSHA1": "yV+2de12Q/t09hBGYGKEOFr1/zc=", + "checksumSHA1": "12GqsW8PiRPnezDDy0v4brZrndM=", "path": "gopkg.in/yaml.v2", - "revision": "e4d366fc3c7938e2958e662b4258c7a89e1f0e3e", - "revisionTime": "2016-07-15T03:37:55Z" + "revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0", + "revisionTime": "2016-09-28T15:37:09Z" } ], "rootPath": "github.com/nsheridan/cashier" -- cgit v1.2.3