From 487e05d25cd81c6112de5ecba6e3b05ff9f88955 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 2 Sep 2016 18:05:09 -0400 Subject: [PATCH] Update deps --- vendor/camlistore.org/COPYING | 202 -- vendor/camlistore.org/pkg/netutil/ident.go | 262 --- .../camlistore.org/pkg/netutil/ident_cgo.go | 39 - .../camlistore.org/pkg/netutil/ident_nocgo.go | 32 - vendor/camlistore.org/pkg/netutil/netutil.go | 165 -- .../Azure/azure-sdk-for-go/storage/README.md | 5 + .../Azure/azure-sdk-for-go/storage/blob.go | 59 +- .../Azure/azure-sdk-for-go/storage/client.go | 61 +- .../Azure/azure-sdk-for-go/storage/file.go | 15 + .../storage/table_entities.go | 4 + .../Azure/azure-sdk-for-go/storage/util.go | 14 + .../aws/aws-sdk-go/aws/awserr/error.go | 4 +- .../aws/aws-sdk-go/aws/awserr/types.go | 2 +- .../aws/aws-sdk-go/aws/awsutil/copy.go | 10 +- .../aws/aws-sdk-go/aws/client/client.go | 23 +- .../github.com/aws/aws-sdk-go/aws/config.go | 129 +- .../aws/credentials/static_provider.go | 11 +- .../stscreds/assume_role_provider.go | 161 ++ .../aws/aws-sdk-go/aws/defaults/defaults.go | 8 +- .../aws/aws-sdk-go/aws/session/doc.go | 223 +++ .../aws/aws-sdk-go/aws/session/env_config.go | 188 ++ .../aws/aws-sdk-go/aws/session/session.go | 344 +++- .../aws-sdk-go/aws/session/shared_config.go | 294 +++ .../aws/aws-sdk-go/aws/signer/v4/v4.go | 2 +- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws-sdk-go/private/endpoints/endpoints.go | 19 +- .../private/endpoints/endpoints.json | 3 + .../private/endpoints/endpoints_map.go | 3 + .../private/protocol/ec2query/build.go | 2 +- .../private/protocol/json/jsonutil/build.go | 4 +- .../private/protocol/jsonrpc/jsonrpc.go | 2 +- .../private/protocol/query/build.go | 2 +- .../private/protocol/restxml/restxml.go | 2 +- .../private/protocol/xml/xmlutil/build.go | 2 +- .../service/dynamodb/dynamodbattribute/doc.go | 7 +- .../dynamodb/dynamodbattribute/encode.go | 2 +- .../aws/aws-sdk-go/service/ec2/api.go | 948 ++++++++-- .../aws-sdk-go/service/ec2/customizations.go | 6 +- .../aws/aws-sdk-go/service/iam/api.go | 12 +- .../aws/aws-sdk-go/service/s3/api.go | 2 +- .../service/s3/host_style_bucket.go | 8 + .../aws-sdk-go/service/s3/unmarshal_error.go | 2 +- .../aws/aws-sdk-go/service/sts/api.go | 58 +- .../bgentry/speakeasy/speakeasy_unix.go | 2 +- .../circonus-labs/circonus-gometrics/LICENSE | 28 + .../circonus-gometrics/README.md | 4 +- .../circonus-gometrics/api/api.go | 53 +- .../circonus-gometrics/api/broker.go | 4 + .../circonus-gometrics/api/check.go | 4 + .../circonus-gometrics/api/checkbundle.go | 4 + .../circonus-gometrics/checkmgr/broker.go | 4 + .../circonus-gometrics/checkmgr/cert.go | 4 + .../circonus-gometrics/checkmgr/check.go | 4 + .../circonus-gometrics/checkmgr/checkmgr.go | 4 + .../circonus-gometrics/checkmgr/metrics.go | 4 + .../circonus-gometrics/circonus-gometrics.go | 4 + .../circonus-gometrics/counter.go | 4 + .../circonus-labs/circonus-gometrics/gauge.go | 4 + .../circonus-gometrics/histogram.go | 4 + .../circonus-gometrics/submit.go | 4 + .../circonus-labs/circonus-gometrics/text.go | 4 + .../circonus-labs/circonus-gometrics/tools.go | 4 + .../circonus-labs/circonus-gometrics/util.go | 4 + .../coreos/etcd/client/keys.generated.go | 3 +- vendor/github.com/coreos/etcd/client/keys.go | 27 +- vendor/github.com/coreos/etcd/client/util.go | 30 + .../coreos/etcd/pkg/fileutil/fileutil.go | 23 + .../coreos/etcd/pkg/transport/listener.go | 8 +- .../etcd/pkg/transport/timeout_transport.go | 2 +- .../coreos/etcd/pkg/transport/tls.go | 49 + .../coreos/etcd/pkg/transport/transport.go | 5 +- vendor/github.com/fatih/structs/structs.go | 5 +- vendor/github.com/go-ini/ini/README.md | 48 +- vendor/github.com/go-ini/ini/README_ZH.md | 48 +- vendor/github.com/go-ini/ini/error.go | 32 + vendor/github.com/go-ini/ini/ini.go | 12 +- vendor/github.com/go-ini/ini/key.go | 18 +- vendor/github.com/go-ini/ini/parser.go | 17 +- vendor/github.com/go-ini/ini/section.go | 6 +- vendor/github.com/go-ini/ini/struct.go | 42 +- vendor/github.com/go-ldap/ldap/control.go | 64 +- .../github.com/go-sql-driver/mysql/packets.go | 19 +- vendor/github.com/gocql/gocql/AUTHORS | 5 + vendor/github.com/gocql/gocql/README.md | 1 + vendor/github.com/gocql/gocql/cluster.go | 14 +- vendor/github.com/gocql/gocql/frame.go | 16 + vendor/github.com/gocql/gocql/helpers.go | 2 +- vendor/github.com/gocql/gocql/host_source.go | 18 +- vendor/github.com/gocql/gocql/marshal.go | 6 + vendor/github.com/gocql/gocql/policies.go | 26 +- .../github.com/gocql/gocql/query_executor.go | 2 +- vendor/github.com/gocql/gocql/session.go | 57 +- .../github.com/golang/protobuf/proto/equal.go | 8 +- .../golang/protobuf/proto/extensions.go | 3 + .../github.com/golang/protobuf/proto/lib.go | 2 +- .../golang/protobuf/proto/properties.go | 10 +- .../golang/protobuf/proto/text_parser.go | 17 +- .../google/go-github/github/authorizations.go | 4 +- .../github.com/google/go-github/github/doc.go | 4 +- .../google/go-github/github/event_types.go | 5 +- .../google/go-github/github/gists.go | 1 + .../google/go-github/github/github.go | 7 +- .../github/migrations_source_import.go | 2 +- .../google/go-github/github/orgs.go | 3 + .../google/go-github/github/pulls.go | 3 +- .../google/go-github/github/repos.go | 2 + .../google/go-github/github/repos_traffic.go | 173 ++ .../google/go-github/github/search.go | 24 +- .../github.com/hashicorp/consul/api/agent.go | 11 +- vendor/github.com/hashicorp/consul/api/api.go | 12 + .../hashicorp/consul/api/catalog.go | 17 +- .../github.com/hashicorp/consul/api/health.go | 2 - .../hashicorp/consul/api/operator.go | 81 + .../hashicorp/go-multierror/Makefile | 31 + .../hashicorp/go-multierror/README.md | 6 + .../hashicorp/go-retryablehttp/client.go | 82 +- vendor/github.com/hashicorp/go-syslog/unix.go | 2 +- .../hashicorp/go-syslog/unsupported.go | 2 +- .../hashicorp/golang-lru/simplelru/lru.go | 2 +- vendor/github.com/hashicorp/hcl/README.md | 10 + vendor/github.com/hashicorp/hcl/decoder.go | 2 +- .../github.com/hashicorp/hcl/hcl/ast/ast.go | 3 +- .../hashicorp/hcl/hcl/scanner/scanner.go | 5 + .../hashicorp/hcl/json/scanner/scanner.go | 2 +- vendor/github.com/hashicorp/logutils/LICENSE | 354 ---- .../github.com/hashicorp/logutils/README.md | 36 - vendor/github.com/hashicorp/logutils/level.go | 81 - .../go-crypto/openpgp/packet/public_key.go | 17 +- vendor/github.com/lib/pq/array.go | 727 +++++++ vendor/github.com/lib/pq/encode.go | 16 +- .../github.com/mattn/go-isatty/isatty_bsd.go | 2 +- vendor/github.com/mitchellh/cli/cli.go | 17 +- .../mitchellh/copystructure/copystructure.go | 151 +- vendor/github.com/ory-am/dockertest/README.md | 68 +- .../github.com/ory-am/dockertest/container.go | 29 +- vendor/github.com/ory-am/dockertest/docker.go | 20 +- .../github.com/ory-am/dockertest/glide.lock | 114 ++ .../github.com/ory-am/dockertest/glide.yaml | 39 + .../ory-am/dockertest/mockserver.go | 8 +- vendor/github.com/ory-am/dockertest/vars.go | 5 +- vendor/github.com/pborman/uuid/dce.go | 0 vendor/github.com/pborman/uuid/doc.go | 0 vendor/github.com/pborman/uuid/node.go | 0 vendor/github.com/pborman/uuid/time.go | 0 vendor/github.com/pborman/uuid/uuid.go | 2 +- .../github.com/samuel/go-zookeeper/zk/conn.go | 240 ++- .../samuel/go-zookeeper/zk/constants.go | 56 +- .../github.com/samuel/go-zookeeper/zk/lock.go | 10 +- .../samuel/go-zookeeper/zk/server_help.go | 62 +- .../samuel/go-zookeeper/zk/structs.go | 11 +- vendor/github.com/ugorji/go/codec/0doc.go | 2 +- vendor/github.com/ugorji/go/codec/encode.go | 14 +- vendor/github.com/ugorji/go/codec/gen.go | 16 + vendor/github.com/ugorji/go/codec/gen_17.go | 10 + vendor/github.com/ugorji/go/codec/helper.go | 40 +- .../ugorji/go/codec/helper_internal.go | 4 +- vendor/github.com/ugorji/go/codec/simple.go | 2 +- vendor/golang.org/x/crypto/ssh/connection.go | 1 - vendor/golang.org/x/crypto/ssh/server.go | 1 - vendor/golang.org/x/net/http2/go17_not18.go | 36 + vendor/golang.org/x/net/http2/go18.go | 11 + vendor/golang.org/x/net/http2/http2.go | 10 + vendor/golang.org/x/net/http2/not_go17.go | 26 + vendor/golang.org/x/net/http2/transport.go | 49 +- vendor/golang.org/x/oauth2/README.md | 1 + vendor/golang.org/x/oauth2/oauth2.go | 4 + .../appengine/internal/internal.go | 34 - .../appengine/internal/main.go | 15 + .../appengine/internal/main_vm.go | 44 + vendor/google.golang.org/grpc/README.md | 2 +- vendor/google.golang.org/grpc/call.go | 2 +- vendor/google.golang.org/grpc/clientconn.go | 34 +- .../grpc/credentials/credentials.go | 7 + vendor/google.golang.org/grpc/rpc_util.go | 4 +- vendor/google.golang.org/grpc/server.go | 13 +- vendor/google.golang.org/grpc/stream.go | 20 +- .../grpc/transport/handler_server.go | 4 +- .../grpc/transport/http2_client.go | 73 +- .../grpc/transport/http2_server.go | 12 +- .../grpc/transport/http_util.go | 8 +- .../grpc/transport/transport.go | 16 +- vendor/gopkg.in/mgo.v2/Makefile | 4 +- vendor/gopkg.in/mgo.v2/bson/bson.go | 23 +- vendor/gopkg.in/mgo.v2/bson/decimal.go | 310 +++ vendor/gopkg.in/mgo.v2/bson/decode.go | 5 + vendor/gopkg.in/mgo.v2/bson/encode.go | 71 +- vendor/gopkg.in/mgo.v2/bson/json.go | 380 ++++ vendor/gopkg.in/mgo.v2/cluster.go | 5 +- vendor/gopkg.in/mgo.v2/gridfs.go | 2 +- vendor/gopkg.in/mgo.v2/internal/json/LICENSE | 27 + .../gopkg.in/mgo.v2/internal/json/decode.go | 1685 +++++++++++++++++ .../gopkg.in/mgo.v2/internal/json/encode.go | 1256 ++++++++++++ .../mgo.v2/internal/json/extension.go | 95 + vendor/gopkg.in/mgo.v2/internal/json/fold.go | 143 ++ .../gopkg.in/mgo.v2/internal/json/indent.go | 141 ++ .../gopkg.in/mgo.v2/internal/json/scanner.go | 697 +++++++ .../gopkg.in/mgo.v2/internal/json/stream.go | 510 +++++ vendor/gopkg.in/mgo.v2/internal/json/tags.go | 44 + .../mgo.v2/internal/sasl/sasl_windows.c | 20 +- .../mgo.v2/internal/sasl/sasl_windows.go | 12 +- .../mgo.v2/internal/sasl/sasl_windows.h | 2 +- vendor/gopkg.in/mgo.v2/server.go | 11 + vendor/gopkg.in/mgo.v2/session.go | 137 +- vendor/vendor.json | 670 +++---- 204 files changed, 11131 insertions(+), 2336 deletions(-) delete mode 100644 vendor/camlistore.org/COPYING delete mode 100644 vendor/camlistore.org/pkg/netutil/ident.go delete mode 100644 vendor/camlistore.org/pkg/netutil/ident_cgo.go delete mode 100644 vendor/camlistore.org/pkg/netutil/ident_nocgo.go delete mode 100644 vendor/camlistore.org/pkg/netutil/netutil.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/README.md create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go create mode 100644 vendor/github.com/circonus-labs/circonus-gometrics/LICENSE create mode 100644 vendor/github.com/coreos/etcd/pkg/transport/tls.go create mode 100644 vendor/github.com/go-ini/ini/error.go create mode 100644 vendor/github.com/google/go-github/github/repos_traffic.go create mode 100644 vendor/github.com/hashicorp/consul/api/operator.go create mode 100644 vendor/github.com/hashicorp/go-multierror/Makefile delete mode 100644 vendor/github.com/hashicorp/logutils/LICENSE delete mode 100644 vendor/github.com/hashicorp/logutils/README.md delete mode 100644 vendor/github.com/hashicorp/logutils/level.go create mode 100644 vendor/github.com/lib/pq/array.go create mode 100644 vendor/github.com/ory-am/dockertest/glide.lock create mode 100644 vendor/github.com/ory-am/dockertest/glide.yaml mode change 100755 => 100644 vendor/github.com/pborman/uuid/dce.go mode change 100755 => 100644 vendor/github.com/pborman/uuid/doc.go mode change 100755 => 100644 vendor/github.com/pborman/uuid/node.go mode change 100755 => 100644 vendor/github.com/pborman/uuid/time.go create mode 100644 vendor/github.com/ugorji/go/codec/gen_17.go create mode 100644 vendor/golang.org/x/net/http2/go17_not18.go create mode 100644 vendor/golang.org/x/net/http2/go18.go create mode 100644 vendor/google.golang.org/appengine/internal/main.go create mode 100644 vendor/google.golang.org/appengine/internal/main_vm.go create mode 100644 vendor/gopkg.in/mgo.v2/bson/decimal.go create mode 100644 vendor/gopkg.in/mgo.v2/bson/json.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/LICENSE create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/decode.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/encode.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/extension.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/fold.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/indent.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/scanner.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/stream.go create mode 100644 vendor/gopkg.in/mgo.v2/internal/json/tags.go diff --git a/vendor/camlistore.org/COPYING b/vendor/camlistore.org/COPYING deleted file mode 100644 index d64569567..000000000 --- a/vendor/camlistore.org/COPYING +++ /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 [yyyy] [name of copyright owner] - - 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/camlistore.org/pkg/netutil/ident.go b/vendor/camlistore.org/pkg/netutil/ident.go deleted file mode 100644 index 711e6fbcb..000000000 --- a/vendor/camlistore.org/pkg/netutil/ident.go +++ /dev/null @@ -1,262 +0,0 @@ -/* -Copyright 2011 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. -*/ - -// Package netutil identifies the system userid responsible for -// localhost TCP connections. -package netutil // import "camlistore.org/pkg/netutil" - -import ( - "bufio" - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "net" - "os" - "os/exec" - "regexp" - "runtime" - "strconv" - "strings" -) - -var ( - ErrNotFound = errors.New("netutil: connection not found") - ErrUnsupportedOS = errors.New("netutil: not implemented on this operating system") -) - -// ConnUserid returns the uid that owns the given localhost connection. -// The returned error is ErrNotFound if the connection wasn't found. -func ConnUserid(conn net.Conn) (uid int, err error) { - return AddrPairUserid(conn.LocalAddr(), conn.RemoteAddr()) -} - -// HostPortToIP parses a host:port to a TCPAddr without resolving names. -// If given a context IP, it will resolve localhost to match the context's IP family. -func HostPortToIP(hostport string, ctx *net.TCPAddr) (hostaddr *net.TCPAddr, err error) { - host, port, err := net.SplitHostPort(hostport) - if err != nil { - return nil, err - } - iport, err := strconv.Atoi(port) - if err != nil || iport < 0 || iport > 0xFFFF { - return nil, fmt.Errorf("invalid port %d", iport) - } - var addr net.IP - if ctx != nil && host == "localhost" { - if ctx.IP.To4() != nil { - addr = net.IPv4(127, 0, 0, 1) - } else { - addr = net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} - } - } else if addr = net.ParseIP(host); addr == nil { - return nil, fmt.Errorf("could not parse IP %s", host) - } - - return &net.TCPAddr{IP: addr, Port: iport}, nil -} - -// AddrPairUserid returns the local userid who owns the TCP connection -// given by the local and remote ip:port (lipport and ripport, -// respectively). Returns ErrNotFound for the error if the TCP connection -// isn't found. -func AddrPairUserid(local, remote net.Addr) (uid int, err error) { - lAddr, lOk := local.(*net.TCPAddr) - rAddr, rOk := remote.(*net.TCPAddr) - if !(lOk && rOk) { - return -1, fmt.Errorf("netutil: Could not convert Addr to TCPAddr.") - } - - localv4 := (lAddr.IP.To4() != nil) - remotev4 := (rAddr.IP.To4() != nil) - if localv4 != remotev4 { - return -1, fmt.Errorf("netutil: address pairs of different families; localv4=%v, remotev4=%v", - localv4, remotev4) - } - - switch runtime.GOOS { - case "darwin": - return uidFromLsof(lAddr.IP, lAddr.Port, rAddr.IP, rAddr.Port) - case "freebsd": - return uidFromSockstat(lAddr.IP, lAddr.Port, rAddr.IP, rAddr.Port) - case "linux": - file := "/proc/net/tcp" - if !localv4 { - file = "/proc/net/tcp6" - } - f, err := os.Open(file) - if err != nil { - return -1, fmt.Errorf("Error opening %s: %v", file, err) - } - defer f.Close() - return uidFromProcReader(lAddr.IP, lAddr.Port, rAddr.IP, rAddr.Port, f) - } - return 0, ErrUnsupportedOS -} - -func toLinuxIPv4Order(b []byte) []byte { - binary.BigEndian.PutUint32(b, binary.LittleEndian.Uint32(b)) - return b -} - -func toLinuxIPv6Order(b []byte) []byte { - for i := 0; i < 16; i += 4 { - sb := b[i : i+4] - binary.BigEndian.PutUint32(sb, binary.LittleEndian.Uint32(sb)) - } - return b -} - -type maybeBrackets net.IP - -func (p maybeBrackets) String() string { - s := net.IP(p).String() - if strings.Contains(s, ":") { - return "[" + s + "]" - } - return s -} - -// Changed by tests. -var uidFromUsername = uidFromUsernameFn - -func uidFromLsof(lip net.IP, lport int, rip net.IP, rport int) (uid int, err error) { - seek := fmt.Sprintf("%s:%d->%s:%d", maybeBrackets(lip), lport, maybeBrackets(rip), rport) - seekb := []byte(seek) - if _, err = exec.LookPath("lsof"); err != nil { - return - } - cmd := exec.Command("lsof", - "-b", // avoid system calls that could block - "-w", // and don't warn about cases where -b fails - "-n", // don't resolve network names - "-P", // don't resolve network ports, - // TODO(bradfitz): pass down the uid we care about, then do: ? - //"-a", // AND the following together: - // "-u", strconv.Itoa(uid) // just this uid - "-itcp") // we only care about TCP connections - stdout, err := cmd.StdoutPipe() - if err != nil { - return - } - defer cmd.Wait() - defer stdout.Close() - err = cmd.Start() - if err != nil { - return - } - defer cmd.Process.Kill() - br := bufio.NewReader(stdout) - for { - line, err := br.ReadSlice('\n') - if err == io.EOF { - break - } - if err != nil { - return -1, err - } - if !bytes.Contains(line, seekb) { - continue - } - // SystemUIS 276 bradfitz 15u IPv4 0xffffff801a7c74e0 0t0 TCP 127.0.0.1:56718->127.0.0.1:5204 (ESTABLISHED) - f := bytes.Fields(line) - if len(f) < 8 { - continue - } - username := string(f[2]) - return uidFromUsername(username) - } - return -1, ErrNotFound - -} - -func uidFromSockstat(lip net.IP, lport int, rip net.IP, rport int) (int, error) { - cmd := exec.Command("sockstat", "-Ptcp") - stdout, err := cmd.StdoutPipe() - if err != nil { - return -1, err - } - defer cmd.Wait() - defer stdout.Close() - err = cmd.Start() - if err != nil { - return -1, err - } - defer cmd.Process.Kill() - - return uidFromSockstatReader(lip, lport, rip, rport, stdout) -} - -func uidFromSockstatReader(lip net.IP, lport int, rip net.IP, rport int, r io.Reader) (int, error) { - pat, err := regexp.Compile(fmt.Sprintf(`^([^ ]+).*%s:%d *%s:%d$`, - lip.String(), lport, rip.String(), rport)) - if err != nil { - return -1, err - } - scanner := bufio.NewScanner(r) - for scanner.Scan() { - l := scanner.Text() - m := pat.FindStringSubmatch(l) - if len(m) == 2 { - return uidFromUsername(m[1]) - } - } - - if err := scanner.Err(); err != nil { - return -1, err - } - - return -1, ErrNotFound -} - -func uidFromProcReader(lip net.IP, lport int, rip net.IP, rport int, r io.Reader) (uid int, err error) { - buf := bufio.NewReader(r) - - localHex := "" - remoteHex := "" - ipv4 := lip.To4() != nil - if ipv4 { - // In the kernel, the port is run through ntohs(), and - // the inet_request_socket in - // include/net/inet_socket.h says the "loc_addr" and - // "rmt_addr" fields are __be32, but get_openreq4's - // printf of them is raw, without byte order - // converstion. - localHex = fmt.Sprintf("%08X:%04X", toLinuxIPv4Order([]byte(lip.To4())), lport) - remoteHex = fmt.Sprintf("%08X:%04X", toLinuxIPv4Order([]byte(rip.To4())), rport) - } else { - localHex = fmt.Sprintf("%032X:%04X", toLinuxIPv6Order([]byte(lip.To16())), lport) - remoteHex = fmt.Sprintf("%032X:%04X", toLinuxIPv6Order([]byte(rip.To16())), rport) - } - - for { - line, err := buf.ReadString('\n') - if err != nil { - return -1, ErrNotFound - } - parts := strings.Fields(strings.TrimSpace(line)) - if len(parts) < 8 { - continue - } - // log.Printf("parts[1] = %q; localHex = %q", parts[1], localHex) - if parts[1] == localHex && parts[2] == remoteHex { - uid, err = strconv.Atoi(parts[7]) - return uid, err - } - } - panic("unreachable") -} diff --git a/vendor/camlistore.org/pkg/netutil/ident_cgo.go b/vendor/camlistore.org/pkg/netutil/ident_cgo.go deleted file mode 100644 index 039471fb6..000000000 --- a/vendor/camlistore.org/pkg/netutil/ident_cgo.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build !nocgo - -/* -Copyright 2016 The Camlistore Authors. - -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 netutil identifies the system userid responsible for -// localhost TCP connections. -package netutil // import "camlistore.org/pkg/netutil" - -import ( - "os" - "os/user" - "strconv" -) - -func uidFromUsernameFn(username string) (uid int, err error) { - if uid := os.Getuid(); uid != 0 && username == os.Getenv("USER") { - return uid, nil - } - u, err := user.Lookup(username) - if err == nil { - uid, err := strconv.Atoi(u.Uid) - return uid, err - } - return 0, err -} diff --git a/vendor/camlistore.org/pkg/netutil/ident_nocgo.go b/vendor/camlistore.org/pkg/netutil/ident_nocgo.go deleted file mode 100644 index df2e4da9e..000000000 --- a/vendor/camlistore.org/pkg/netutil/ident_nocgo.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build nocgo - -/* -Copyright 2016 The Camlistore Authors. - -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 netutil identifies the system userid responsible for -// localhost TCP connections. -package netutil // import "camlistore.org/pkg/netutil" - -import ( - "os" -) - -func uidFromUsernameFn(username string) (uid int, err error) { - if uid := os.Getuid(); uid != 0 && username == os.Getenv("USER") { - return uid, nil - } - return 0, err -} diff --git a/vendor/camlistore.org/pkg/netutil/netutil.go b/vendor/camlistore.org/pkg/netutil/netutil.go deleted file mode 100644 index e06a40eef..000000000 --- a/vendor/camlistore.org/pkg/netutil/netutil.go +++ /dev/null @@ -1,165 +0,0 @@ -/* -Copyright 2014 The Camlistore Authors - -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 netutil - -import ( - "errors" - "fmt" - "net" - "net/url" - "strings" - "time" -) - -// AwaitReachable tries to make a TCP connection to addr regularly. -// It returns an error if it's unable to make a connection before maxWait. -func AwaitReachable(addr string, maxWait time.Duration) error { - done := time.Now().Add(maxWait) - for time.Now().Before(done) { - c, err := net.Dial("tcp", addr) - if err == nil { - c.Close() - return nil - } - time.Sleep(100 * time.Millisecond) - } - return fmt.Errorf("%v unreachable for %v", addr, maxWait) -} - -// HostPort takes a urlStr string URL, and returns a host:port string suitable -// to passing to net.Dial, with the port set as the scheme's default port if -// absent. -func HostPort(urlStr string) (string, error) { - // TODO: rename this function to URLHostPort instead, like - // ListenHostPort below. - u, err := url.Parse(urlStr) - if err != nil { - return "", fmt.Errorf("could not parse %q as a url: %v", urlStr, err) - } - if u.Scheme == "" { - return "", fmt.Errorf("url %q has no scheme", urlStr) - } - hostPort := u.Host - if hostPort == "" || strings.HasPrefix(hostPort, ":") { - return "", fmt.Errorf("url %q has no host", urlStr) - } - idx := strings.Index(hostPort, "]") - if idx == -1 { - idx = 0 - } - if !strings.Contains(hostPort[idx:], ":") { - if u.Scheme == "https" { - hostPort += ":443" - } else { - hostPort += ":80" - } - } - return hostPort, nil -} - -// ListenHostPort maps a listen address into a host:port string. -// If the host part in listenAddr is empty or 0.0.0.0, localhost -// is used instead. -func ListenHostPort(listenAddr string) (string, error) { - hp := listenAddr - if strings.HasPrefix(hp, ":") { - hp = "localhost" + hp - } else if strings.HasPrefix(hp, "0.0.0.0:") { - hp = "localhost:" + hp[len("0.0.0.0:"):] - } - if _, _, err := net.SplitHostPort(hp); err != nil { - return "", err - } - return hp, nil -} - -// ListenOnLocalRandomPort returns a TCP listener on a random -// localhost port. -func ListenOnLocalRandomPort() (net.Listener, error) { - ip, err := Localhost() - if err != nil { - return nil, err - } - return net.ListenTCP("tcp", &net.TCPAddr{IP: ip, Port: 0}) -} - -// Localhost returns the first address found when -// doing a lookup of "localhost". If not successful, -// it looks for an ip on the loopback interfaces. -func Localhost() (net.IP, error) { - if ip := localhostLookup(); ip != nil { - return ip, nil - } - if ip := loopbackIP(); ip != nil { - return ip, nil - } - return nil, errors.New("No loopback ip found.") -} - -// localhostLookup looks for a loopback IP by resolving localhost. -func localhostLookup() net.IP { - if ips, err := net.LookupIP("localhost"); err == nil && len(ips) > 0 { - return ips[0] - } - return nil -} - -// loopbackIP returns the first loopback IP address sniffing network -// interfaces or nil if none is found. -func loopbackIP() net.IP { - interfaces, err := net.Interfaces() - if err != nil { - return nil - } - for _, inf := range interfaces { - const flagUpLoopback = net.FlagUp | net.FlagLoopback - if inf.Flags&flagUpLoopback == flagUpLoopback { - addrs, _ := inf.Addrs() - for _, addr := range addrs { - ip, _, err := net.ParseCIDR(addr.String()) - if err == nil && ip.IsLoopback() { - return ip - } - } - } - } - return nil -} - -// RandPort returns a random port to listen on. -func RandPort() (int, error) { - var port int - addr, err := net.ResolveTCPAddr("tcp", "localhost:0") - if err != nil { - return port, err - } - listener, err := net.ListenTCP("tcp", addr) - if err != nil { - return port, fmt.Errorf("could not listen to find random port: %v", err) - } - randAddr := listener.Addr().(*net.TCPAddr) - if err := listener.Close(); err != nil { - return port, fmt.Errorf("could not close random listener: %v", err) - } - return randAddr.Port, nil -} - -// HasPort, given a string of the form "host", "host:port", or -// "[ipv6::address]:port", returns true if the string includes a port. -func HasPort(s string) bool { - return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md new file mode 100644 index 000000000..0ab099848 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md @@ -0,0 +1,5 @@ +# Azure Storage SDK for Go + +The `github.com/Azure/azure-sdk-for-go/storage` package is used to perform operations in Azure Storage Service. To manage your storage accounts (Azure Resource Manager / ARM), use the [github.com/Azure/azure-sdk-for-go/arm/storage](../arm/storage) package. For your classic storage accounts (Azure Service Management / ASM), use [github.com/Azure/azure-sdk-for-go/management/storageservice](../management/storageservice) package. + +This package includes support for [Azure Storage Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/) \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go index 8b2b6f69f..4207cfec6 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go @@ -111,6 +111,8 @@ type BlobProperties struct { ContentLength int64 `xml:"Content-Length"` ContentType string `xml:"Content-Type"` ContentEncoding string `xml:"Content-Encoding"` + CacheControl string `xml:"Cache-Control"` + ContentLanguage string `xml:"Cache-Language"` BlobType BlobType `xml:"x-ms-blob-blob-type"` SequenceNumber int64 `xml:"x-ms-blob-sequence-number"` CopyID string `xml:"CopyId"` @@ -122,6 +124,16 @@ type BlobProperties struct { LeaseStatus string `xml:"LeaseStatus"` } +// BlobHeaders contains various properties of a blob and is an entry +// in SetBlobProperties +type BlobHeaders struct { + ContentMD5 string `header:"x-ms-blob-content-md5"` + ContentLanguage string `header:"x-ms-blob-content-language"` + ContentEncoding string `header:"x-ms-blob-content-encoding"` + ContentType string `header:"x-ms-blob-content-type"` + CacheControl string `header:"x-ms-blob-cache-control"` +} + // BlobListResponse contains the response fields from ListBlobs call. // // See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx @@ -474,7 +486,6 @@ func (b BlobStorageClient) ListBlobs(container string, params ListBlobsParameter func (b BlobStorageClient) BlobExists(container, name string) (bool, error) { verb := "HEAD" uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - headers := b.client.getStandardHeaders() resp, err := b.client.exec(verb, uri, headers, nil) if resp != nil { @@ -590,6 +601,9 @@ func (b BlobStorageClient) GetBlobProperties(container, name string) (*BlobPrope ContentMD5: resp.headers.Get("Content-MD5"), ContentLength: contentLength, ContentEncoding: resp.headers.Get("Content-Encoding"), + ContentType: resp.headers.Get("Content-Type"), + CacheControl: resp.headers.Get("Cache-Control"), + ContentLanguage: resp.headers.Get("Content-Language"), SequenceNumber: sequenceNum, CopyCompletionTime: resp.headers.Get("x-ms-copy-completion-time"), CopyStatusDescription: resp.headers.Get("x-ms-copy-status-description"), @@ -602,6 +616,34 @@ func (b BlobStorageClient) GetBlobProperties(container, name string) (*BlobPrope }, nil } +// SetBlobProperties replaces the BlobHeaders for the specified blob. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetBlobProperties. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691966.aspx +func (b BlobStorageClient) SetBlobProperties(container, name string, blobHeaders BlobHeaders) error { + params := url.Values{"comp": {"properties"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + extraHeaders := headersFromStruct(blobHeaders) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec("PUT", uri, headers, nil) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + // SetBlobMetadata replaces the metadata for the specified blob. // // Some keys may be converted to Camel-Case before sending. All keys @@ -1033,9 +1075,24 @@ func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Tim blobURL = b.GetBlobURL(container, name) ) canonicalizedResource, err := b.client.buildCanonicalizedResource(blobURL) + if err != nil { return "", err } + + // "The canonicalizedresouce portion of the string is a canonical path to the signed resource. + // It must include the service name (blob, table, queue or file) for version 2015-02-21 or + // later, the storage account name, and the resource name, and must be URL-decoded. + // -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + + // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). + canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) + + canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) + if err != nil { + return "", err + } + signedExpiry := expiry.UTC().Format(time.RFC3339) signedResource := "b" diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go index 4cc7e1124..2816e03ec 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go @@ -29,10 +29,20 @@ const ( defaultUseHTTPS = true + // StorageEmulatorAccountName is the fixed storage account used by Azure Storage Emulator + StorageEmulatorAccountName = "devstoreaccount1" + + // StorageEmulatorAccountKey is the the fixed storage account used by Azure Storage Emulator + StorageEmulatorAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + blobServiceName = "blob" tableServiceName = "table" queueServiceName = "queue" fileServiceName = "file" + + storageEmulatorBlob = "127.0.0.1:10000" + storageEmulatorTable = "127.0.0.1:10002" + storageEmulatorQueue = "127.0.0.1:10001" ) // Client is the object that needs to be constructed to perform @@ -114,9 +124,18 @@ func (e UnexpectedStatusCodeError) Got() int { // NewBasicClient constructs a Client with given storage service name and // key. func NewBasicClient(accountName, accountKey string) (Client, error) { + if accountName == StorageEmulatorAccountName { + return NewEmulatorClient() + } return NewClient(accountName, accountKey, DefaultBaseURL, DefaultAPIVersion, defaultUseHTTPS) } +//NewEmulatorClient contructs a Client intended to only work with Azure +//Storage Emulator +func NewEmulatorClient() (Client, error) { + return NewClient(StorageEmulatorAccountName, StorageEmulatorAccountKey, DefaultBaseURL, DefaultAPIVersion, false) +} + // NewClient constructs a Client. This should be used if the caller wants // to specify whether to use HTTPS, a specific REST API version or a custom // storage endpoint than Azure Public Cloud. @@ -149,8 +168,19 @@ func (c Client) getBaseURL(service string) string { if c.useHTTPS { scheme = "https" } - - host := fmt.Sprintf("%s.%s.%s", c.accountName, service, c.baseURL) + host := "" + if c.accountName == StorageEmulatorAccountName { + switch service { + case blobServiceName: + host = storageEmulatorBlob + case tableServiceName: + host = storageEmulatorTable + case queueServiceName: + host = storageEmulatorQueue + } + } else { + host = fmt.Sprintf("%s.%s.%s", c.accountName, service, c.baseURL) + } u := &url.URL{ Scheme: scheme, @@ -165,8 +195,13 @@ func (c Client) getEndpoint(service, path string, params url.Values) string { panic(err) } - if path == "" { - path = "/" // API doesn't accept path segments not starting with '/' + // API doesn't accept path segments not starting with '/' + if !strings.HasPrefix(path, "/") { + path = fmt.Sprintf("/%v", path) + } + + if c.accountName == StorageEmulatorAccountName { + path = fmt.Sprintf("/%v%v", StorageEmulatorAccountName, path) } u.Path = path @@ -200,7 +235,7 @@ func (c Client) GetFileService() FileServiceClient { func (c Client) createAuthorizationHeader(canonicalizedString string) string { signature := c.computeHmac256(canonicalizedString) - return fmt.Sprintf("%s %s:%s", "SharedKey", c.accountName, signature) + return fmt.Sprintf("%s %s:%s", "SharedKey", c.getCanonicalizedAccountName(), signature) } func (c Client) getAuthorizationHeader(verb, url string, headers map[string]string) (string, error) { @@ -220,6 +255,12 @@ func (c Client) getStandardHeaders() map[string]string { } } +func (c Client) getCanonicalizedAccountName() string { + // since we may be trying to access a secondary storage account, we need to + // remove the -secondary part of the storage name + return strings.TrimSuffix(c.accountName, "-secondary") +} + func (c Client) buildCanonicalizedHeader(headers map[string]string) string { cm := make(map[string]string) @@ -261,7 +302,7 @@ func (c Client) buildCanonicalizedResourceTable(uri string) (string, error) { return "", fmt.Errorf(errMsg, err.Error()) } - cr := "/" + c.accountName + cr := "/" + c.getCanonicalizedAccountName() if len(u.Path) > 0 { cr += u.Path @@ -277,10 +318,13 @@ func (c Client) buildCanonicalizedResource(uri string) (string, error) { return "", fmt.Errorf(errMsg, err.Error()) } - cr := "/" + c.accountName + cr := "/" + c.getCanonicalizedAccountName() if len(u.Path) > 0 { - cr += u.Path + // Any portion of the CanonicalizedResource string that is derived from + // the resource's URI should be encoded exactly as it is in the URI. + // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx + cr += u.EscapedPath() } params, err := url.ParseQuery(u.RawQuery) @@ -343,7 +387,6 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader return nil, err } headers["Authorization"] = authHeader - if err != nil { return nil, err } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go index ede4e21be..4710fbad3 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go @@ -47,6 +47,9 @@ func (f FileServiceClient) CreateShareIfNotExists(name string) (bool, error) { // CreateShare creates a Azure File Share and returns its response func (f FileServiceClient) createShare(name string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}}) headers := f.client.getStandardHeaders() return f.client.exec("PUT", uri, headers, nil) @@ -86,6 +89,18 @@ func (f FileServiceClient) DeleteShareIfExists(name string) (bool, error) { // deleteShare makes the call to Delete Share operation endpoint and returns // the response func (f FileServiceClient) deleteShare(name string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}}) return f.client.exec("DELETE", uri, f.client.getStandardHeaders(), nil) } + +//checkForStorageEmulator determines if the client is setup for use with +//Azure Storage Emulator, and returns a relevant error +func (f FileServiceClient) checkForStorageEmulator() error { + if f.client.accountName == StorageEmulatorAccountName { + return fmt.Errorf("Error: File service is not currently supported by Azure Storage Emulator") + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go index c81393e5f..1b5919cd1 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go @@ -98,6 +98,10 @@ func (c *TableServiceClient) QueryTableEntities(tableName AzureTable, previousCo resp, err := c.client.execTable("GET", uri, headers, nil) + if err != nil { + return nil, nil, err + } + contToken := extractContinuationTokenFromHeaders(resp.headers) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go index 33155af7f..d71c6ce55 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "net/http" "net/url" + "reflect" "time" ) @@ -69,3 +70,16 @@ func xmlMarshal(v interface{}) (io.Reader, int, error) { } return bytes.NewReader(b), len(b), nil } + +func headersFromStruct(v interface{}) map[string]string { + headers := make(map[string]string) + value := reflect.ValueOf(v) + for i := 0; i < value.NumField(); i++ { + key := value.Type().Field(i).Tag.Get("header") + val := value.Field(i).String() + if val != "" { + headers[key] = val + } + } + return headers +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go index e50771f80..56fdfc2bf 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go @@ -44,7 +44,7 @@ type Error interface { // BatchError is a batch of errors which also wraps lower level errors with // code, message, and original errors. Calling Error() will include all errors -// that occured in the batch. +// that occurred in the batch. // // Deprecated: Replaced with BatchedErrors. Only defined for backwards // compatibility. @@ -64,7 +64,7 @@ type BatchError interface { // BatchedErrors is a batch of errors which also wraps lower level errors with // code, message, and original errors. Calling Error() will include all errors -// that occured in the batch. +// that occurred in the batch. // // Replaces BatchError type BatchedErrors interface { diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go index e2d333b84..0202a008f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go @@ -98,7 +98,7 @@ func (b baseError) OrigErr() error { return NewBatchError(err.Code(), err.Message(), b.errs[1:]) } return NewBatchError("BatchedErrors", - "multiple errors occured", b.errs) + "multiple errors occurred", b.errs) } } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go index 8429470b9..1a3d106d5 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go @@ -3,6 +3,7 @@ package awsutil import ( "io" "reflect" + "time" ) // Copy deeply copies a src structure to dst. Useful for copying request and @@ -49,7 +50,14 @@ func rcopy(dst, src reflect.Value, root bool) { } else { e := src.Type().Elem() if dst.CanSet() && !src.IsNil() { - dst.Set(reflect.New(e)) + if _, ok := src.Interface().(*time.Time); !ok { + dst.Set(reflect.New(e)) + } else { + tempValue := reflect.New(e) + tempValue.Elem().Set(src.Elem()) + // Sets time.Time's unexported values + dst.Set(tempValue) + } } if src.Elem().IsValid() { // Keep the current root state since the depth hasn't changed 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 c8d0564d8..4003c04b0 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 @@ -87,9 +87,18 @@ const logReqMsg = `DEBUG: Request %s/%s Details: %s -----------------------------------------------------` +const logReqErrMsg = `DEBUG ERROR: Request %s/%s: +---[ REQUEST DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + func logRequest(r *request.Request) { logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) - dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody) + dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } if logBody { // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's @@ -107,11 +116,21 @@ const logRespMsg = `DEBUG: Response %s/%s Details: %s -----------------------------------------------------` +const logRespErrMsg = `DEBUG ERROR: Response %s/%s: +---[ RESPONSE DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + func logResponse(r *request.Request) { var msg = "no response data" if r.HTTPResponse != nil { logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) - dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody) + dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + msg = string(dumpedBody) } else if r.Error != nil { msg = r.Error.Error() diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go index da72935be..fca922584 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -7,24 +7,36 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials" ) -// UseServiceDefaultRetries instructs the config to use the service's own default -// number of retries. This will be the default action if Config.MaxRetries -// is nil also. +// UseServiceDefaultRetries instructs the config to use the service's own +// default number of retries. This will be the default action if +// Config.MaxRetries is nil also. const UseServiceDefaultRetries = -1 -// RequestRetryer is an alias for a type that implements the request.Retryer interface. +// RequestRetryer is an alias for a type that implements the request.Retryer +// interface. type RequestRetryer interface{} // A Config provides service configuration for service clients. By default, -// all clients will use the {defaults.DefaultConfig} structure. +// all clients will use the defaults.DefaultConfig tructure. +// +// // Create Session with MaxRetry configuration to be shared by multiple +// // service clients. +// sess, err := session.NewSession(&aws.Config{ +// MaxRetries: aws.Int(3), +// }) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, &aws.Config{ +// Region: aws.String("us-west-2"), +// }) type Config struct { // Enables verbose error printing of all credential chain errors. - // Should be used when wanting to see all errors while attempting to retreive - // credentials. + // Should be used when wanting to see all errors while attempting to + // retrieve credentials. CredentialsChainVerboseErrors *bool - // The credentials object to use when signing requests. Defaults to - // a chain of credential providers to search for credentials in environment + // The credentials object to use when signing requests. Defaults to a + // chain of credential providers to search for credentials in environment // variables, shared credential file, and EC2 Instance Roles. Credentials *credentials.Credentials @@ -63,11 +75,12 @@ type Config struct { Logger Logger // The maximum number of times that a request will be retried for failures. - // Defaults to -1, which defers the max retry setting to the service specific - // configuration. + // Defaults to -1, which defers the max retry setting to the service + // specific configuration. MaxRetries *int - // Retryer guides how HTTP requests should be retried in case of recoverable failures. + // Retryer guides how HTTP requests should be retried in case of + // recoverable failures. // // When nil or the value does not implement the request.Retryer interface, // the request.DefaultRetryer will be used. @@ -82,8 +95,8 @@ type Config struct { // Retryer RequestRetryer - // Disables semantic parameter validation, which validates input for missing - // required fields and/or other semantic request input errors. + // Disables semantic parameter validation, which validates input for + // missing required fields and/or other semantic request input errors. DisableParamValidation *bool // Disables the computation of request and response checksums, e.g., @@ -91,8 +104,8 @@ type Config struct { DisableComputeChecksums *bool // Set this to `true` to force the request to use path-style addressing, - // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will - // use virtual hosted bucket addressing when possible + // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client + // will use virtual hosted bucket addressing when possible // (`http://BUCKET.s3.amazonaws.com/KEY`). // // @note This configuration option is specific to the Amazon S3 service. @@ -109,36 +122,63 @@ type Config struct { // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html // // 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s - // `ExpectContinueTimeout` for information on adjusting the continue wait timeout. - // https://golang.org/pkg/net/http/#Transport + // `ExpectContinueTimeout` for information on adjusting the continue wait + // timeout. https://golang.org/pkg/net/http/#Transport // - // You should use this flag to disble 100-Continue if you experiance issues - // with proxies or thrid party S3 compatible services. + // You should use this flag to disble 100-Continue if you experience issues + // with proxies or third party S3 compatible services. S3Disable100Continue *bool - // Set this to `true` to enable S3 Accelerate feature. For all operations compatible - // with S3 Accelerate will use the accelerate endpoint for requests. Requests not compatible - // will fall back to normal S3 requests. + // Set this to `true` to enable S3 Accelerate feature. For all operations + // compatible with S3 Accelerate will use the accelerate endpoint for + // requests. Requests not compatible will fall back to normal S3 requests. // - // The bucket must be enable for accelerate to be used with S3 client with accelerate - // enabled. If the bucket is not enabled for accelerate an error will be returned. - // The bucket name must be DNS compatible to also work with accelerate. + // The bucket must be enable for accelerate to be used with S3 client with + // accelerate enabled. If the bucket is not enabled for accelerate an error + // will be returned. The bucket name must be DNS compatible to also work + // with accelerate. + // + // Not compatible with UseDualStack requests will fail if both flags are + // specified. S3UseAccelerate *bool // Set this to `true` to disable the EC2Metadata client from overriding the - // default http.Client's Timeout. This is helpful if you do not want the EC2Metadata - // client to create a new http.Client. This options is only meaningful if you're not - // already using a custom HTTP client with the SDK. Enabled by default. + // default http.Client's Timeout. This is helpful if you do not want the + // EC2Metadata client to create a new http.Client. This options is only + // meaningful if you're not already using a custom HTTP client with the + // SDK. Enabled by default. // - // Must be set and provided to the session.New() in order to disable the EC2Metadata - // overriding the timeout for default credentials chain. + // Must be set and provided to the session.NewSession() in order to disable + // the EC2Metadata overriding the timeout for default credentials chain. // // Example: - // sess := session.New(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true)) + // sess, err := session.NewSession(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true)) + // // svc := s3.New(sess) // EC2MetadataDisableTimeoutOverride *bool + // Instructs the endpiont to be generated for a service client to + // be the dual stack endpoint. The dual stack endpoint will support + // both IPv4 and IPv6 addressing. + // + // Setting this for a service which does not support dual stack will fail + // to make requets. It is not recommended to set this value on the session + // as it will apply to all service clients created with the session. Even + // services which don't support dual stack endpoints. + // + // If the Endpoint config value is also provided the UseDualStack flag + // will be ignored. + // + // Only supported with. + // + // sess, err := session.NewSession() + // + // svc := s3.New(sess, &aws.Config{ + // UseDualStack: aws.Bool(true), + // }) + UseDualStack *bool + // SleepDelay is an override for the func the SDK will call when sleeping // during the lifecycle of a request. Specifically this will be used for // request delays. This value should only be used for testing. To adjust @@ -147,11 +187,19 @@ type Config struct { SleepDelay func(time.Duration) } -// NewConfig returns a new Config pointer that can be chained with builder methods to -// set multiple configuration values inline without using pointers. +// NewConfig returns a new Config pointer that can be chained with builder +// methods to set multiple configuration values inline without using pointers. // -// sess := session.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10)) +// // Create Session with MaxRetry configuration to be shared by multiple +// // service clients. +// sess, err := session.NewSession(aws.NewConfig(). +// WithMaxRetries(3), +// ) // +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, aws.NewConfig(). +// WithRegion("us-west-2"), +// ) func NewConfig() *Config { return &Config{} } @@ -254,6 +302,13 @@ func (c *Config) WithS3UseAccelerate(enable bool) *Config { return c } +// WithUseDualStack sets a config UseDualStack value returning a Config +// pointer for chaining. +func (c *Config) WithUseDualStack(enable bool) *Config { + c.UseDualStack = &enable + return c +} + // WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value // returning a Config pointer for chaining. func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config { @@ -340,6 +395,10 @@ func mergeInConfig(dst *Config, other *Config) { dst.S3UseAccelerate = other.S3UseAccelerate } + if other.UseDualStack != nil { + dst.UseDualStack = other.UseDualStack + } + if other.EC2MetadataDisableTimeoutOverride != nil { dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go index 6f075604e..4f5dab3fc 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go @@ -30,13 +30,22 @@ func NewStaticCredentials(id, secret, token string) *Credentials { }}) } +// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object +// wrapping the static credentials value provide. Same as NewStaticCredentials +// but takes the creds Value instead of individual fields +func NewStaticCredentialsFromCreds(creds Value) *Credentials { + return NewCredentials(&StaticProvider{Value: creds}) +} + // Retrieve returns the credentials or error if the credentials are invalid. func (s *StaticProvider) Retrieve() (Value, error) { if s.AccessKeyID == "" || s.SecretAccessKey == "" { return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty } - s.Value.ProviderName = StaticProviderName + if len(s.Value.ProviderName) == 0 { + s.Value.ProviderName = StaticProviderName + } return s.Value, nil } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go new file mode 100644 index 000000000..30c847ae2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go @@ -0,0 +1,161 @@ +// Package stscreds are credential Providers to retrieve STS AWS credentials. +// +// STS provides multiple ways to retrieve credentials which can be used when making +// future AWS service API operation calls. +package stscreds + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/service/sts" +) + +// ProviderName provides a name of AssumeRole provider +const ProviderName = "AssumeRoleProvider" + +// AssumeRoler represents the minimal subset of the STS client API used by this provider. +type AssumeRoler interface { + AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) +} + +// DefaultDuration is the default amount of time in minutes that the credentials +// will be valid for. +var DefaultDuration = time.Duration(15) * time.Minute + +// AssumeRoleProvider retrieves temporary credentials from the STS service, and +// keeps track of their expiration time. This provider must be used explicitly, +// as it is not included in the credentials chain. +type AssumeRoleProvider struct { + credentials.Expiry + + // STS client to make assume role request with. + Client AssumeRoler + + // Role to be assumed. + RoleARN string + + // Session name, if you wish to reuse the credentials elsewhere. + RoleSessionName string + + // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // Optional ExternalID to pass along, defaults to nil if not set. + ExternalID *string + + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + SerialNumber *string + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + TokenCode *string + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes a Config provider to create the STS client. The ConfigProvider is +// satisfied by the session.Session type. +func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: sts.New(c), + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes an AssumeRoler which can be satisfiede by the STS client. +func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: svc, + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve generates a new set of temporary credentials using STS. +func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { + + // Apply defaults where parameters are not set. + if p.RoleSessionName == "" { + // Try to work out a role name that will hopefully end up unique. + p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano()) + } + if p.Duration == 0 { + // Expire as often as AWS permits. + p.Duration = DefaultDuration + } + input := &sts.AssumeRoleInput{ + DurationSeconds: aws.Int64(int64(p.Duration / time.Second)), + RoleArn: aws.String(p.RoleARN), + RoleSessionName: aws.String(p.RoleSessionName), + ExternalId: p.ExternalID, + } + if p.Policy != nil { + input.Policy = p.Policy + } + if p.SerialNumber != nil && p.TokenCode != nil { + input.SerialNumber = p.SerialNumber + input.TokenCode = p.TokenCode + } + roleOutput, err := p.Client.AssumeRole(input) + + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + // We will proactively generate new credentials before they expire. + p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: *roleOutput.Credentials.AccessKeyId, + SecretAccessKey: *roleOutput.Credentials.SecretAccessKey, + SessionToken: *roleOutput.Credentials.SessionToken, + ProviderName: ProviderName, + }, nil +} 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 570417ffa..10b7d8649 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 @@ -90,12 +90,14 @@ func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credenti Providers: []credentials.Provider{ &credentials.EnvProvider{}, &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, - remoteCredProvider(*cfg, handlers), + RemoteCredProvider(*cfg, handlers), }, }) } -func remoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { +// RemoteCredProvider returns a credenitials provider for the default remote +// endpoints such as EC2 or ECS Roles. +func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { ecsCredURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") if len(ecsCredURI) > 0 { @@ -118,7 +120,7 @@ func ecsCredProvider(cfg aws.Config, handlers request.Handlers, uri string) cred func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, - aws.StringValue(cfg.Region), true) + aws.StringValue(cfg.Region), true, false) return &ec2rolecreds.EC2RoleProvider{ Client: ec2metadata.NewClient(cfg, handlers, endpoint, signingRegion), diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go new file mode 100644 index 000000000..097d3237b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go @@ -0,0 +1,223 @@ +/* +Package session provides configuration for the SDK's service clients. + +Sessions can be shared across all service clients that share the same base +configuration. The Session is built from the SDK's default configuration and +request handlers. + +Sessions should be cached when possible, because creating a new Session will +load all configuration values from the environment, and config files each time +the Session is created. Sharing the Session value across all of your service +clients will ensure the configuration is loaded the fewest number of times possible. + +Concurrency + +Sessions are safe to use concurrently as long as the Session is not being +modified. The SDK will not modify the Session once the Session has been created. +Creating service clients concurrently from a shared Session is safe. + +Sessions from Shared Config + +Sessions can be created using the method above that will only load the +additional config if the AWS_SDK_LOAD_CONFIG environment variable is set. +Alternatively you can explicitly create a Session with shared config enabled. +To do this you can use NewSessionWithOptions to configure how the Session will +be created. Using the NewSessionWithOptions with SharedConfigState set to +SharedConfigEnabled will create the session as if the AWS_SDK_LOAD_CONFIG +environment variable was set. + +Creating Sessions + +When creating Sessions optional aws.Config values can be passed in that will +override the default, or loaded config values the Session is being created +with. This allows you to provide additional, or case based, configuration +as needed. + +By default NewSession will only load credentials from the shared credentials +file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is +set to a truthy value the Session will be created from the configuration +values from the shared config (~/.aws/config) and shared credentials +(~/.aws/credentials) files. See the section Sessions from Shared Config for +more information. + +Create a Session with the default config and request handlers. With credentials +region, and profile loaded from the environment and shared config automatically. +Requires the AWS_PROFILE to be set, or "default" is used. + + // Create Session + sess, err := session.NewSession() + + // Create a Session with a custom region + sess, err := session.NewSession(&aws.Config{Region: aws.String("us-east-1")}) + + // Create a S3 client instance from a session + sess, err := session.NewSession() + if err != nil { + // Handle Session creation error + } + svc := s3.New(sess) + +Create Session With Option Overrides + +In addition to NewSession, Sessions can be created using NewSessionWithOptions. +This func allows you to control and override how the Session will be created +through code instead of being driven by environment variables only. + +Use NewSessionWithOptions when you want to provide the config profile, or +override the shared config state (AWS_SDK_LOAD_CONFIG). + + // Equivalent to session.New + sess, err := session.NewSessionWithOptions(session.Options{}) + + // Specify profile to load for the session's config + sess, err := session.NewSessionWithOptions(session.Options{ + Profile: "profile_name", + }) + + // Specify profile for config and region for requests + sess, err := session.NewSessionWithOptions(session.Options{ + Config: aws.Config{Region: aws.String("us-east-1")}, + Profile: "profile_name", + }) + + // Force enable Shared Config support + sess, err := session.NewSessionWithOptions(session.Options{ + SharedConfigState: SharedConfigEnable, + }) + +Adding Handlers + +You can add handlers to a session for processing HTTP requests. All service +clients that use the session inherit the handlers. For example, the following +handler logs every request and its payload made by a service client: + + // Create a session, and add additional handlers for all service + // clients created with the Session to inherit. Adds logging handler. + sess, err := session.NewSession() + sess.Handlers.Send.PushFront(func(r *request.Request) { + // Log every request made and its payload + logger.Println("Request: %s/%s, Payload: %s", + r.ClientInfo.ServiceName, r.Operation, r.Params) + }) + +Deprecated "New" function + +The New session function has been deprecated because it does not provide good +way to return errors that occur when loading the configuration files and values. +Because of this, NewSession was created so errors can be retrieved when +creating a session fails. + +Shared Config Fields + +By default the SDK will only load the shared credentials file's (~/.aws/credentials) +credentials values, and all other config is provided by the environment variables, +SDK defaults, and user provided aws.Config values. + +If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable +option is used to create the Session the full shared config values will be +loaded. This includes credentials, region, and support for assume role. In +addition the Session will load its configuration from both the shared config +file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both +files have the same format. + +If both config files are present the configuration from both files will be +read. The Session will be created from configuration values from the shared +credentials file (~/.aws/credentials) over those in the shared credentials +file (~/.aws/config). + +Credentials are the values the SDK should use for authenticating requests with +AWS Services. They arfrom a configuration file will need to include both +aws_access_key_id and aws_secret_access_key must be provided together in the +same file to be considered valid. The values will be ignored if not a complete +group. aws_session_token is an optional field that can be provided if both of +the other two fields are also provided. + + aws_access_key_id = AKID + aws_secret_access_key = SECRET + aws_session_token = TOKEN + +Assume Role values allow you to configure the SDK to assume an IAM role using +a set of credentials provided in a config file via the source_profile field. +Both "role_arn" and "source_profile" are required. The SDK does not support +assuming a role with MFA token Via the Session's constructor. You can use the +stscreds.AssumeRoleProvider credentials provider to specify custom +configuration and support for MFA. + + role_arn = arn:aws:iam:::role/ + source_profile = profile_with_creds + external_id = 1234 + mfa_serial = not supported! + role_session_name = session_name + +Region is the region the SDK should use for looking up AWS service endpoints +and signing requests. + + region = us-east-1 + +Environment Variables + +When a Session is created several environment variables can be set to adjust +how the SDK functions, and what configuration data it loads when creating +Sessions. All environment values are optional, but some values like credentials +require multiple of the values to set or the partial values will be ignored. +All environment variable values are strings unless otherwise noted. + +Environment configuration values. If set both Access Key ID and Secret Access +Key must be provided. Session Token and optionally also be provided, but is +not required. + + # Access Key ID + AWS_ACCESS_KEY_ID=AKID + AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + + # Secret Access Key + AWS_SECRET_ACCESS_KEY=SECRET + AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + + # Session Token + AWS_SESSION_TOKEN=TOKEN + +Region value will instruct the SDK where to make service API requests to. If is +not provided in the environment the region must be provided before a service +client request is made. + + AWS_REGION=us-east-1 + + # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_REGION is not also set. + AWS_DEFAULT_REGION=us-east-1 + +Profile name the SDK should load use when loading shared config from the +configuration files. If not provided "default" will be used as the profile name. + + AWS_PROFILE=my_profile + + # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_PROFILE is not also set. + AWS_DEFAULT_PROFILE=my_profile + +SDK load config instructs the SDK to load the shared config in addition to +shared credentials. This also expands the configuration loaded so the shared +credentials will have parity with the shared config file. This also enables +Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE +env values as well. + + AWS_SDK_LOAD_CONFIG=1 + +Shared credentials file path can be set to instruct the SDK to use an alternative +file for the shared credentials. If not set the file will be loaded from +$HOME/.aws/credentials on Linux/Unix based systems, and +%USERPROFILE%\.aws\credentials on Windows. + + AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + +Shared config file path can be set to instruct the SDK to use an alternative +file for the shared config. If not set the file will be loaded from +$HOME/.aws/config on Linux/Unix based systems, and +%USERPROFILE%\.aws\config on Windows. + + AWS_CONFIG_FILE=$HOME/my_shared_config + + +*/ +package session diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go new file mode 100644 index 000000000..d2f0c8448 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -0,0 +1,188 @@ +package session + +import ( + "os" + "path/filepath" + "strconv" + + "github.com/aws/aws-sdk-go/aws/credentials" +) + +// envConfig is a collection of environment values the SDK will read +// setup config from. All environment values are optional. But some values +// such as credentials require multiple values to be complete or the values +// will be ignored. +type envConfig struct { + // Environment configuration values. If set both Access Key ID and Secret Access + // Key must be provided. Session Token and optionally also be provided, but is + // not required. + // + // # Access Key ID + // AWS_ACCESS_KEY_ID=AKID + // AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + // + // # Secret Access Key + // AWS_SECRET_ACCESS_KEY=SECRET + // AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + // + // # Session Token + // AWS_SESSION_TOKEN=TOKEN + Creds credentials.Value + + // Region value will instruct the SDK where to make service API requests to. If is + // not provided in the environment the region must be provided before a service + // client request is made. + // + // AWS_REGION=us-east-1 + // + // # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_REGION is not also set. + // AWS_DEFAULT_REGION=us-east-1 + Region string + + // Profile name the SDK should load use when loading shared configuration from the + // shared configuration files. If not provided "default" will be used as the + // profile name. + // + // AWS_PROFILE=my_profile + // + // # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_PROFILE is not also set. + // AWS_DEFAULT_PROFILE=my_profile + Profile string + + // SDK load config instructs the SDK to load the shared config in addition to + // shared credentials. This also expands the configuration loaded from the shared + // credentials to have parity with the shared config file. This also enables + // Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE + // env values as well. + // + // AWS_SDK_LOAD_CONFIG=1 + EnableSharedConfig bool + + // Shared credentials file path can be set to instruct the SDK to use an alternate + // file for the shared credentials. If not set the file will be loaded from + // $HOME/.aws/credentials on Linux/Unix based systems, and + // %USERPROFILE%\.aws\credentials on Windows. + // + // AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + SharedCredentialsFile string + + // Shared config file path can be set to instruct the SDK to use an alternate + // file for the shared config. If not set the file will be loaded from + // $HOME/.aws/config on Linux/Unix based systems, and + // %USERPROFILE%\.aws\config on Windows. + // + // AWS_CONFIG_FILE=$HOME/my_shared_config + SharedConfigFile string +} + +var ( + credAccessEnvKey = []string{ + "AWS_ACCESS_KEY_ID", + "AWS_ACCESS_KEY", + } + credSecretEnvKey = []string{ + "AWS_SECRET_ACCESS_KEY", + "AWS_SECRET_KEY", + } + credSessionEnvKey = []string{ + "AWS_SESSION_TOKEN", + } + + regionEnvKeys = []string{ + "AWS_REGION", + "AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set + } + profileEnvKeys = []string{ + "AWS_PROFILE", + "AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set + } +) + +// loadEnvConfig retrieves the SDK's environment configuration. +// See `envConfig` for the values that will be retrieved. +// +// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value +// the shared SDK config will be loaded in addition to the SDK's specific +// configuration values. +func loadEnvConfig() envConfig { + enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) + return envConfigLoad(enableSharedConfig) +} + +// loadEnvSharedConfig retrieves the SDK's environment configuration, and the +// SDK shared config. See `envConfig` for the values that will be retrieved. +// +// Loads the shared configuration in addition to the SDK's specific configuration. +// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` +// environment variable is set. +func loadSharedEnvConfig() envConfig { + return envConfigLoad(true) +} + +func envConfigLoad(enableSharedConfig bool) envConfig { + cfg := envConfig{} + + cfg.EnableSharedConfig = enableSharedConfig + + setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey) + setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey) + setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey) + + // Require logical grouping of credentials + if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 { + cfg.Creds = credentials.Value{} + } else { + cfg.Creds.ProviderName = "EnvConfigCredentials" + } + + regionKeys := regionEnvKeys + profileKeys := profileEnvKeys + if !cfg.EnableSharedConfig { + regionKeys = regionKeys[:1] + profileKeys = profileKeys[:1] + } + + setFromEnvVal(&cfg.Region, regionKeys) + setFromEnvVal(&cfg.Profile, profileKeys) + + cfg.SharedCredentialsFile = sharedCredentialsFilename() + cfg.SharedConfigFile = sharedConfigFilename() + + return cfg +} + +func setFromEnvVal(dst *string, keys []string) { + for _, k := range keys { + if v := os.Getenv(k); len(v) > 0 { + *dst = v + break + } + } +} + +func sharedCredentialsFilename() string { + if name := os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(name) > 0 { + return name + } + + return filepath.Join(userHomeDir(), ".aws", "credentials") +} + +func sharedConfigFilename() string { + if name := os.Getenv("AWS_CONFIG_FILE"); len(name) > 0 { + return name + } + + return filepath.Join(userHomeDir(), ".aws", "config") +} + +func userHomeDir() string { + homeDir := os.Getenv("HOME") // *nix + if len(homeDir) == 0 { // windows + homeDir = os.Getenv("USERPROFILE") + } + + return homeDir +} 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 6bc8f1be9..2374b1f27 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 @@ -1,17 +1,14 @@ -// Package session provides a way to create service clients with shared configuration -// and handlers. -// -// Generally this package should be used instead of the `defaults` package. -// -// A session should be used to share configurations and request handlers between multiple -// service clients. When service clients need specific configuration aws.Config can be -// used to provide additional configuration directly to the service client. package session import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/private/endpoints" @@ -21,36 +18,199 @@ import ( // store configurations and request handlers for those services. // // Sessions are safe to create service clients concurrently, but it is not safe -// to mutate the session concurrently. +// to mutate the Session concurrently. +// +// The Session satisfies the service client's client.ClientConfigProvider. type Session struct { Config *aws.Config Handlers request.Handlers } -// New creates a new instance of the handlers merging in the provided Configs -// on top of the SDK's default configurations. Once the session is created it -// can be mutated to modify Configs or Handlers. The session is safe to be read -// concurrently, but it should not be written to concurrently. +// New creates a new instance of the handlers merging in the provided configs +// on top of the SDK's default configurations. Once the Session is created it +// can be mutated to modify the Config or Handlers. The Session is safe to be +// read concurrently, but it should not be written to concurrently. // -// Example: -// // Create a session with the default config and request handlers. -// sess := session.New() +// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New +// method could now encounter an error when loading the configuration. When +// The environment variable is set, and an error occurs, New will return a +// session that will fail all requests reporting the error that occured while +// loading the session. Use NewSession to get the error when creating the +// session. // -// // Create a session with a custom region -// sess := session.New(&aws.Config{Region: aws.String("us-east-1")}) +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded, in addition to +// the shared credentials file (~/.aws/config). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. // -// // Create a session, and add additional handlers for all service -// // clients created with the session to inherit. Adds logging handler. -// sess := session.New() -// sess.Handlers.Send.PushFront(func(r *request.Request) { -// // Log every request made and its payload -// logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params) +// Deprecated: Use NewSession functiions to create sessions instead. NewSession +// has the same functionality as New except an error can be returned when the +// func is called instead of waiting to receive an error until a request is made. +func New(cfgs ...*aws.Config) *Session { + // load initial config from environment + envCfg := loadEnvConfig() + + if envCfg.EnableSharedConfig { + s, err := newSession(envCfg, cfgs...) + if err != nil { + // Old session.New expected all errors to be discovered when + // a request is made, and would report the errors then. This + // needs to be replicated if an error occurs while creating + // the session. + msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " + + "Use session.NewSession to handle errors occuring during session creation." + + // Session creation failed, need to report the error and prevent + // any requests from succeeding. + s = &Session{Config: defaults.Config()} + s.Config.MergeIn(cfgs...) + s.Config.Logger.Log("ERROR:", msg, "Error:", err) + s.Handlers.Validate.PushBack(func(r *request.Request) { + r.Error = err + }) + } + return s + } + + return oldNewSession(cfgs...) +} + +// NewSession returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. Once the Session is created +// it can be mutated to modify the Config or Handlers. The Session is safe to +// be read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/config). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// See the NewSessionWithOptions func for information on how to override or +// control through code how the Session will be created. Such as specifing the +// config profile, and controlling if shared config is enabled or not. +func NewSession(cfgs ...*aws.Config) (*Session, error) { + envCfg := loadEnvConfig() + + return newSession(envCfg, cfgs...) +} + +// SharedConfigState provides the ability to optionally override the state +// of the session's creation based on the shared config being enabled or +// disabled. +type SharedConfigState int + +const ( + // SharedConfigStateFromEnv does not override any state of the + // AWS_SDK_LOAD_CONFIG env var. It is the default value of the + // SharedConfigState type. + SharedConfigStateFromEnv SharedConfigState = iota + + // SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value + // and disables the shared config functionality. + SharedConfigDisable + + // SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value + // and enables the shared config functionality. + SharedConfigEnable +) + +// Options provides the means to control how a Session is created and what +// configuration values will be loaded. +// +type Options struct { + // Provides config values for the SDK to use when creating service clients + // and making API requests to services. Any value set in with this field + // will override the associated value provided by the SDK defaults, + // environment or config files where relevent. + // + // If not set, configuration values from from SDK defaults, environment, + // config will be used. + Config aws.Config + + // Overrides the config profile the Session should be created from. If not + // set the value of the environment variable will be loaded (AWS_PROFILE, + // or AWS_DEFAULT_PROFILE if the Shared Config is enabled). + // + // If not set and environment variables are not set the "default" + // (DefaultSharedConfigProfile) will be used as the profile to load the + // session config from. + Profile string + + // Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG + // environment variable. By default a Session will be created using the + // value provided by the AWS_SDK_LOAD_CONFIG environment variable. + // + // Setting this value to SharedConfigEnable or SharedConfigDisable + // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable + // and enable or disable the shared config functionality. + SharedConfigState SharedConfigState +} + +// NewSessionWithOptions returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. This func uses the Options +// values to configure how the Session is created. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/config). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// // Equivalent to session.New +// sess, err := session.NewSessionWithOptions(session.Options{}) +// +// // Specify profile to load for the session's config +// sess, err := session.NewSessionWithOptions(session.Options{ +// Profile: "profile_name", // }) // -// // Create a S3 client instance from a session -// sess := session.New() -// svc := s3.New(sess) -func New(cfgs ...*aws.Config) *Session { +// // Specify profile for config and region for requests +// sess, err := session.NewSessionWithOptions(session.Options{ +// Config: aws.Config{Region: aws.String("us-east-1")}, +// Profile: "profile_name", +// }) +// +// // Force enable Shared Config support +// sess, err := session.NewSessionWithOptions(session.Options{ +// SharedConfigState: SharedConfigEnable, +// }) +func NewSessionWithOptions(opts Options) (*Session, error) { + envCfg := loadEnvConfig() + + if len(opts.Profile) > 0 { + envCfg.Profile = opts.Profile + } + + switch opts.SharedConfigState { + case SharedConfigDisable: + envCfg.EnableSharedConfig = false + case SharedConfigEnable: + envCfg.EnableSharedConfig = true + } + + return newSession(envCfg, &opts.Config) +} + +// Must is a helper function to ensure the Session is valid and there was no +// error when calling a NewSession function. +// +// This helper is intended to be used in variable initialization to load the +// Session and configuration at startup. Such as: +// +// var sess = session.Must(session.NewSession()) +func Must(sess *Session, err error) *Session { + if err != nil { + panic(err) + } + + return sess +} + +func oldNewSession(cfgs ...*aws.Config) *Session { cfg := defaults.Config() handlers := defaults.Handlers() @@ -72,6 +232,115 @@ func New(cfgs ...*aws.Config) *Session { return s } +func newSession(envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { + cfg := defaults.Config() + handlers := defaults.Handlers() + + // Get a merged version of the user provided config to determine if + // credentials were. + userCfg := &aws.Config{} + userCfg.MergeIn(cfgs...) + + // Order config files will be loaded in with later files overwriting + // previous config file values. + cfgFiles := []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile} + if !envCfg.EnableSharedConfig { + // The shared config file (~/.aws/config) is only loaded if instructed + // to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG). + cfgFiles = cfgFiles[1:] + } + + // Load additional config from file(s) + sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles) + if err != nil { + return nil, err + } + + mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers) + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + + return s, nil +} + +func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers) { + // Merge in user provided configuration + cfg.MergeIn(userCfg) + + // Region if not already set by user + if len(aws.StringValue(cfg.Region)) == 0 { + if len(envCfg.Region) > 0 { + cfg.WithRegion(envCfg.Region) + } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 { + cfg.WithRegion(sharedCfg.Region) + } + } + + // Configure credentials if not already set + if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { + if len(envCfg.Creds.AccessKeyID) > 0 { + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + envCfg.Creds, + ) + } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil { + cfgCp := *cfg + cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( + sharedCfg.AssumeRoleSource.Creds, + ) + cfg.Credentials = stscreds.NewCredentials( + &Session{ + Config: &cfgCp, + Handlers: handlers.Copy(), + }, + sharedCfg.AssumeRole.RoleARN, + func(opt *stscreds.AssumeRoleProvider) { + opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName + + if len(sharedCfg.AssumeRole.ExternalID) > 0 { + opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) + } + + // MFA not supported + }, + ) + } else if len(sharedCfg.Creds.AccessKeyID) > 0 { + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + sharedCfg.Creds, + ) + } else { + // Fallback to default credentials provider, include mock errors + // for the credential chain so user can identify why credentials + // failed to be retrieved. + cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: []credentials.Provider{ + &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)}, + &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)}, + defaults.RemoteCredProvider(*cfg, handlers), + }, + }) + } + } +} + +type credProviderError struct { + Err error +} + +var emptyCreds = credentials.Value{} + +func (c credProviderError) Retrieve() (credentials.Value, error) { + return credentials.Value{}, c.Err +} +func (c credProviderError) IsExpired() bool { + return true +} + func initHandlers(s *Session) { // Add the Validate parameter handler if it is not disabled. s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) @@ -80,12 +349,11 @@ func initHandlers(s *Session) { } } -// Copy creates and returns a copy of the current session, coping the config +// Copy creates and returns a copy of the current Session, coping the config // and handlers. If any additional configs are provided they will be merged -// on top of the session's copied config. +// on top of the Session's copied config. // -// Example: -// // Create a copy of the current session, configured for the us-west-2 region. +// // Create a copy of the current Session, configured for the us-west-2 region. // sess.Copy(&aws.Config{Region: aws.String("us-west-2")}) func (s *Session) Copy(cfgs ...*aws.Config) *Session { newSession := &Session{ @@ -101,15 +369,15 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session { // ClientConfig satisfies the client.ConfigProvider interface and is used to // configure the service client instances. Passing the Session to the service // client's constructor (New) will use this method to configure the client. -// -// Example: -// sess := session.New() -// s3.New(sess) func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { s = s.Copy(cfgs...) endpoint, signingRegion := endpoints.NormalizeEndpoint( - aws.StringValue(s.Config.Endpoint), serviceName, - aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL)) + aws.StringValue(s.Config.Endpoint), + serviceName, + aws.StringValue(s.Config.Region), + aws.BoolValue(s.Config.DisableSSL), + aws.BoolValue(s.Config.UseDualStack), + ) return client.Config{ Config: s.Config, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go new file mode 100644 index 000000000..0147eedeb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go @@ -0,0 +1,294 @@ +package session + +import ( + "fmt" + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/go-ini/ini" +) + +const ( + // Static Credentials group + accessKeyIDKey = `aws_access_key_id` // group required + secretAccessKey = `aws_secret_access_key` // group required + sessionTokenKey = `aws_session_token` // optional + + // Assume Role Credentials group + roleArnKey = `role_arn` // group required + sourceProfileKey = `source_profile` // group required + externalIDKey = `external_id` // optional + mfaSerialKey = `mfa_serial` // optional + roleSessionNameKey = `role_session_name` // optional + + // Additional Config fields + regionKey = `region` + + // DefaultSharedConfigProfile is the default profile to be used when + // loading configuration from the config files if another profile name + // is not provided. + DefaultSharedConfigProfile = `default` +) + +type assumeRoleConfig struct { + RoleARN string + SourceProfile string + ExternalID string + MFASerial string + RoleSessionName string +} + +// sharedConfig represents the configuration fields of the SDK config files. +type sharedConfig struct { + // Credentials values from the config file. Both aws_access_key_id + // and aws_secret_access_key must be provided together in the same file + // to be considered valid. The values will be ignored if not a complete group. + // aws_session_token is an optional field that can be provided if both of the + // other two fields are also provided. + // + // aws_access_key_id + // aws_secret_access_key + // aws_session_token + Creds credentials.Value + + AssumeRole assumeRoleConfig + AssumeRoleSource *sharedConfig + + // Region is the region the SDK should use for looking up AWS service endpoints + // and signing requests. + // + // region + Region string +} + +type sharedConfigFile struct { + Filename string + IniData *ini.File +} + +// loadSharedConfig retrieves the configuration from the list of files +// using the profile provided. The order the files are listed will determine +// precedence. Values in subsequent files will overwrite values defined in +// earlier files. +// +// For example, given two files A and B. Both define credentials. If the order +// of the files are A then B, B's credential values will be used instead of A's. +// +// See sharedConfig.setFromFile for information how the config files +// will be loaded. +func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) { + if len(profile) == 0 { + profile = DefaultSharedConfigProfile + } + + files, err := loadSharedConfigIniFiles(filenames) + if err != nil { + return sharedConfig{}, err + } + + cfg := sharedConfig{} + if err = cfg.setFromIniFiles(profile, files); err != nil { + return sharedConfig{}, err + } + + if len(cfg.AssumeRole.SourceProfile) > 0 { + if err := cfg.setAssumeRoleSource(profile, files); err != nil { + return sharedConfig{}, err + } + } + + return cfg, nil +} + +func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) { + files := make([]sharedConfigFile, 0, len(filenames)) + + for _, filename := range filenames { + if _, err := os.Stat(filename); os.IsNotExist(err) { + // Trim files from the list that don't exist. + continue + } + + f, err := ini.Load(filename) + if err != nil { + return nil, SharedConfigLoadError{Filename: filename} + } + + files = append(files, sharedConfigFile{ + Filename: filename, IniData: f, + }) + } + + return files, nil +} + +func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error { + var assumeRoleSrc sharedConfig + + // Multiple level assume role chains are not support + if cfg.AssumeRole.SourceProfile == origProfile { + assumeRoleSrc = *cfg + assumeRoleSrc.AssumeRole = assumeRoleConfig{} + } else { + err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files) + if err != nil { + return err + } + } + + if len(assumeRoleSrc.Creds.AccessKeyID) == 0 { + return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN} + } + + cfg.AssumeRoleSource = &assumeRoleSrc + + return nil +} + +func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error { + // Trim files from the list that don't exist. + for _, f := range files { + if err := cfg.setFromIniFile(profile, f); err != nil { + if _, ok := err.(SharedConfigProfileNotExistsError); ok { + // Ignore proviles missings + continue + } + return err + } + } + + return nil +} + +// setFromFile loads the configuration from the file using +// the profile provided. A sharedConfig pointer type value is used so that +// multiple config file loadings can be chained. +// +// Only loads complete logically grouped values, and will not set fields in cfg +// for incomplete grouped values in the config. Such as credentials. For example +// if a config file only includes aws_access_key_id but no aws_secret_access_key +// the aws_access_key_id will be ignored. +func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error { + section, err := file.IniData.GetSection(profile) + if err != nil { + // Fallback to to alternate profile name: profile + section, err = file.IniData.GetSection(fmt.Sprintf("profile %s", profile)) + if err != nil { + return SharedConfigProfileNotExistsError{Profile: profile, Err: err} + } + } + + // Shared Credentials + akid := section.Key(accessKeyIDKey).String() + secret := section.Key(secretAccessKey).String() + if len(akid) > 0 && len(secret) > 0 { + cfg.Creds = credentials.Value{ + AccessKeyID: akid, + SecretAccessKey: secret, + SessionToken: section.Key(sessionTokenKey).String(), + ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename), + } + } + + // Assume Role + roleArn := section.Key(roleArnKey).String() + srcProfile := section.Key(sourceProfileKey).String() + if len(roleArn) > 0 && len(srcProfile) > 0 { + cfg.AssumeRole = assumeRoleConfig{ + RoleARN: roleArn, + SourceProfile: srcProfile, + ExternalID: section.Key(externalIDKey).String(), + MFASerial: section.Key(mfaSerialKey).String(), + RoleSessionName: section.Key(roleSessionNameKey).String(), + } + } + + // Region + if v := section.Key(regionKey).String(); len(v) > 0 { + cfg.Region = v + } + + return nil +} + +// SharedConfigLoadError is an error for the shared config file failed to load. +type SharedConfigLoadError struct { + Filename string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigLoadError) Code() string { + return "SharedConfigLoadError" +} + +// Message is the description of the error +func (e SharedConfigLoadError) Message() string { + return fmt.Sprintf("failed to load config file, %s", e.Filename) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigLoadError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigLoadError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigProfileNotExistsError is an error for the shared config when +// the profile was not find in the config file. +type SharedConfigProfileNotExistsError struct { + Profile string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigProfileNotExistsError) Code() string { + return "SharedConfigProfileNotExistsError" +} + +// Message is the description of the error +func (e SharedConfigProfileNotExistsError) Message() string { + return fmt.Sprintf("failed to get profile, %s", e.Profile) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigProfileNotExistsError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigProfileNotExistsError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigAssumeRoleError is an error for the shared config when the +// profile contains assume role information, but that information is invalid +// or not complete. +type SharedConfigAssumeRoleError struct { + RoleARN string +} + +// Code is the short id of the error. +func (e SharedConfigAssumeRoleError) Code() string { + return "SharedConfigAssumeRoleError" +} + +// Message is the description of the error +func (e SharedConfigAssumeRoleError) Message() string { + return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials", + e.RoleARN) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigAssumeRoleError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e SharedConfigAssumeRoleError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} 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 f040f9ce9..7d99f54d1 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 @@ -545,7 +545,7 @@ func (ctx *signingCtx) buildBodyDigest() { } else { hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) } - if ctx.ServiceName == "s3" { + if ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" { ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) } } 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 438218867..c87a0c256 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.2.7" +const SDKVersion = "1.4.6" diff --git a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go index 2b279e659..b4ad7405c 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go @@ -14,9 +14,9 @@ import ( // normalized endpoint and signing region. If the endpoint is not an empty string // the service name and region will be used to look up the service's API endpoint. // If the endpoint is provided the scheme will be added if it is not present. -func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (normEndpoint, signingRegion string) { +func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL, useDualStack bool) (normEndpoint, signingRegion string) { if endpoint == "" { - return EndpointForRegion(serviceName, region, disableSSL) + return EndpointForRegion(serviceName, region, disableSSL, useDualStack) } return AddScheme(endpoint, disableSSL), "" @@ -24,12 +24,17 @@ func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (n // EndpointForRegion returns an endpoint and its signing region for a service and region. // if the service and region pair are not found endpoint and signingRegion will be empty. -func EndpointForRegion(svcName, region string, disableSSL bool) (endpoint, signingRegion string) { +func EndpointForRegion(svcName, region string, disableSSL, useDualStack bool) (endpoint, signingRegion string) { + dualStackField := "" + if useDualStack { + dualStackField = "/dualstack" + } + derivedKeys := []string{ - region + "/" + svcName, - region + "/*", - "*/" + svcName, - "*/*", + region + "/" + svcName + dualStackField, + region + "/*" + dualStackField, + "*/" + svcName + dualStackField, + "*/*" + dualStackField, } for _, key := range derivedKeys { diff --git a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json index 5f4991c2b..c5bf3c7c3 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json +++ b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json @@ -65,6 +65,9 @@ "*/s3": { "endpoint": "s3-{region}.amazonaws.com" }, + "*/s3/dualstack": { + "endpoint": "s3.dualstack.{region}.amazonaws.com" + }, "us-east-1/s3": { "endpoint": "s3.amazonaws.com" }, diff --git a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go index e995315ab..a81d158c3 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go +++ b/vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go @@ -48,6 +48,9 @@ var endpointsMap = endpointStruct{ "*/s3": { Endpoint: "s3-{region}.amazonaws.com", }, + "*/s3/dualstack": { + Endpoint: "s3.dualstack.{region}.amazonaws.com", + }, "*/sts": { Endpoint: "sts.amazonaws.com", SigningRegion: "us-east-1", diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go index 68e344d1f..bb0dae97a 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go @@ -1,4 +1,4 @@ -// Package ec2query provides serialisation of AWS EC2 requests and responses. +// Package ec2query provides serialization of AWS EC2 requests and responses. package ec2query //go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/ec2.json build_test.go diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go index 7ad674278..4504efe2b 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go @@ -1,4 +1,4 @@ -// Package jsonutil provides JSON serialisation of AWS requests and responses. +// Package jsonutil provides JSON serialization of AWS requests and responses. package jsonutil import ( @@ -160,7 +160,7 @@ func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].Strin func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { buf.WriteString("{") - var sv sortedValues = value.MapKeys() + sv := sortedValues(value.MapKeys()) sort.Sort(sv) for i, k := range sv { diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go index 7aff0e0fa..d5490cd7f 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go @@ -1,4 +1,4 @@ -// Package jsonrpc provides JSON RPC utilities for serialisation of AWS +// Package jsonrpc provides JSON RPC utilities for serialization of AWS // requests and responses. package jsonrpc diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go index 56d69db05..c705481c3 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go @@ -1,4 +1,4 @@ -// Package query provides serialisation of AWS query requests, and responses. +// Package query provides serialization of AWS query requests, and responses. package query //go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go index c74088bfe..c74b97e17 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go @@ -1,4 +1,4 @@ -// Package restxml provides RESTful XML serialisation of AWS +// Package restxml provides RESTful XML serialization of AWS // requests and responses. package restxml diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go index ceb4132c5..221029baf 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go @@ -1,4 +1,4 @@ -// Package xmlutil provides XML serialisation of AWS requests and responses. +// Package xmlutil provides XML serialization of AWS requests and responses. package xmlutil import ( diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/doc.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/doc.go index 34476569e..b603b5840 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/doc.go @@ -31,7 +31,12 @@ // // Marshal Go value type for DynamoDB.PutItem: // -// sess := session.New() +// sess, err := session.NewSession() +// if err != nil { +// fmt.Println("Failed create session", err) +// return +// } +// // svc := dynamodb.New(sess) // item, err := dynamodbattribute.MarshalMap(r) // if err != nil { diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode.go index 6670c5c18..dac9ef8d1 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode.go +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode.go @@ -9,7 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/dynamodb" ) -// A Marshaler is an interface to provide custom marshalling of Go value types +// A Marshaler is an interface to provide custom marshaling of Go value types // to AttributeValues. Use this to provide custom logic determining how a // Go Value type should be marshaled. // diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index 170405fa1..0b4c51a81 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -157,7 +157,7 @@ func (c *EC2) AllocateHostsRequest(input *AllocateHostsInput) (req *request.Requ return } -// Allocates a Dedicated host to your account. At minimum you need to specify +// Allocates a Dedicated Host to your account. At minimum you need to specify // the instance size type, Availability Zone, and quantity of hosts you want // to allocate. func (c *EC2) AllocateHosts(input *AllocateHostsInput) (*AllocateHostsOutput, error) { @@ -983,9 +983,8 @@ func (c *EC2) CancelConversionTaskRequest(input *CancelConversionTaskInput) (req // is in the process of transferring the final disk image, the command fails // and returns an exception. // -// For more information, see Using the Command Line Tools to Import Your Virtual -// Machine to Amazon EC2 (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UploadingYourInstancesandVolumes.html) -// in the Amazon Elastic Compute Cloud User Guide. +// For more information, see Importing a Virtual Machine Using the Amazon EC2 +// CLI (http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ec2-cli-vmimport-export.html). func (c *EC2) CancelConversionTask(input *CancelConversionTaskInput) (*CancelConversionTaskOutput, error) { req, out := c.CancelConversionTaskRequest(input) err := req.Send() @@ -1416,6 +1415,9 @@ func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *request.Reques // To copy an encrypted snapshot that has been shared from another account, // you must have permissions for the CMK used to encrypt the snapshot. // +// Snapshots created by the CopySnapshot action have an arbitrary volume +// ID that should not be used for any purpose. +// // For more information, see Copying an Amazon EBS Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-copy-snapshot.html) // in the Amazon Elastic Compute Cloud User Guide. func (c *EC2) CopySnapshot(input *CopySnapshotInput) (*CopySnapshotOutput, error) { @@ -1546,17 +1548,20 @@ func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *requ // domain-name-servers - The IP addresses of up to four domain name servers, // or AmazonProvidedDNS. The default DHCP option set specifies AmazonProvidedDNS. // If specifying more than one domain name server, specify the IP addresses -// in a single parameter, separated by commas. +// in a single parameter, separated by commas. If you want your instance to +// receive a custom DNS hostname as specified in domain-name, you must set domain-name-servers +// to a custom DNS server. // // domain-name - If you're using AmazonProvidedDNS in "us-east-1", specify // "ec2.internal". If you're using AmazonProvidedDNS in another region, specify // "region.compute.internal" (for example, "ap-northeast-1.compute.internal"). -// Otherwise, specify a domain name (for example, "MyCompany.com"). Important: -// Some Linux operating systems accept multiple domain names separated by spaces. -// However, Windows and other Linux operating systems treat the value as a single -// domain, which results in unexpected behavior. If your DHCP options set is -// associated with a VPC that has instances with multiple operating systems, -// specify only one domain name. +// Otherwise, specify a domain name (for example, "MyCompany.com"). This value +// is used to complete unqualified DNS hostnames. Important: Some Linux operating +// systems accept multiple domain names separated by spaces. However, Windows +// and other Linux operating systems treat the value as a single domain, which +// results in unexpected behavior. If your DHCP options set is associated with +// a VPC that has instances with multiple operating systems, specify only one +// domain name. // // ntp-servers - The IP addresses of up to four Network Time Protocol (NTP) // servers. @@ -1739,8 +1744,8 @@ func (c *EC2) CreateInstanceExportTaskRequest(input *CreateInstanceExportTaskInp // // For information about the supported operating systems, image formats, and // known limitations for the types of instances you can export, see Exporting -// EC2 Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExportingEC2Instances.html) -// in the Amazon Elastic Compute Cloud User Guide. +// an Instance as a VM Using VM Import/Export (http://docs.aws.amazon.com/vm-import/latest/userguide/vmexport.html) +// in the VM Import/Export User Guide. func (c *EC2) CreateInstanceExportTask(input *CreateInstanceExportTaskInput) (*CreateInstanceExportTaskOutput, error) { req, out := c.CreateInstanceExportTaskRequest(input) err := req.Send() @@ -4699,9 +4704,7 @@ func (c *EC2) DescribeConversionTasksRequest(input *DescribeConversionTasksInput } // Describes one or more of your conversion tasks. For more information, see -// Using the Command Line Tools to Import Your Virtual Machine to Amazon EC2 -// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UploadingYourInstancesandVolumes.html) -// in the Amazon Elastic Compute Cloud User Guide. +// the VM Import/Export User Guide (http://docs.aws.amazon.com/vm-import/latest/userguide/). // // For information about the import manifest referenced by this API action, // see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). @@ -4912,6 +4915,111 @@ func (c *EC2) DescribeFlowLogs(input *DescribeFlowLogsInput) (*DescribeFlowLogsO return out, err } +const opDescribeHostReservationOfferings = "DescribeHostReservationOfferings" + +// DescribeHostReservationOfferingsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeHostReservationOfferings operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeHostReservationOfferings method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeHostReservationOfferingsRequest method. +// req, resp := client.DescribeHostReservationOfferingsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeHostReservationOfferingsRequest(input *DescribeHostReservationOfferingsInput) (req *request.Request, output *DescribeHostReservationOfferingsOutput) { + op := &request.Operation{ + Name: opDescribeHostReservationOfferings, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeHostReservationOfferingsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeHostReservationOfferingsOutput{} + req.Data = output + return +} + +// Describes the Dedicated Host Reservations that are available to purchase. +// +// The results describe all the Dedicated Host Reservation offerings, including +// offerings that may not match the instance family and region of your Dedicated +// Hosts. When purchasing an offering, ensure that the the instance family and +// region of the offering matches that of the Dedicated Host/s it will be associated +// with. For an overview of supported instance types, see Dedicated Hosts Overview +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-hosts-overview.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DescribeHostReservationOfferings(input *DescribeHostReservationOfferingsInput) (*DescribeHostReservationOfferingsOutput, error) { + req, out := c.DescribeHostReservationOfferingsRequest(input) + err := req.Send() + return out, err +} + +const opDescribeHostReservations = "DescribeHostReservations" + +// DescribeHostReservationsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeHostReservations operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeHostReservations method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeHostReservationsRequest method. +// req, resp := client.DescribeHostReservationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) DescribeHostReservationsRequest(input *DescribeHostReservationsInput) (req *request.Request, output *DescribeHostReservationsOutput) { + op := &request.Operation{ + Name: opDescribeHostReservations, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeHostReservationsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeHostReservationsOutput{} + req.Data = output + return +} + +// Describes Dedicated Host Reservations which are associated with Dedicated +// Hosts in your account. +func (c *EC2) DescribeHostReservations(input *DescribeHostReservationsInput) (*DescribeHostReservationsOutput, error) { + req, out := c.DescribeHostReservationsRequest(input) + err := req.Send() + return out, err +} + const opDescribeHosts = "DescribeHosts" // DescribeHostsRequest generates a "aws/request.Request" representing the @@ -4953,11 +5061,11 @@ func (c *EC2) DescribeHostsRequest(input *DescribeHostsInput) (req *request.Requ return } -// Describes one or more of your Dedicated hosts. +// Describes one or more of your Dedicated Hosts. // -// The results describe only the Dedicated hosts in the region you're currently -// using. All listed instances consume capacity on your Dedicated host. Dedicated -// hosts that have recently been released will be listed with the state released. +// The results describe only the Dedicated Hosts in the region you're currently +// using. All listed instances consume capacity on your Dedicated Host. Dedicated +// Hosts that have recently been released will be listed with the state released. func (c *EC2) DescribeHosts(input *DescribeHostsInput) (*DescribeHostsOutput, error) { req, out := c.DescribeHostsRequest(input) err := req.Send() @@ -8220,9 +8328,10 @@ func (c *EC2) DetachVolumeRequest(input *DetachVolumeInput) (req *request.Reques // Detaches an EBS volume from an instance. Make sure to unmount any file systems // on the device within your operating system before detaching the volume. Failure -// to do so results in the volume being stuck in a busy state while detaching. -// -// If an Amazon EBS volume is the root device of an instance, it can't be detached +// to do so can result in the volume becoming stuck in the busy state while +// detaching. If this happens, detachment can be delayed indefinitely until +// you unmount the volume, force detachment, reboot the instance, or all three. +// If an EBS volume is the root device of an instance, it can't be detached // while the instance is running. To detach the root volume, stop the instance // first. // @@ -8884,6 +8993,59 @@ func (c *EC2) GetConsoleScreenshot(input *GetConsoleScreenshotInput) (*GetConsol return out, err } +const opGetHostReservationPurchasePreview = "GetHostReservationPurchasePreview" + +// GetHostReservationPurchasePreviewRequest generates a "aws/request.Request" representing the +// client's request for the GetHostReservationPurchasePreview operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetHostReservationPurchasePreview method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetHostReservationPurchasePreviewRequest method. +// req, resp := client.GetHostReservationPurchasePreviewRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) GetHostReservationPurchasePreviewRequest(input *GetHostReservationPurchasePreviewInput) (req *request.Request, output *GetHostReservationPurchasePreviewOutput) { + op := &request.Operation{ + Name: opGetHostReservationPurchasePreview, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetHostReservationPurchasePreviewInput{} + } + + req = c.newRequest(op, input, output) + output = &GetHostReservationPurchasePreviewOutput{} + req.Data = output + return +} + +// Preview a reservation purchase with configurations that match those of your +// Dedicated Host. You must have active Dedicated Hosts in your account before +// you purchase a reservation. +// +// This is a preview of the PurchaseHostReservation action and does not result +// in the offering being purchased. +func (c *EC2) GetHostReservationPurchasePreview(input *GetHostReservationPurchasePreviewInput) (*GetHostReservationPurchasePreviewOutput, error) { + req, out := c.GetHostReservationPurchasePreviewRequest(input) + err := req.Send() + return out, err +} + const opGetPasswordData = "GetPasswordData" // GetPasswordDataRequest generates a "aws/request.Request" representing the @@ -8987,7 +9149,9 @@ func (c *EC2) ImportImageRequest(input *ImportImageInput) (req *request.Request, } // Import single or multi-volume disk images or EBS snapshots into an Amazon -// Machine Image (AMI). +// Machine Image (AMI). For more information, see Importing a VM as an Image +// Using VM Import/Export (http://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html) +// in the VM Import/Export User Guide. func (c *EC2) ImportImage(input *ImportImageInput) (*ImportImageOutput, error) { req, out := c.ImportImageRequest(input) err := req.Send() @@ -9037,11 +9201,8 @@ func (c *EC2) ImportInstanceRequest(input *ImportInstanceInput) (req *request.Re // Creates an import instance task using metadata from the specified disk image. // ImportInstance only supports single-volume VMs. To import multi-volume VMs, -// use ImportImage. After importing the image, you then upload it using the -// ec2-import-volume command in the EC2 command line tools. For more information, -// see Using the Command Line Tools to Import Your Virtual Machine to Amazon -// EC2 (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UploadingYourInstancesandVolumes.html) -// in the Amazon Elastic Compute Cloud User Guide. +// use ImportImage. For more information, see Importing a Virtual Machine Using +// the Amazon EC2 CLI (http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ec2-cli-vmimport-export.html). // // For information about the import manifest referenced by this API action, // see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). @@ -9195,12 +9356,8 @@ func (c *EC2) ImportVolumeRequest(input *ImportVolumeInput) (req *request.Reques return } -// Creates an import volume task using metadata from the specified disk image. -// After importing the image, you then upload it using the ec2-import-volume -// command in the Amazon EC2 command-line interface (CLI) tools. For more information, -// see Using the Command Line Tools to Import Your Virtual Machine to Amazon -// EC2 (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UploadingYourInstancesandVolumes.html) -// in the Amazon Elastic Compute Cloud User Guide. +// Creates an import volume task using metadata from the specified disk image.For +// more information, see Importing Disks to Amazon EBS (http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/importing-your-volumes-into-amazon-ebs.html). // // For information about the import manifest referenced by this API action, // see VM Import Manifest (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/manifest.html). @@ -9251,9 +9408,9 @@ func (c *EC2) ModifyHostsRequest(input *ModifyHostsInput) (req *request.Request, return } -// Modify the auto-placement setting of a Dedicated host. When auto-placement +// Modify the auto-placement setting of a Dedicated Host. When auto-placement // is enabled, AWS will place instances that you launch with a tenancy of host, -// but without targeting a specific host ID, onto any available Dedicated host +// but without targeting a specific host ID, onto any available Dedicated Host // in your account which has auto-placement enabled. When auto-placement is // disabled, you need to provide a host ID if you want the instance to launch // onto a specific host. If no host ID is provided, the instance will be launched @@ -9439,6 +9596,11 @@ func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req // // AWS Marketplace product codes cannot be modified. Images with an AWS Marketplace // product code cannot be made public. +// +// The SriovNetSupport enhanced networking attribute cannot be changed using +// this command. Instead, enable SriovNetSupport on an instance and create an +// AMI from the instance. This will result in an image with SriovNetSupport +// enabled. func (c *EC2) ModifyImageAttribute(input *ModifyImageAttributeInput) (*ModifyImageAttributeOutput, error) { req, out := c.ModifyImageAttributeRequest(input) err := req.Send() @@ -9545,7 +9707,7 @@ func (c *EC2) ModifyInstancePlacementRequest(input *ModifyInstancePlacementInput // the instance tenancy setting. // // Instance affinity is disabled by default. When instance affinity is host -// and it is not associated with a specific Dedicated host, the next time it +// and it is not associated with a specific Dedicated Host, the next time it // is launched it will automatically be associated with the host it lands on. // This relationship will persist if the instance is stopped/started, or rebooted. // @@ -10060,12 +10222,15 @@ func (c *EC2) ModifyVpcPeeringConnectionOptionsRequest(input *ModifyVpcPeeringCo // Enable/disable communication over the peering connection between instances // in your VPC and an EC2-Classic instance that's linked to the peer VPC. // +// Enable/disable a local VPC to resolve public DNS hostnames to private +// IP addresses when queried from instances in the peer VPC. +// // If the peered VPCs are in different accounts, each owner must initiate -// a separate request to enable or disable communication in either direction, -// depending on whether their VPC was the requester or accepter for the VPC -// peering connection. If the peered VPCs are in the same account, you can modify -// the requester and accepter options in the same request. To confirm which -// VPC is the accepter and requester for a VPC peering connection, use the DescribeVpcPeeringConnections +// a separate request to modify the peering connection options, depending on +// whether their VPC was the requester or accepter for the VPC peering connection. +// If the peered VPCs are in the same account, you can modify the requester +// and accepter options in the same request. To confirm which VPC is the accepter +// and requester for a VPC peering connection, use the DescribeVpcPeeringConnections // command. func (c *EC2) ModifyVpcPeeringConnectionOptions(input *ModifyVpcPeeringConnectionOptionsInput) (*ModifyVpcPeeringConnectionOptionsOutput, error) { req, out := c.ModifyVpcPeeringConnectionOptionsRequest(input) @@ -10177,6 +10342,57 @@ func (c *EC2) MoveAddressToVpc(input *MoveAddressToVpcInput) (*MoveAddressToVpcO return out, err } +const opPurchaseHostReservation = "PurchaseHostReservation" + +// PurchaseHostReservationRequest generates a "aws/request.Request" representing the +// client's request for the PurchaseHostReservation operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PurchaseHostReservation method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PurchaseHostReservationRequest method. +// req, resp := client.PurchaseHostReservationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *EC2) PurchaseHostReservationRequest(input *PurchaseHostReservationInput) (req *request.Request, output *PurchaseHostReservationOutput) { + op := &request.Operation{ + Name: opPurchaseHostReservation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PurchaseHostReservationInput{} + } + + req = c.newRequest(op, input, output) + output = &PurchaseHostReservationOutput{} + req.Data = output + return +} + +// Purchase a reservation with configurations that match those of your Dedicated +// Host. You must have active Dedicated Hosts in your account before you purchase +// a reservation. This action results in the specified reservation being purchased +// and charged to your account. +func (c *EC2) PurchaseHostReservation(input *PurchaseHostReservationInput) (*PurchaseHostReservationOutput, error) { + req, out := c.PurchaseHostReservationRequest(input) + err := req.Send() + return out, err +} + const opPurchaseReservedInstancesOffering = "PurchaseReservedInstancesOffering" // PurchaseReservedInstancesOfferingRequest generates a "aws/request.Request" representing the @@ -10590,13 +10806,13 @@ func (c *EC2) ReleaseHostsRequest(input *ReleaseHostsInput) (req *request.Reques return } -// When you no longer want to use a Dedicated host it can be released. On-Demand -// billing is stopped and the host goes into released state. The host ID of -// Dedicated hosts that have been released can no longer be specified in another -// request, e.g., ModifyHosts. You must stop or terminate all instances on a -// host before it can be released. +// When you no longer want to use an On-Demand Dedicated Host it can be released. +// On-Demand billing is stopped and the host goes into released state. The host +// ID of Dedicated Hosts that have been released can no longer be specified +// in another request, e.g., ModifyHosts. You must stop or terminate all instances +// on a host before it can be released. // -// When Dedicated hosts are released, it make take some time for them to stop +// When Dedicated Hosts are released, it make take some time for them to stop // counting toward your limit and you may receive capacity errors when trying // to allocate new Dedicated hosts. Try waiting a few minutes, and then try // again. @@ -12049,13 +12265,13 @@ type AllocateHostsInput struct { _ struct{} `type:"structure"` // This is enabled by default. This property allows instances to be automatically - // placed onto available Dedicated hosts, when you are launching instances without + // placed onto available Dedicated Hosts, when you are launching instances without // specifying a host ID. // // Default: Enabled AutoPlacement *string `locationName:"autoPlacement" type:"string" enum:"AutoPlacement"` - // The Availability Zone for the Dedicated hosts. + // The Availability Zone for the Dedicated Hosts. AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` // Unique, case-sensitive identifier you provide to ensure idempotency of the @@ -12063,12 +12279,12 @@ type AllocateHostsInput struct { // in the Amazon Elastic Compute Cloud User Guide. ClientToken *string `locationName:"clientToken" type:"string"` - // Specify the instance type that you want your Dedicated hosts to be configured + // Specify the instance type that you want your Dedicated Hosts to be configured // for. When you specify the instance type, that is the only instance type that // you can launch onto that host. InstanceType *string `locationName:"instanceType" type:"string" required:"true"` - // The number of Dedicated hosts you want to allocate to your account with these + // The number of Dedicated Hosts you want to allocate to your account with these // parameters. Quantity *int64 `locationName:"quantity" type:"integer" required:"true"` } @@ -12106,7 +12322,7 @@ func (s *AllocateHostsInput) Validate() error { type AllocateHostsOutput struct { _ struct{} `type:"structure"` - // The ID of the allocated Dedicated host. This is used when you want to launch + // The ID of the allocated Dedicated Host. This is used when you want to launch // an instance onto a specific host. HostIds []*string `locationName:"hostIdSet" locationNameList:"item" type:"list"` } @@ -12819,7 +13035,8 @@ type AuthorizeSecurityGroupIngressInput struct { IpPermissions []*IpPermission `locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). - // (VPC only) Use -1 to specify all. + // (VPC only) Use -1 to specify all traffic. If you specify -1, traffic on all + // ports is allowed, regardless of any ports you specify. IpProtocol *string `type:"string"` // [EC2-Classic, default VPC] The name of the source security group. You can't @@ -12913,14 +13130,14 @@ func (s AvailabilityZoneMessage) GoString() string { return s.String() } -// The capacity information for instances launched onto the Dedicated host. +// The capacity information for instances launched onto the Dedicated Host. type AvailableCapacity struct { _ struct{} `type:"structure"` - // The total number of instances that the Dedicated host supports. + // The total number of instances that the Dedicated Host supports. AvailableInstanceCapacity []*InstanceCapacity `locationName:"availableInstanceCapacity" locationNameList:"item" type:"list"` - // The number of vCPUs available on the Dedicated host. + // The number of vCPUs available on the Dedicated Host. AvailableVCpus *int64 `locationName:"availableVCpus" type:"integer"` } @@ -17703,31 +17920,157 @@ func (s DescribeFlowLogsOutput) GoString() string { return s.String() } +type DescribeHostReservationOfferingsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // instance-family - The instance family of the offering (e.g., m4). + // + // payment-option - The payment option (No Upfront | Partial Upfront | All + // Upfront). + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // This is the maximum duration of the reservation you'd like to purchase, specified + // in seconds.Reservations are available in 1, 3, and 5 year terms. The number + // of seconds specified must be the number of seconds in a year (365x24x60x60) + // times one of the supported durations (1, 3, or 5). For example, specify 157680000 + // for 5 years. + MaxDuration *int64 `type:"integer"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // nextToken value. This value can be between 5 and 500; if maxResults is given + // a larger value than 500, you will receive an error. + MaxResults *int64 `type:"integer"` + + // This is the minimum duration of the reservation you'd like to purchase, specified + // in seconds. Reservations are available in 1, 3, and 5 year terms. The number + // of seconds specified must be the number of seconds in a year (365x24x60x60) + // times one of the supported durations (1, 3, or 5). For example, specify 94608000 + // for 3 years. + MinDuration *int64 `type:"integer"` + + // The token to use to retrieve the next page of results. + NextToken *string `type:"string"` + + // The ID of the reservation offering. + OfferingId *string `type:"string"` +} + +// String returns the string representation +func (s DescribeHostReservationOfferingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationOfferingsInput) GoString() string { + return s.String() +} + +type DescribeHostReservationOfferingsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the offerings. + OfferingSet []*HostOffering `locationName:"offeringSet" type:"list"` +} + +// String returns the string representation +func (s DescribeHostReservationOfferingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationOfferingsOutput) GoString() string { + return s.String() +} + +type DescribeHostReservationsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // instance-family - The instance family (e.g., m4). + // + // payment-option - The payment option (No Upfront | Partial Upfront | All + // Upfront). + // + // state - The state of the reservation (payment-pending | payment-failed + // | active | retired). + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // One or more host reservation IDs. + HostReservationIdSet []*string `locationNameList:"item" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // nextToken value. This value can be between 5 and 500; if maxResults is given + // a larger value than 500, you will receive an error. + MaxResults *int64 `type:"integer"` + + // The token to use to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeHostReservationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationsInput) GoString() string { + return s.String() +} + +type DescribeHostReservationsOutput struct { + _ struct{} `type:"structure"` + + // Details about the reservation's configuration. + HostReservationSet []*HostReservation `locationName:"hostReservationSet" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeHostReservationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeHostReservationsOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeHosts. type DescribeHostsInput struct { _ struct{} `type:"structure"` // One or more filters. // - // instance-type - The instance type size that the Dedicated host is configured + // instance-type - The instance type size that the Dedicated Host is configured // to support. // // auto-placement - Whether auto-placement is enabled or disabled (on | // off). // - // host-reservation-id - The ID of the reservation associated with this - // host. + // host-reservation-id - The ID of the reservation assigned to this host. // // client-token - The idempotency token you provided when you launched the // instance // - // state- The allocation state of the Dedicated host (available | under-assessment + // state- The allocation state of the Dedicated Host (available | under-assessment // | permanent-failure | released | released-permanent-failure). // // availability-zone - The Availability Zone of the host. Filter []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"` - // The IDs of the Dedicated hosts. The IDs are used for targeted instance launches. + // The IDs of the Dedicated Hosts. The IDs are used for targeted instance launches. HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list"` // The maximum number of results to return for the request in a single page. @@ -17755,7 +18098,7 @@ func (s DescribeHostsInput) GoString() string { type DescribeHostsOutput struct { _ struct{} `type:"structure"` - // Information about the Dedicated hosts. + // Information about the Dedicated Hosts. Hosts []*Host `locationName:"hostSet" locationNameList:"item" type:"list"` // The token to use to retrieve the next page of results. This value is null @@ -17777,7 +18120,7 @@ func (s DescribeHostsOutput) GoString() string { type DescribeIdFormatInput struct { _ struct{} `type:"structure"` - // The type of resource. + // The type of resource: instance | reservation | snapshot | volume Resource *string `type:"string"` } @@ -17817,7 +18160,7 @@ type DescribeIdentityIdFormatInput struct { // user. PrincipalArn *string `locationName:"principalArn" type:"string" required:"true"` - // The type of resource. + // The type of resource: instance | reservation | snapshot | volume Resource *string `locationName:"resource" type:"string"` } @@ -17998,7 +18341,9 @@ type DescribeImagesInput struct { // // name - The name of the AMI (provided during image creation). // - // owner-alias - The AWS account alias (for example, amazon). + // owner-alias - String value from an Amazon-maintained list (amazon | aws-marketplace + // | microsoft) of snapshot owners. Not to be confused with the user-configured + // AWS account alias, which is set from the IAM console. // // owner-id - The AWS account ID of the image owner. // @@ -18040,10 +18385,10 @@ type DescribeImagesInput struct { // Default: Describes all images available to you. ImageIds []*string `locationName:"ImageId" locationNameList:"ImageId" type:"list"` - // Filters the images by the owner. Specify an AWS account ID, amazon (owner - // is Amazon), aws-marketplace (owner is AWS Marketplace), self (owner is the - // sender of the request). Omitting this option returns all images for which - // you have launch permissions, regardless of ownership. + // Filters the images by the owner. Specify an AWS account ID, self (owner is + // the sender of the request), or an AWS owner alias (valid values are amazon + // | aws-marketplace | microsoft). Omitting this option returns all images for + // which you have launch permissions, regardless of ownership. Owners []*string `locationName:"Owner" locationNameList:"Owner" type:"list"` } @@ -18415,7 +18760,7 @@ type DescribeInstancesInput struct { // One or more filters. // // affinity - The affinity setting for an instance running on a Dedicated - // host (default | host). + // Host (default | host). // // architecture - The instance architecture (i386 | x86_64). // @@ -18446,7 +18791,7 @@ type DescribeInstancesInput struct { // group-name - The name of the security group for the instance. EC2-Classic // only. // - // host-Id - The ID of the Dedicated host on which the instance is running, + // host-id - The ID of the Dedicated Host on which the instance is running, // if applicable. // // hypervisor - The hypervisor type of the instance (ovm | xen). @@ -20271,8 +20616,9 @@ type DescribeSnapshotsInput struct { // // description - A description of the snapshot. // - // owner-alias - The AWS account alias (for example, amazon) that owns the - // snapshot. + // owner-alias - Value from an Amazon-maintained list (amazon | aws-marketplace + // | microsoft) of snapshot owners. Not to be confused with the user-configured + // AWS account alias, which is set from the IAM consolew. // // owner-id - The ID of the AWS account that owns the snapshot. // @@ -23352,6 +23698,71 @@ func (s GetConsoleScreenshotOutput) GoString() string { return s.String() } +type GetHostReservationPurchasePreviewInput struct { + _ struct{} `type:"structure"` + + // The ID/s of the Dedicated Host/s that the reservation will be associated + // with. + HostIdSet []*string `locationNameList:"item" type:"list" required:"true"` + + // The offering ID of the reservation. + OfferingId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s GetHostReservationPurchasePreviewInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostReservationPurchasePreviewInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHostReservationPurchasePreviewInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHostReservationPurchasePreviewInput"} + if s.HostIdSet == nil { + invalidParams.Add(request.NewErrParamRequired("HostIdSet")) + } + if s.OfferingId == nil { + invalidParams.Add(request.NewErrParamRequired("OfferingId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type GetHostReservationPurchasePreviewOutput struct { + _ struct{} `type:"structure"` + + // The currency in which the totalUpfrontPrice and totalHourlyPrice amounts + // are specified. At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The purchase information of the Dedicated Host Reservation and the Dedicated + // Hosts associated with it. + Purchase []*Purchase `locationName:"purchase" type:"list"` + + // The potential total hourly price of the reservation per hour. + TotalHourlyPrice *string `locationName:"totalHourlyPrice" type:"string"` + + // The potential total upfront price. This is billed immediately. + TotalUpfrontPrice *string `locationName:"totalUpfrontPrice" type:"string"` +} + +// String returns the string representation +func (s GetHostReservationPurchasePreviewOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostReservationPurchasePreviewOutput) GoString() string { + return s.String() +} + // Contains the parameters for GetPasswordData. type GetPasswordDataInput struct { _ struct{} `type:"structure"` @@ -23465,17 +23876,17 @@ func (s HistoryRecord) GoString() string { return s.String() } -// Describes the properties of the Dedicated host. +// Describes the properties of the Dedicated Host. type Host struct { _ struct{} `type:"structure"` // Whether auto-placement is on or off. AutoPlacement *string `locationName:"autoPlacement" type:"string" enum:"AutoPlacement"` - // The Availability Zone of the Dedicated host. + // The Availability Zone of the Dedicated Host. AvailabilityZone *string `locationName:"availabilityZone" type:"string"` - // The number of new instances that can be launched onto the Dedicated host. + // The number of new instances that can be launched onto the Dedicated Host. AvailableCapacity *AvailableCapacity `locationName:"availableCapacity" type:"structure"` // Unique, case-sensitive identifier you provide to ensure idempotency of the @@ -23483,20 +23894,20 @@ type Host struct { // in the Amazon Elastic Compute Cloud User Guide. ClientToken *string `locationName:"clientToken" type:"string"` - // The ID of the Dedicated host. + // The ID of the Dedicated Host. HostId *string `locationName:"hostId" type:"string"` - // The hardware specifications of the Dedicated host. + // The hardware specifications of the Dedicated Host. HostProperties *HostProperties `locationName:"hostProperties" type:"structure"` - // The reservation ID of the Dedicated host. This returns a null response if - // the Dedicated host doesn't have an associated reservation. + // The reservation ID of the Dedicated Host. This returns a null response if + // the Dedicated Host doesn't have an associated reservation. HostReservationId *string `locationName:"hostReservationId" type:"string"` - // The IDs and instance type that are currently running on the Dedicated host. + // The IDs and instance type that are currently running on the Dedicated Host. Instances []*HostInstance `locationName:"instances" locationNameList:"item" type:"list"` - // The Dedicated host's state. + // The Dedicated Host's state. State *string `locationName:"state" type:"string" enum:"AllocationState"` } @@ -23510,11 +23921,11 @@ func (s Host) GoString() string { return s.String() } -// Describes an instance running on a Dedicated host. +// Describes an instance running on a Dedicated Host. type HostInstance struct { _ struct{} `type:"structure"` - // the IDs of instances that are running on the Dedicated host. + // the IDs of instances that are running on the Dedicated Host. InstanceId *string `locationName:"instanceId" type:"string"` // The instance type size (for example, m3.medium) of the running instance. @@ -23531,20 +23942,56 @@ func (s HostInstance) GoString() string { return s.String() } -// Describes properties of a Dedicated host. +// Details about the Dedicated Host Reservation offering. +type HostOffering struct { + _ struct{} `type:"structure"` + + // The currency of the offering. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The duration of the offering (in seconds). + Duration *int64 `locationName:"duration" type:"integer"` + + // The hourly price of the offering. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance family that the offering covers. + InstanceFamily *string `locationName:"instanceFamily" type:"string"` + + // The ID of the offering. + OfferingId *string `locationName:"offeringId" type:"string"` + + // The available payment option. + PaymentOption *string `locationName:"paymentOption" type:"string" enum:"PaymentOption"` + + // The upfront price of the offering. Does not apply to No Upfront offerings. + UpfrontPrice *string `locationName:"upfrontPrice" type:"string"` +} + +// String returns the string representation +func (s HostOffering) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostOffering) GoString() string { + return s.String() +} + +// Describes properties of a Dedicated Host. type HostProperties struct { _ struct{} `type:"structure"` - // The number of cores on the Dedicated host. + // The number of cores on the Dedicated Host. Cores *int64 `locationName:"cores" type:"integer"` - // The instance type size that the Dedicated host supports (for example, m3.medium). + // The instance type size that the Dedicated Host supports (for example, m3.medium). InstanceType *string `locationName:"instanceType" type:"string"` - // The number of sockets on the Dedicated host. + // The number of sockets on the Dedicated Host. Sockets *int64 `locationName:"sockets" type:"integer"` - // The number of vCPUs on the Dedicated host. + // The number of vCPUs on the Dedicated Host. TotalVCpus *int64 `locationName:"totalVCpus" type:"integer"` } @@ -23558,6 +24005,65 @@ func (s HostProperties) GoString() string { return s.String() } +// Details about the Dedicated Host Reservation and associated Dedicated Hosts. +type HostReservation struct { + _ struct{} `type:"structure"` + + // The number of Dedicated Hosts the reservation is associated with. + Count *int64 `locationName:"count" type:"integer"` + + // The currency in which the upfrontPrice and hourlyPrice amounts are specified. + // At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The length of the reservation's term, specified in seconds. Can be 31536000 + // (1 year) | 94608000 (3 years) | 157680000 (5 years). + Duration *int64 `locationName:"duration" type:"integer"` + + // The date and time that the reservation ends. + End *time.Time `locationName:"end" type:"timestamp" timestampFormat:"iso8601"` + + // The IDs of the Dedicated Hosts associated with the reservation. + HostIdSet []*string `locationName:"hostIdSet" locationNameList:"item" type:"list"` + + // The ID of the reservation that specifies the associated Dedicated Hosts. + HostReservationId *string `locationName:"hostReservationId" type:"string"` + + // The hourly price of the reservation. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance family of the Dedicated Host Reservation. The instance family + // on the Dedicated Host must be the same in order for it to benefit from the + // reservation. + InstanceFamily *string `locationName:"instanceFamily" type:"string"` + + // The ID of the reservation. This remains the same regardless of which Dedicated + // Hosts are associated with it. + OfferingId *string `locationName:"offeringId" type:"string"` + + // The payment option selected for this reservation. + PaymentOption *string `locationName:"paymentOption" type:"string" enum:"PaymentOption"` + + // The date and time that the reservation started. + Start *time.Time `locationName:"start" type:"timestamp" timestampFormat:"iso8601"` + + // The state of the reservation. + State *string `locationName:"state" type:"string" enum:"ReservationState"` + + // The upfront price of the reservation. + UpfrontPrice *string `locationName:"upfrontPrice" type:"string"` +} + +// String returns the string representation +func (s HostReservation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostReservation) GoString() string { + return s.String() +} + // Describes an IAM instance profile. type IamInstanceProfile struct { _ struct{} `type:"structure"` @@ -23814,8 +24320,8 @@ type ImportImageInput struct { // // Note: You may only use BYOL if you have existing licenses with rights to // use these licenses in a third party cloud like AWS. For more information, - // see VM Import/Export Prerequisites (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/VMImportPrerequisites.html) - // in the Amazon Elastic Compute Cloud User Guide. + // see Prerequisites (http://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html#prerequisites-image) + // in the VM Import/Export User Guide. // // Valid values: AWS | BYOL LicenseType *string `type:"string"` @@ -24016,8 +24522,8 @@ type ImportInstanceLaunchSpecification struct { InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` // The instance type. For more information about the instance types that you - // can import, see Before You Get Started (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/VMImportPrerequisites.html) - // in the Amazon Elastic Compute Cloud User Guide. + // can import, see Instance Types (http://docs.aws.amazon.com/vm-import/latest/userguide/vmimport-image-import.html#vmimport-instance-types) + // in the VM Import/Export User Guide. InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // Indicates whether monitoring is enabled. @@ -24587,17 +25093,17 @@ func (s InstanceBlockDeviceMappingSpecification) GoString() string { return s.String() } -// Information about the instance type that the Dedicated host supports. +// Information about the instance type that the Dedicated Host supports. type InstanceCapacity struct { _ struct{} `type:"structure"` - // The number of instances that can still be launched onto the Dedicated host. + // The number of instances that can still be launched onto the Dedicated Host. AvailableCapacity *int64 `locationName:"availableCapacity" type:"integer"` - // The instance type size supported by the Dedicated host. + // The instance type size supported by the Dedicated Host. InstanceType *string `locationName:"instanceType" type:"string"` - // The total number of instances that can be launched onto the Dedicated host. + // The total number of instances that can be launched onto the Dedicated Host. TotalCapacity *int64 `locationName:"totalCapacity" type:"integer"` } @@ -25319,7 +25825,7 @@ type ModifyHostsInput struct { // Specify whether to enable or disable auto-placement. AutoPlacement *string `locationName:"autoPlacement" type:"string" required:"true" enum:"AutoPlacement"` - // The host IDs of the Dedicated hosts you want to modify. + // The host IDs of the Dedicated Hosts you want to modify. HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list" required:"true"` } @@ -25353,10 +25859,10 @@ func (s *ModifyHostsInput) Validate() error { type ModifyHostsOutput struct { _ struct{} `type:"structure"` - // The IDs of the Dedicated hosts that were successfully modified. + // The IDs of the Dedicated Hosts that were successfully modified. Successful []*string `locationName:"successful" locationNameList:"item" type:"list"` - // The IDs of the Dedicated hosts that could not be modified. Check whether + // The IDs of the Dedicated Hosts that could not be modified. Check whether // the setting you requested can be used. Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` } @@ -25375,7 +25881,7 @@ func (s ModifyHostsOutput) GoString() string { type ModifyIdFormatInput struct { _ struct{} `type:"structure"` - // The type of resource. + // The type of resource: instance | reservation | snapshot | volume Resource *string `type:"string" required:"true"` // Indicate whether the resource should use longer IDs (17-character IDs). @@ -25430,7 +25936,7 @@ type ModifyIdentityIdFormatInput struct { // user. PrincipalArn *string `locationName:"principalArn" type:"string" required:"true"` - // The type of resource. + // The type of resource: instance | reservation | snapshot | volume Resource *string `locationName:"resource" type:"string" required:"true"` // Indicates whether the resource should use longer IDs (17-character IDs) @@ -25698,7 +26204,7 @@ type ModifyInstancePlacementInput struct { // The new affinity setting for the instance. Affinity *string `locationName:"affinity" type:"string" enum:"Affinity"` - // The ID of the Dedicated host that the instance will have affinity with. + // The ID of the Dedicated Host that the instance will have affinity with. HostId *string `locationName:"hostId" type:"string"` // The ID of the instance that you are modifying. @@ -26274,16 +26780,6 @@ func (s *ModifyVpcPeeringConnectionOptionsInput) Validate() error { if s.VpcPeeringConnectionId == nil { invalidParams.Add(request.NewErrParamRequired("VpcPeeringConnectionId")) } - if s.AccepterPeeringConnectionOptions != nil { - if err := s.AccepterPeeringConnectionOptions.Validate(); err != nil { - invalidParams.AddNested("AccepterPeeringConnectionOptions", err.(request.ErrInvalidParams)) - } - } - if s.RequesterPeeringConnectionOptions != nil { - if err := s.RequesterPeeringConnectionOptions.Validate(); err != nil { - invalidParams.AddNested("RequesterPeeringConnectionOptions", err.(request.ErrInvalidParams)) - } - } if invalidParams.Len() > 0 { return invalidParams @@ -26884,6 +27380,10 @@ func (s NewDhcpConfiguration) GoString() string { type PeeringConnectionOptions struct { _ struct{} `type:"structure"` + // If true, enables a local VPC to resolve public DNS hostnames to private IP + // addresses when queried from instances in the peer VPC. + AllowDnsResolutionFromRemoteVpc *bool `locationName:"allowDnsResolutionFromRemoteVpc" type:"boolean"` + // If true, enables outbound communication from an EC2-Classic instance that's // linked to a local VPC via ClassicLink to instances in a peer VPC. AllowEgressFromLocalClassicLinkToRemoteVpc *bool `locationName:"allowEgressFromLocalClassicLinkToRemoteVpc" type:"boolean"` @@ -26907,13 +27407,17 @@ func (s PeeringConnectionOptions) GoString() string { type PeeringConnectionOptionsRequest struct { _ struct{} `type:"structure"` + // If true, enables a local VPC to resolve public DNS hostnames to private IP + // addresses when queried from instances in the peer VPC. + AllowDnsResolutionFromRemoteVpc *bool `type:"boolean"` + // If true, enables outbound communication from an EC2-Classic instance that's // linked to a local VPC via ClassicLink to instances in a peer VPC. - AllowEgressFromLocalClassicLinkToRemoteVpc *bool `type:"boolean" required:"true"` + AllowEgressFromLocalClassicLinkToRemoteVpc *bool `type:"boolean"` // If true, enables outbound communication from instances in a local VPC to // an EC2-Classic instance that's linked to a peer VPC via ClassicLink. - AllowEgressFromLocalVpcToRemoteClassicLink *bool `type:"boolean" required:"true"` + AllowEgressFromLocalVpcToRemoteClassicLink *bool `type:"boolean"` } // String returns the string representation @@ -26926,27 +27430,11 @@ func (s PeeringConnectionOptionsRequest) GoString() string { return s.String() } -// Validate inspects the fields of the type to determine if they are valid. -func (s *PeeringConnectionOptionsRequest) Validate() error { - invalidParams := request.ErrInvalidParams{Context: "PeeringConnectionOptionsRequest"} - if s.AllowEgressFromLocalClassicLinkToRemoteVpc == nil { - invalidParams.Add(request.NewErrParamRequired("AllowEgressFromLocalClassicLinkToRemoteVpc")) - } - if s.AllowEgressFromLocalVpcToRemoteClassicLink == nil { - invalidParams.Add(request.NewErrParamRequired("AllowEgressFromLocalVpcToRemoteClassicLink")) - } - - if invalidParams.Len() > 0 { - return invalidParams - } - return nil -} - // Describes the placement for the instance. type Placement struct { _ struct{} `type:"structure"` - // The affinity setting for the instance on the Dedicated host. This parameter + // The affinity setting for the instance on the Dedicated Host. This parameter // is not supported for the ImportInstance command. Affinity *string `locationName:"affinity" type:"string"` @@ -27264,6 +27752,135 @@ func (s ProvisionedBandwidth) GoString() string { return s.String() } +// Describes the result of the purchase. +type Purchase struct { + _ struct{} `type:"structure"` + + // The currency in which the UpfrontPrice and HourlyPrice amounts are specified. + // At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // The duration of the reservation's term in seconds. + Duration *int64 `locationName:"duration" type:"integer"` + + // The IDs of the Dedicated Hosts associated with the reservation. + HostIdSet []*string `locationName:"hostIdSet" locationNameList:"item" type:"list"` + + // The ID of the reservation. + HostReservationId *string `locationName:"hostReservationId" type:"string"` + + // The hourly price of the reservation per hour. + HourlyPrice *string `locationName:"hourlyPrice" type:"string"` + + // The instance family on the Dedicated Host that the reservation can be associated + // with. + InstanceFamily *string `locationName:"instanceFamily" type:"string"` + + // The payment option for the reservation. + PaymentOption *string `locationName:"paymentOption" type:"string" enum:"PaymentOption"` + + // The upfront price of the reservation. + UpfrontPrice *string `locationName:"upfrontPrice" type:"string"` +} + +// String returns the string representation +func (s Purchase) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Purchase) GoString() string { + return s.String() +} + +type PurchaseHostReservationInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide. + ClientToken *string `type:"string"` + + // The currency in which the totalUpfrontPrice, LimitPrice, and totalHourlyPrice + // amounts are specified. At this time, the only supported currency is USD. + CurrencyCode *string `type:"string" enum:"CurrencyCodeValues"` + + // The ID/s of the Dedicated Host/s that the reservation will be associated + // with. + HostIdSet []*string `locationNameList:"item" type:"list" required:"true"` + + // The specified limit is checked against the total upfront cost of the reservation + // (calculated as the offering's upfront cost multiplied by the host count). + // If the total upfront cost is greater than the specified price limit, the + // request will fail. This is used to ensure that the purchase does not exceed + // the expected upfront cost of the purchase. At this time, the only supported + // currency is USD. For example, to indicate a limit price of USD 100, specify + // 100.00. + LimitPrice *string `type:"string"` + + // The ID of the offering. + OfferingId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s PurchaseHostReservationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseHostReservationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PurchaseHostReservationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PurchaseHostReservationInput"} + if s.HostIdSet == nil { + invalidParams.Add(request.NewErrParamRequired("HostIdSet")) + } + if s.OfferingId == nil { + invalidParams.Add(request.NewErrParamRequired("OfferingId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type PurchaseHostReservationOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure idempotency of the + // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) + // in the Amazon Elastic Compute Cloud User Guide + ClientToken *string `locationName:"clientToken" type:"string"` + + // The currency in which the totalUpfrontPrice and totalHourlyPrice amounts + // are specified. At this time, the only supported currency is USD. + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` + + // Describes the details of the purchase. + Purchase []*Purchase `locationName:"purchase" type:"list"` + + // The total hourly price of the reservation calculated per hour. + TotalHourlyPrice *string `locationName:"totalHourlyPrice" type:"string"` + + // The total amount that will be charged to your account when you purchase the + // reservation. + TotalUpfrontPrice *string `locationName:"totalUpfrontPrice" type:"string"` +} + +// String returns the string representation +func (s PurchaseHostReservationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseHostReservationOutput) GoString() string { + return s.String() +} + // Describes a request to purchase Scheduled Instances. type PurchaseRequest struct { _ struct{} `type:"structure"` @@ -27737,7 +28354,7 @@ func (s ReleaseAddressOutput) GoString() string { type ReleaseHostsInput struct { _ struct{} `type:"structure"` - // The IDs of the Dedicated hosts you want to release. + // The IDs of the Dedicated Hosts you want to release. HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list" required:"true"` } @@ -27768,10 +28385,10 @@ func (s *ReleaseHostsInput) Validate() error { type ReleaseHostsOutput struct { _ struct{} `type:"structure"` - // The IDs of the Dedicated hosts that were successfully released. + // The IDs of the Dedicated Hosts that were successfully released. Successful []*string `locationName:"successful" locationNameList:"item" type:"list"` - // The IDs of the Dedicated hosts that could not be released, including an error + // The IDs of the Dedicated Hosts that could not be released, including an error // message. Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` } @@ -29364,6 +29981,12 @@ type RunInstancesInput struct { AdditionalInfo *string `locationName:"additionalInfo" type:"string"` // The block device mapping. + // + // Supplying both a snapshot ID and an encryption value as arguments for block-device + // mapping results in an error. This is because only blank volumes can be encrypted + // on start, and these are not created from a snapshot. If a snapshot is the + // basis for the volume, it contains data by definition and its encryption status + // cannot be changed using this action. BlockDeviceMappings []*BlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` // Unique, case-sensitive identifier you provide to ensure the idempotency of @@ -30321,8 +30944,9 @@ type Snapshot struct { // volume. KmsKeyId *string `locationName:"kmsKeyId" type:"string"` - // The AWS account alias (for example, amazon, self) or AWS account ID that - // owns the snapshot. + // Value from an Amazon-maintained list (amazon | aws-marketplace | microsoft) + // of snapshot owners. Not to be confused with the user-configured AWS account + // alias, which is set from the IAM console. OwnerAlias *string `locationName:"ownerAlias" type:"string"` // The AWS account ID of the EBS snapshot owner. @@ -30351,7 +30975,9 @@ type Snapshot struct { // Any tags assigned to the snapshot. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - // The ID of the volume that was used to create the snapshot. + // The ID of the volume that was used to create the snapshot. Snapshots created + // by the CopySnapshot action have an arbitrary volume ID that should not be + // used for any purpose. VolumeId *string `locationName:"volumeId" type:"string"` // The size of the volume, in GiB. @@ -30645,6 +31271,13 @@ func (s SpotFleetMonitoring) GoString() string { type SpotFleetRequestConfig struct { _ struct{} `type:"structure"` + // The progress of the Spot fleet request. If there is an error, the status + // is error. After all bids are placed, the status is pending_fulfillment. If + // the size of the fleet is equal to or greater than its target capacity, the + // status is fulfilled. If the size of the fleet is decreased, the status is + // pending_termination while Spot instances are terminating. + ActivityStatus *string `locationName:"activityStatus" type:"string" enum:"ActivityStatus"` + // The creation date and time of the request. CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` @@ -32065,6 +32698,10 @@ func (s VpcPeeringConnection) GoString() string { type VpcPeeringConnectionOptionsDescription struct { _ struct{} `type:"structure"` + // Indicates whether a local VPC can resolve public DNS hostnames to private + // IP addresses when queried from instances in a peer VPC. + AllowDnsResolutionFromRemoteVpc *bool `locationName:"allowDnsResolutionFromRemoteVpc" type:"boolean"` + // Indicates whether a local ClassicLink connection can communicate with the // peer VPC over the VPC peering connection. AllowEgressFromLocalClassicLinkToRemoteVpc *bool `locationName:"allowEgressFromLocalClassicLinkToRemoteVpc" type:"boolean"` @@ -32284,6 +32921,17 @@ const ( AccountAttributeNameDefaultVpc = "default-vpc" ) +const ( + // @enum ActivityStatus + ActivityStatusError = "error" + // @enum ActivityStatus + ActivityStatusPendingFulfillment = "pending_fulfillment" + // @enum ActivityStatus + ActivityStatusPendingTermination = "pending_termination" + // @enum ActivityStatus + ActivityStatusFulfilled = "fulfilled" +) + const ( // @enum Affinity AffinityDefault = "default" @@ -32861,6 +33509,15 @@ const ( OperationTypeRemove = "remove" ) +const ( + // @enum PaymentOption + PaymentOptionAllUpfront = "AllUpfront" + // @enum PaymentOption + PaymentOptionPartialUpfront = "PartialUpfront" + // @enum PaymentOption + PaymentOptionNoUpfront = "NoUpfront" +) + const ( // @enum PermissionGroup PermissionGroupAll = "all" @@ -32938,6 +33595,17 @@ const ( ReportStatusTypeImpaired = "impaired" ) +const ( + // @enum ReservationState + ReservationStatePaymentPending = "payment-pending" + // @enum ReservationState + ReservationStatePaymentFailed = "payment-failed" + // @enum ReservationState + ReservationStateActive = "active" + // @enum ReservationState + ReservationStateRetired = "retired" +) + const ( // @enum ReservedInstanceState ReservedInstanceStatePaymentPending = "payment-pending" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go index 9e94fe671..36181d991 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/customizations.go @@ -40,7 +40,11 @@ func fillPresignedURL(r *request.Request) { clientInfo := r.ClientInfo clientInfo.Endpoint, clientInfo.SigningRegion = endpoints.EndpointForRegion( - clientInfo.ServiceName, aws.StringValue(cfg.Region), aws.BoolValue(cfg.DisableSSL)) + clientInfo.ServiceName, + aws.StringValue(cfg.Region), + aws.BoolValue(cfg.DisableSSL), + aws.BoolValue(cfg.UseDualStack), + ) // Presign a CopySnapshot request with modified params req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data) diff --git a/vendor/github.com/aws/aws-sdk-go/service/iam/api.go b/vendor/github.com/aws/aws-sdk-go/service/iam/api.go index 35efd0338..08f8bcc0c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/iam/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/iam/api.go @@ -7985,7 +7985,9 @@ type CreateGroupInput struct { // // The regex pattern (http://wikipedia.org/wiki/regex) for this parameter is // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: =,.@-. + // The group name must be unique within the account. Group names are not distinguished + // by case. For example, you cannot create groups named both "ADMINS" and "admins". GroupName *string `min:"1" type:"string" required:"true"` // The path to the group. For more information about paths, see IAM Identifiers @@ -8505,7 +8507,9 @@ type CreateRoleInput struct { // // The regex pattern (http://wikipedia.org/wiki/regex) for this parameter is // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: =,.@-. + // Role names are not distinguished by case. For example, you cannot create + // roles named both "PRODROLE" and "prodrole". RoleName *string `min:"1" type:"string" required:"true"` } @@ -8654,7 +8658,9 @@ type CreateUserInput struct { // // The regex pattern (http://wikipedia.org/wiki/regex) for this parameter is // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: =,.@-. + // User names are not distinguished by case. For example, you cannot create + // users named both "TESTUSER" and "testuser". UserName *string `min:"1" type:"string" required:"true"` } 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 5132954f3..553b0e4a3 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 @@ -1242,7 +1242,7 @@ func (c *S3) GetBucketReplicationRequest(input *GetBucketReplicationInput) (req return } -// Deprecated, see the GetBucketReplicationConfiguration operation. +// Returns the replication configuration of a bucket. func (c *S3) GetBucketReplication(input *GetBucketReplicationInput) (*GetBucketReplicationOutput, error) { req, out := c.GetBucketReplicationRequest(input) err := req.Send() diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go b/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go index 517292903..ccbf5cc1a 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go @@ -37,6 +37,14 @@ var accelerateOpBlacklist = operationBlacklist{ func updateEndpointForS3Config(r *request.Request) { forceHostStyle := aws.BoolValue(r.Config.S3ForcePathStyle) accelerate := aws.BoolValue(r.Config.S3UseAccelerate) + useDualStack := aws.BoolValue(r.Config.UseDualStack) + + if useDualStack && accelerate { + r.Error = awserr.New("InvalidParameterException", + fmt.Sprintf("configuration aws.Config.UseDualStack is not compatible with aws.Config.Accelerate"), + nil) + return + } if accelerate && accelerateOpBlacklist.Continue(r) { if forceHostStyle { diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go index a3d96f6b2..ed91c5872 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go @@ -23,7 +23,7 @@ func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() defer io.Copy(ioutil.Discard, r.HTTPResponse.Body) - // Bucket exists in a differnt region, and request needs + // Bucket exists in a different region, and request needs // to be made to the correct region. if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { r.Error = awserr.NewRequestFailure( 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 5e4078ea8..f11e8675f 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 @@ -215,13 +215,14 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re // returned by the operation have the permissions that are defined in the access // policy of the role that is being assumed. If you pass a policy to this operation, // the temporary security credentials that are returned by the operation have -// the permissions that are allowed by both the access policy of the role that -// is being assumed, and the policy that you pass. This gives you a way to -// further restrict the permissions for the resulting temporary security credentials. -// You cannot use the passed policy to grant permissions that are in excess -// of those allowed by the access policy of the role that is being assumed. -// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, -// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) +// the permissions that are allowed by the intersection of both the access policy +// of the role that is being assumed, and the policy that you pass. This means +// that both policies must grant the permission for the action to be allowed. +// This gives you a way to further restrict the permissions for the resulting +// temporary security credentials. You cannot use the passed policy to grant +// permissions that are in excess of those allowed by the access policy of the +// role that is being assumed. For more information, see Permissions for AssumeRole, +// AssumeRoleWithSAML, and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) // in the IAM User Guide. // // Before your application can call AssumeRoleWithSAML, you must configure @@ -743,6 +744,14 @@ type AssumeRoleInput struct { // The duration, in seconds, of the role session. The value can range from 900 // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set // to 3600 seconds. + // + // This is separate from the duration of a console session that you might + // request using the returned credentials. The request to the federation endpoint + // for a console sign-in token takes a SessionDuration parameter that specifies + // the maximum length of the console session, separately from the DurationSeconds + // parameter on this API. For more information, see Creating a URL that Enables + // Federated Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. DurationSeconds *int64 `min:"900" type:"integer"` // A unique identifier that is used by third parties when assuming roles in @@ -757,7 +766,8 @@ type AssumeRoleInput struct { // // The format for this parameter, as described by its regex pattern, is a string // of characters consisting of upper- and lower-case alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@:\/- + // with no spaces. You can also include underscores or any of the following + // characters: =,.@:\/- ExternalId *string `min:"2" type:"string"` // An IAM policy in JSON format. @@ -801,7 +811,8 @@ type AssumeRoleInput struct { // // The format for this parameter, as described by its regex pattern, is a string // of characters consisting of upper- and lower-case alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- RoleSessionName *string `min:"2" type:"string" required:"true"` // The identification number of the MFA device that is associated with the user @@ -812,7 +823,8 @@ type AssumeRoleInput struct { // // The format for this parameter, as described by its regex pattern, is a string // of characters consisting of upper- and lower-case alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- SerialNumber *string `min:"9" type:"string"` // The value provided by the MFA device, if the trust policy of the role being @@ -918,8 +930,13 @@ type AssumeRoleWithSAMLInput struct { // response's SessionNotOnOrAfter value. The actual expiration time is whichever // value is shorter. // - // The maximum duration for a session is 1 hour, and the minimum duration - // is 15 minutes, even if values outside this range are specified. + // This is separate from the duration of a console session that you might + // request using the returned credentials. The request to the federation endpoint + // for a console sign-in token takes a SessionDuration parameter that specifies + // the maximum length of the console session, separately from the DurationSeconds + // parameter on this API. For more information, see Enabling SAML 2.0 Federated + // Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html) + // in the IAM User Guide. DurationSeconds *int64 `min:"900" type:"integer"` // An IAM policy in JSON format. @@ -1078,6 +1095,14 @@ type AssumeRoleWithWebIdentityInput struct { // The duration, in seconds, of the role session. The value can range from 900 // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set // to 3600 seconds. + // + // This is separate from the duration of a console session that you might + // request using the returned credentials. The request to the federation endpoint + // for a console sign-in token takes a SessionDuration parameter that specifies + // the maximum length of the console session, separately from the DurationSeconds + // parameter on this API. For more information, see Creating a URL that Enables + // Federated Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. DurationSeconds *int64 `min:"900" type:"integer"` // An IAM policy in JSON format. @@ -1125,7 +1150,8 @@ type AssumeRoleWithWebIdentityInput struct { // // The format for this parameter, as described by its regex pattern, is a string // of characters consisting of upper- and lower-case alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- RoleSessionName *string `min:"2" type:"string" required:"true"` // The OAuth 2.0 access token or OpenID Connect ID token that is provided by @@ -1432,7 +1458,8 @@ type GetFederationTokenInput struct { // // The format for this parameter, as described by its regex pattern, is a string // of characters consisting of upper- and lower-case alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- Name *string `min:"2" type:"string" required:"true"` // An IAM policy in JSON format that is passed with the GetFederationToken call @@ -1556,7 +1583,8 @@ type GetSessionTokenInput struct { // // The format for this parameter, as described by its regex pattern, is a string // of characters consisting of upper- and lower-case alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include underscores or any of the following + // characters: =,.@- SerialNumber *string `min:"9" type:"string"` // The value provided by the MFA device, if MFA is required. If any policy requires diff --git a/vendor/github.com/bgentry/speakeasy/speakeasy_unix.go b/vendor/github.com/bgentry/speakeasy/speakeasy_unix.go index dca74bd99..d99fda191 100644 --- a/vendor/github.com/bgentry/speakeasy/speakeasy_unix.go +++ b/vendor/github.com/bgentry/speakeasy/speakeasy_unix.go @@ -4,7 +4,7 @@ // Original code is based on code by RogerV in the golang-nuts thread: // https://groups.google.com/group/golang-nuts/browse_thread/thread/40cc41e9d9fc9247 -// +build darwin freebsd linux netbsd openbsd solaris +// +build darwin dragonfly freebsd linux netbsd openbsd solaris package speakeasy diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/LICENSE b/vendor/github.com/circonus-labs/circonus-gometrics/LICENSE new file mode 100644 index 000000000..761798c3b --- /dev/null +++ b/vendor/github.com/circonus-labs/circonus-gometrics/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2016, Circonus, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name Circonus, Inc. nor the names + of its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/README.md b/vendor/github.com/circonus-labs/circonus-gometrics/README.md index f0889037b..d245e40af 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/README.md +++ b/vendor/github.com/circonus-labs/circonus-gometrics/README.md @@ -163,7 +163,7 @@ import ( func main() { cmc := &cgm.Config{} cmc.CheckManager.API.TokenKey = os.Getenv("CIRCONUS_API_TOKEN") - + metrics, err := cgm.NewCirconusMetrics(cmc) if err != nil { panic(err) @@ -177,3 +177,5 @@ func main() { } ``` + +Unless otherwise noted, the source files are distributed under the BSD-style license found in the LICENSE file. diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/api/api.go b/vendor/github.com/circonus-labs/circonus-gometrics/api/api.go index 30fe7fbb0..7a7f18708 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/api/api.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/api/api.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + // Package api provides methods for interacting with the Circonus API package api @@ -152,36 +156,45 @@ func (a *API) apiCall(reqMethod string, reqPath string, data []byte) ([]byte, er req.Header.Add("X-Circonus-Auth-Token", string(a.key)) req.Header.Add("X-Circonus-App-Name", string(a.app)) + // keep last HTTP error in the event of retry failure + var lastHTTPError error + retryPolicy := func(resp *http.Response, err error) (bool, error) { + if err != nil { + lastHTTPError = err + return true, err + } + // Check the response code. We retry on 500-range responses to allow + // the server time to recover, as 500's are typically not permanent + // errors and may relate to outages on the server side. This will catch + // invalid response codes as well, like 0 and 999. + if resp.StatusCode == 0 || resp.StatusCode >= 500 { + defer resp.Body.Close() + body, readErr := ioutil.ReadAll(resp.Body) + if readErr != nil { + lastHTTPError = fmt.Errorf("- last HTTP error: %d %+v", resp.StatusCode, readErr) + } else { + lastHTTPError = fmt.Errorf("- last HTTP error: %d %s", resp.StatusCode, string(body)) + } + return true, nil + } + return false, nil + } + client := retryablehttp.NewClient() client.RetryWaitMin = minRetryWait client.RetryWaitMax = maxRetryWait client.RetryMax = maxRetries client.Logger = a.Log + client.CheckRetry = retryPolicy resp, err := client.Do(req) if err != nil { - stdClient := &http.Client{} - dataReader.Seek(0, 0) - stdRequest, _ := http.NewRequest(reqMethod, reqURL, dataReader) - stdRequest.Header.Add("Accept", "application/json") - stdRequest.Header.Add("X-Circonus-Auth-Token", string(a.key)) - stdRequest.Header.Add("X-Circonus-App-Name", string(a.app)) - res, errSC := stdClient.Do(stdRequest) - if errSC != nil { - return nil, fmt.Errorf("[ERROR] fetching %s: %s", reqURL, errSC) + if lastHTTPError != nil { + return nil, fmt.Errorf("[ERROR] fetching: %+v %+v", err, lastHTTPError) } - - if res != nil && res.Body != nil { - defer res.Body.Close() - body, _ := ioutil.ReadAll(res.Body) - if a.Debug { - a.Log.Printf("[DEBUG] %v\n", string(body)) - } - return nil, fmt.Errorf("[ERROR] %s", string(body)) - } - - return nil, fmt.Errorf("[ERROR] fetching %s: %s", reqURL, err) + return nil, fmt.Errorf("[ERROR] fetching %s: %+v", reqURL, err) } + defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/api/broker.go b/vendor/github.com/circonus-labs/circonus-gometrics/api/broker.go index f04dbf60f..87e2b5e37 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/api/broker.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/api/broker.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package api import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/api/check.go b/vendor/github.com/circonus-labs/circonus-gometrics/api/check.go index 89b833731..df0524f43 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/api/check.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/api/check.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package api import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/api/checkbundle.go b/vendor/github.com/circonus-labs/circonus-gometrics/api/checkbundle.go index 247bf9f49..559df7ac0 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/api/checkbundle.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/api/checkbundle.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package api import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/broker.go b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/broker.go index 0213c0ac4..b23486ce2 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/broker.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/broker.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package checkmgr import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/cert.go b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/cert.go index c5a6736f2..3f173bf5c 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/cert.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/cert.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package checkmgr import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/check.go b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/check.go index 4eefa936e..56f6fed28 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/check.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/check.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package checkmgr import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/checkmgr.go b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/checkmgr.go index 1237ba1d4..e23f00a57 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/checkmgr.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/checkmgr.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + // Package checkmgr provides a check management interace to circonus-gometrics package checkmgr diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/metrics.go b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/metrics.go index 046386823..8f03d4476 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/metrics.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/checkmgr/metrics.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package checkmgr import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/circonus-gometrics.go b/vendor/github.com/circonus-labs/circonus-gometrics/circonus-gometrics.go index 2fd6aad60..34166c007 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/circonus-gometrics.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/circonus-gometrics.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + // Package circonusgometrics provides instrumentation for your applications in the form // of counters, gauges and histograms and allows you to publish them to // Circonus diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/counter.go b/vendor/github.com/circonus-labs/circonus-gometrics/counter.go index ef3a85c01..2b34961f1 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/counter.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/counter.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics // A Counter is a monotonically increasing unsigned integer. diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/gauge.go b/vendor/github.com/circonus-labs/circonus-gometrics/gauge.go index 7573f655f..b44236959 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/gauge.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/gauge.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics // A Gauge is an instantaneous measurement of a value. diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/histogram.go b/vendor/github.com/circonus-labs/circonus-gometrics/histogram.go index cbdd5c692..59d19e20f 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/histogram.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/histogram.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/submit.go b/vendor/github.com/circonus-labs/circonus-gometrics/submit.go index fa2f9eab0..abeb73006 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/submit.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/submit.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/text.go b/vendor/github.com/circonus-labs/circonus-gometrics/text.go index f9064dc6e..eb2d12a87 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/text.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/text.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics // A Text metric is an arbitrary string diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/tools.go b/vendor/github.com/circonus-labs/circonus-gometrics/tools.go index c00820c6c..73259a7b1 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/tools.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/tools.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics import ( diff --git a/vendor/github.com/circonus-labs/circonus-gometrics/util.go b/vendor/github.com/circonus-labs/circonus-gometrics/util.go index b2b698426..d5cc7d56c 100644 --- a/vendor/github.com/circonus-labs/circonus-gometrics/util.go +++ b/vendor/github.com/circonus-labs/circonus-gometrics/util.go @@ -1,3 +1,7 @@ +// Copyright 2016 Circonus, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package circonusgometrics import ( diff --git a/vendor/github.com/coreos/etcd/client/keys.generated.go b/vendor/github.com/coreos/etcd/client/keys.generated.go index 748283aa9..16f10301a 100644 --- a/vendor/github.com/coreos/etcd/client/keys.generated.go +++ b/vendor/github.com/coreos/etcd/client/keys.generated.go @@ -8,10 +8,11 @@ package client import ( "errors" "fmt" - codec1978 "github.com/ugorji/go/codec" "reflect" "runtime" time "time" + + codec1978 "github.com/ugorji/go/codec" ) const ( diff --git a/vendor/github.com/coreos/etcd/client/keys.go b/vendor/github.com/coreos/etcd/client/keys.go index 62d5d506e..b74b9e0a5 100644 --- a/vendor/github.com/coreos/etcd/client/keys.go +++ b/vendor/github.com/coreos/etcd/client/keys.go @@ -191,6 +191,10 @@ type SetOptions struct { // Dir specifies whether or not this Node should be created as a directory. Dir bool + + // NoValueOnSuccess specifies whether the response contains the current value of the Node. + // If set, the response will only contain the current value when the request fails. + NoValueOnSuccess bool } type GetOptions struct { @@ -335,6 +339,7 @@ func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions act.TTL = opts.TTL act.Refresh = opts.Refresh act.Dir = opts.Dir + act.NoValueOnSuccess = opts.NoValueOnSuccess } doCtx := ctx @@ -523,15 +528,16 @@ func (w *waitAction) HTTPRequest(ep url.URL) *http.Request { } type setAction struct { - Prefix string - Key string - Value string - PrevValue string - PrevIndex uint64 - PrevExist PrevExistType - TTL time.Duration - Refresh bool - Dir bool + Prefix string + Key string + Value string + PrevValue string + PrevIndex uint64 + PrevExist PrevExistType + TTL time.Duration + Refresh bool + Dir bool + NoValueOnSuccess bool } func (a *setAction) HTTPRequest(ep url.URL) *http.Request { @@ -565,6 +571,9 @@ func (a *setAction) HTTPRequest(ep url.URL) *http.Request { if a.Refresh { form.Add("refresh", "true") } + if a.NoValueOnSuccess { + params.Set("noValueOnSuccess", strconv.FormatBool(a.NoValueOnSuccess)) + } u.RawQuery = params.Encode() body := strings.NewReader(form.Encode()) diff --git a/vendor/github.com/coreos/etcd/client/util.go b/vendor/github.com/coreos/etcd/client/util.go index 198bff965..15a8babff 100644 --- a/vendor/github.com/coreos/etcd/client/util.go +++ b/vendor/github.com/coreos/etcd/client/util.go @@ -14,6 +14,20 @@ package client +import ( + "regexp" +) + +var ( + roleNotFoundRegExp *regexp.Regexp + userNotFoundRegExp *regexp.Regexp +) + +func init() { + roleNotFoundRegExp = regexp.MustCompile("auth: Role .* does not exist.") + userNotFoundRegExp = regexp.MustCompile("auth: User .* does not exist.") +} + // IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound. func IsKeyNotFound(err error) bool { if cErr, ok := err.(Error); ok { @@ -21,3 +35,19 @@ func IsKeyNotFound(err error) bool { } return false } + +// IsRoleNotFound returns true if the error means role not found of v2 API. +func IsRoleNotFound(err error) bool { + if ae, ok := err.(authError); ok { + return roleNotFoundRegExp.MatchString(ae.Message) + } + return false +} + +// IsUserNotFound returns true if the error means user not found of v2 API. +func IsUserNotFound(err error) bool { + if ae, ok := err.(authError); ok { + return userNotFoundRegExp.MatchString(ae.Message) + } + return false +} diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go index c963a7903..8d9e725f0 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go @@ -96,3 +96,26 @@ func Exist(name string) bool { _, err := os.Stat(name) return err == nil } + +// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily +// shorten the length of the file. +func ZeroToEnd(f *os.File) error { + // TODO: support FALLOC_FL_ZERO_RANGE + off, err := f.Seek(0, os.SEEK_CUR) + if err != nil { + return err + } + lenf, lerr := f.Seek(0, os.SEEK_END) + if lerr != nil { + return lerr + } + if err = f.Truncate(off); err != nil { + return err + } + // make sure blocks remain allocated + if err = Preallocate(f, lenf, true); err != nil { + return err + } + _, err = f.Seek(off, os.SEEK_SET) + return err +} diff --git a/vendor/github.com/coreos/etcd/pkg/transport/listener.go b/vendor/github.com/coreos/etcd/pkg/transport/listener.go index 78407ad8b..9d7209c53 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/listener.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/listener.go @@ -67,6 +67,9 @@ type TLSInfo struct { TrustedCAFile string ClientCertAuth bool + // ServerName ensures the cert matches the given host in case of discovery / virtual hosting + ServerName string + selfCert bool // parseFunc exists to simplify testing. Typically, parseFunc @@ -167,6 +170,7 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) { cfg := &tls.Config{ Certificates: []tls.Certificate{*tlsCert}, MinVersion: tls.VersionTLS12, + ServerName: info.ServerName, } return cfg, nil } @@ -218,7 +222,7 @@ func (info TLSInfo) ClientConfig() (*tls.Config, error) { return nil, err } } else { - cfg = &tls.Config{} + cfg = &tls.Config{ServerName: info.ServerName} } CAFiles := info.cafiles() @@ -227,6 +231,8 @@ func (info TLSInfo) ClientConfig() (*tls.Config, error) { if err != nil { return nil, err } + // if given a CA, trust any host with a cert signed by the CA + cfg.ServerName = "" } if info.selfCert { diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go index 742cc5cbf..ea16b4c0f 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go @@ -35,7 +35,7 @@ func NewTimeoutTransport(info TLSInfo, dialtimeoutd, rdtimeoutd, wtimeoutd time. // it should not be put back to http transport as an idle connection for future usage. tr.MaxIdleConnsPerHost = -1 } else { - // allow more idle connections between peers to avoid unncessary port allocation. + // allow more idle connections between peers to avoid unnecessary port allocation. tr.MaxIdleConnsPerHost = 1024 } diff --git a/vendor/github.com/coreos/etcd/pkg/transport/tls.go b/vendor/github.com/coreos/etcd/pkg/transport/tls.go new file mode 100644 index 000000000..62fe0d385 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/transport/tls.go @@ -0,0 +1,49 @@ +// Copyright 2016 The etcd Authors +// +// 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" + "strings" + "time" +) + +// ValidateSecureEndpoints scans the given endpoints against tls info, returning only those +// endpoints that could be validated as secure. +func ValidateSecureEndpoints(tlsInfo TLSInfo, eps []string) ([]string, error) { + t, err := NewTransport(tlsInfo, 5*time.Second) + if err != nil { + return nil, err + } + var errs []string + var endpoints []string + for _, ep := range eps { + if !strings.HasPrefix(ep, "https://") { + errs = append(errs, fmt.Sprintf("%q is insecure", ep)) + continue + } + conn, cerr := t.Dial("tcp", ep[len("https://"):]) + if cerr != nil { + errs = append(errs, fmt.Sprintf("%q failed to dial (%v)", ep, cerr)) + continue + } + conn.Close() + endpoints = append(endpoints, ep) + } + if len(errs) != 0 { + err = fmt.Errorf("%s", strings.Join(errs, ",")) + } + return endpoints, err +} diff --git a/vendor/github.com/coreos/etcd/pkg/transport/transport.go b/vendor/github.com/coreos/etcd/pkg/transport/transport.go index ca9ccfd80..4a7fe69d2 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/transport.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/transport.go @@ -64,7 +64,8 @@ func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, er } func (urt *unixTransport) RoundTrip(req *http.Request) (*http.Response, error) { - req2 := *req - req2.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1) + url := *req.URL + req.URL = &url + req.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1) return urt.Transport.RoundTrip(req) } diff --git a/vendor/github.com/fatih/structs/structs.go b/vendor/github.com/fatih/structs/structs.go index bfcfb706b..06da62094 100644 --- a/vendor/github.com/fatih/structs/structs.go +++ b/vendor/github.com/fatih/structs/structs.go @@ -558,7 +558,10 @@ func (s *Struct) nested(val reflect.Value) interface{} { // TODO(arslan): should this be optional? // do not iterate of non struct types, just pass the value. Ie: []int, // []string, co... We only iterate further if it's a struct. - if val.Type().Elem().Kind() != reflect.Struct { + // i.e []foo or []*foo + if val.Type().Elem().Kind() != reflect.Struct && + !(val.Type().Elem().Kind() == reflect.Ptr && + val.Type().Elem().Elem().Kind() == reflect.Struct) { finalVal = val.Interface() break } diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md index 98698c187..a939d75e9 100644 --- a/vendor/github.com/go-ini/ini/README.md +++ b/vendor/github.com/go-ini/ini/README.md @@ -70,6 +70,8 @@ cfg, err := ini.LooseLoad("filename", "filename_404") The cool thing is, whenever the file is available to load while you're calling `Reload` method, it will be counted as usual. +#### Ignore cases of key name + When you do not care about cases of section and key names, you can use `InsensitiveLoad` to force all names to be lowercased while parsing. ```go @@ -85,7 +87,24 @@ key1, err := cfg.GetKey("Key") key2, err := cfg.GetKey("KeY") ``` -If you want to give more advanced load options, use `LoadSources` and take a look at [`LoadOptions`](https://github.com/go-ini/ini/blob/v1.16.1/ini.go#L156). +#### MySQL-like boolean key + +MySQL's configuration allows a key without value as follows: + +```ini +[mysqld] +... +skip-host-cache +skip-name-resolve +``` + +By default, this is considered as missing value. But if you know you're going to deal with those cases, you can assign advanced load options: + +```go +cfg, err := LoadSources(LoadOptions{AllowBooleanKeys: true}, "my.cnf")) +``` + +The value of those keys are always `true`, and when you save to a file, it will keep in the same foramt as you read. ### Working with sections @@ -512,8 +531,8 @@ Why not? ```go type Embeded struct { Dates []time.Time `delim:"|"` - Places []string - None []int + Places []string `ini:"places,omitempty"` + None []int `ini:",omitempty"` } type Author struct { @@ -548,8 +567,7 @@ GPA = 2.8 [Embeded] Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00 -Places = HangZhou,Boston -None = +places = HangZhou,Boston ``` #### Name Mapper @@ -583,6 +601,26 @@ func main() { Same rules of name mapper apply to `ini.ReflectFromWithMapper` function. +#### Value Mapper + +To expand values (e.g. from environment variables), you can use the `ValueMapper` to transform values: + +```go +type Env struct { + Foo string `ini:"foo"` +} + +func main() { + cfg, err := ini.Load([]byte("[env]\nfoo = ${MY_VAR}\n") + cfg.ValueMapper = os.ExpandEnv + // ... + env := &Env{} + err = cfg.Section("env").MapTo(env) +} +``` + +This would set the value of `env.Foo` to the value of the environment variable `MY_VAR`. + #### Other Notes On Map/Reflect Any embedded struct is treated as a section by default, and there is no automatic parent-child relations in map/reflect feature: diff --git a/vendor/github.com/go-ini/ini/README_ZH.md b/vendor/github.com/go-ini/ini/README_ZH.md index 7b2f9e096..2178e4789 100644 --- a/vendor/github.com/go-ini/ini/README_ZH.md +++ b/vendor/github.com/go-ini/ini/README_ZH.md @@ -63,6 +63,8 @@ cfg, err := ini.LooseLoad("filename", "filename_404") 更牛逼的是,当那些之前不存在的文件在重新调用 `Reload` 方法的时候突然出现了,那么它们会被正常加载。 +#### 忽略键名的大小写 + 有时候分区和键的名称大小写混合非常烦人,这个时候就可以通过 `InsensitiveLoad` 将所有分区和键名在读取里强制转换为小写: ```go @@ -78,7 +80,24 @@ key1, err := cfg.GetKey("Key") key2, err := cfg.GetKey("KeY") ``` -如果您想要更加自定义的加载选项,可以使用 `LoadSources` 方法并参见 [`LoadOptions`](https://github.com/go-ini/ini/blob/v1.16.1/ini.go#L156)。 +#### 类似 MySQL 配置中的布尔值键 + +MySQL 的配置文件中会出现没有具体值的布尔类型的键: + +```ini +[mysqld] +... +skip-host-cache +skip-name-resolve +``` + +默认情况下这被认为是缺失值而无法完成解析,但可以通过高级的加载选项对它们进行处理: + +```go +cfg, err := LoadSources(LoadOptions{AllowBooleanKeys: true}, "my.cnf")) +``` + +这些键的值永远为 `true`,且在保存到文件时也只会输出键名。 ### 操作分区(Section) @@ -503,8 +522,8 @@ p := &Person{ ```go type Embeded struct { Dates []time.Time `delim:"|"` - Places []string - None []int + Places []string `ini:"places,omitempty"` + None []int `ini:",omitempty"` } type Author struct { @@ -539,8 +558,7 @@ GPA = 2.8 [Embeded] Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00 -Places = HangZhou,Boston -None = +places = HangZhou,Boston ``` #### 名称映射器(Name Mapper) @@ -574,6 +592,26 @@ func main() { 使用函数 `ini.ReflectFromWithMapper` 时也可应用相同的规则。 +#### 值映射器(Value Mapper) + +值映射器允许使用一个自定义函数自动展开值的具体内容,例如:运行时获取环境变量: + +```go +type Env struct { + Foo string `ini:"foo"` +} + +func main() { + cfg, err := ini.Load([]byte("[env]\nfoo = ${MY_VAR}\n") + cfg.ValueMapper = os.ExpandEnv + // ... + env := &Env{} + err = cfg.Section("env").MapTo(env) +} +``` + +本例中,`env.Foo` 将会是运行时所获取到环境变量 `MY_VAR` 的值。 + #### 映射/反射的其它说明 任何嵌入的结构都会被默认认作一个不同的分区,并且不会自动产生所谓的父子分区关联: diff --git a/vendor/github.com/go-ini/ini/error.go b/vendor/github.com/go-ini/ini/error.go new file mode 100644 index 000000000..80afe7431 --- /dev/null +++ b/vendor/github.com/go-ini/ini/error.go @@ -0,0 +1,32 @@ +// Copyright 2016 Unknwon +// +// 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 ini + +import ( + "fmt" +) + +type ErrDelimiterNotFound struct { + Line string +} + +func IsErrDelimiterNotFound(err error) bool { + _, ok := err.(ErrDelimiterNotFound) + return ok +} + +func (err ErrDelimiterNotFound) Error() string { + return fmt.Sprintf("key-value delimiter not found: %s", err.Line) +} diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go index 24cfb46b7..cd065e782 100644 --- a/vendor/github.com/go-ini/ini/ini.go +++ b/vendor/github.com/go-ini/ini/ini.go @@ -36,7 +36,7 @@ const ( // Maximum allowed depth when recursively substituing variable names. _DEPTH_VALUES = 99 - _VERSION = "1.18.0" + _VERSION = "1.21.1" ) // Version returns current package version literal. @@ -129,6 +129,7 @@ type File struct { options LoadOptions NameMapper + ValueMapper } // newFile initializes File object with given data sources. @@ -160,6 +161,9 @@ type LoadOptions struct { Insensitive bool // IgnoreContinuation indicates whether to ignore continuation lines while parsing. IgnoreContinuation bool + // AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing. + // This type of keys are mostly used in my.cnf. + AllowBooleanKeys bool } func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) { @@ -422,7 +426,7 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) { } switch { - case key.isAutoIncr: + case key.isAutoIncrement: kname = "-" case strings.ContainsAny(kname, "\"=:"): kname = "`" + kname + "`" @@ -433,6 +437,10 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) { return 0, err } + if key.isBooleanType { + continue + } + // Write out alignment spaces before "=" sign if PrettyFormat { buf.Write(alignSpaces[:alignLength-len(kname)]) diff --git a/vendor/github.com/go-ini/ini/key.go b/vendor/github.com/go-ini/ini/key.go index 3b2f47203..9738c55a2 100644 --- a/vendor/github.com/go-ini/ini/key.go +++ b/vendor/github.com/go-ini/ini/key.go @@ -23,13 +23,18 @@ import ( // Key represents a key under a section. type Key struct { - s *Section - Comment string - name string - value string - isAutoIncr bool + s *Section + name string + value string + isAutoIncrement bool + isBooleanType bool + + Comment string } +// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv +type ValueMapper func(string) string + // Name returns name of key. func (k *Key) Name() string { return k.name @@ -43,6 +48,9 @@ func (k *Key) Value() string { // String returns string representation of value. func (k *Key) String() string { val := k.value + if k.s.f.ValueMapper != nil { + val = k.s.f.ValueMapper(val) + } if strings.Index(val, "%") == -1 { return val } diff --git a/vendor/github.com/go-ini/ini/parser.go b/vendor/github.com/go-ini/ini/parser.go index d6d4005a8..dc6df87a6 100644 --- a/vendor/github.com/go-ini/ini/parser.go +++ b/vendor/github.com/go-ini/ini/parser.go @@ -111,7 +111,7 @@ func readKeyName(in []byte) (string, int, error) { // Find key-value delimiter i := strings.IndexAny(line[pos+startIdx:], "=:") if i < 0 { - return "", -1, fmt.Errorf("key-value delimiter not found: %s", line) + return "", -1, ErrDelimiterNotFound{line} } endIdx = pos + i return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil @@ -119,7 +119,7 @@ func readKeyName(in []byte) (string, int, error) { endIdx = strings.IndexAny(line, "=:") if endIdx < 0 { - return "", -1, fmt.Errorf("key-value delimiter not found: %s", line) + return "", -1, ErrDelimiterNotFound{line} } return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil } @@ -285,6 +285,17 @@ func (f *File) parse(reader io.Reader) (err error) { kname, offset, err := readKeyName(line) if err != nil { + // Treat as boolean key when desired, and whole line is key name. + if IsErrDelimiterNotFound(err) && f.options.AllowBooleanKeys { + key, err := section.NewKey(string(line), "true") + if err != nil { + return err + } + key.isBooleanType = true + key.Comment = strings.TrimSpace(p.comment.String()) + p.comment.Reset() + continue + } return err } @@ -300,7 +311,7 @@ func (f *File) parse(reader io.Reader) (err error) { if err != nil { return err } - key.isAutoIncr = isAutoIncr + key.isAutoIncrement = isAutoIncr value, err := p.readValue(line[offset:], f.options.IgnoreContinuation) if err != nil { diff --git a/vendor/github.com/go-ini/ini/section.go b/vendor/github.com/go-ini/ini/section.go index 2fa099f80..bbb73caf8 100644 --- a/vendor/github.com/go-ini/ini/section.go +++ b/vendor/github.com/go-ini/ini/section.go @@ -58,7 +58,11 @@ func (s *Section) NewKey(name, val string) (*Key, error) { } s.keyList = append(s.keyList, name) - s.keys[name] = &Key{s, "", name, val, false} + s.keys[name] = &Key{ + s: s, + name: name, + value: val, + } s.keysHash[name] = val return s.keys[name], nil } diff --git a/vendor/github.com/go-ini/ini/struct.go b/vendor/github.com/go-ini/ini/struct.go index f4620afdb..d00fb4b83 100644 --- a/vendor/github.com/go-ini/ini/struct.go +++ b/vendor/github.com/go-ini/ini/struct.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "reflect" + "strings" "time" "unicode" ) @@ -161,7 +162,8 @@ func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim stri // byte is an alias for uint8, so supporting uint8 breaks support for byte case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: durationVal, err := key.Duration() - if err == nil { + // Skip zero value + if err == nil && int(durationVal) > 0 { field.Set(reflect.ValueOf(durationVal)) return nil } @@ -207,7 +209,8 @@ func (s *Section) mapTo(val reflect.Value) error { continue } - fieldName := s.parseFieldName(tpField.Name, tag) + opts := strings.SplitN(tag, ",", 2) // strip off possible omitempty + fieldName := s.parseFieldName(tpField.Name, opts[0]) if len(fieldName) == 0 || !field.CanSet() { continue } @@ -323,6 +326,28 @@ func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim return nil } +// CR: copied from encoding/json/encode.go with modifications of time.Time support. +// TODO: add more test coverage. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflectTime: + return v.Interface().(time.Time).IsZero() + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} + func (s *Section) reflectFrom(val reflect.Value) error { if val.Kind() == reflect.Ptr { val = val.Elem() @@ -338,13 +363,18 @@ func (s *Section) reflectFrom(val reflect.Value) error { continue } - fieldName := s.parseFieldName(tpField.Name, tag) + opts := strings.SplitN(tag, ",", 2) + if len(opts) == 2 && opts[1] == "omitempty" && isEmptyValue(field) { + continue + } + + fieldName := s.parseFieldName(tpField.Name, opts[0]) if len(fieldName) == 0 || !field.CanSet() { continue } if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) || - (tpField.Type.Kind() == reflect.Struct && tpField.Type.Kind() != reflectTime) { + (tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") { // Note: The only error here is section doesn't exist. sec, err := s.f.GetSection(fieldName) if err != nil { @@ -352,7 +382,7 @@ func (s *Section) reflectFrom(val reflect.Value) error { sec, _ = s.f.NewSection(fieldName) } if err = sec.reflectFrom(field); err != nil { - return fmt.Errorf("error reflecting field(%s): %v", fieldName, err) + return fmt.Errorf("error reflecting field (%s): %v", fieldName, err) } continue } @@ -363,7 +393,7 @@ func (s *Section) reflectFrom(val reflect.Value) error { key, _ = s.NewKey(fieldName, "") } if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil { - return fmt.Errorf("error reflecting field(%s): %v", fieldName, err) + return fmt.Errorf("error reflecting field (%s): %v", fieldName, err) } } diff --git a/vendor/github.com/go-ldap/ldap/control.go b/vendor/github.com/go-ldap/ldap/control.go index 4bd84c993..5c62118d4 100644 --- a/vendor/github.com/go-ldap/ldap/control.go +++ b/vendor/github.com/go-ldap/ldap/control.go @@ -89,7 +89,7 @@ func (c *ControlPaging) Encode() *ber.Packet { p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)") seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value") - seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size")) + seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(c.PagingSize), "Paging Size")) cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie") cookie.Value = c.Cookie cookie.Data.Write(c.Cookie) @@ -254,19 +254,54 @@ func FindControl(controls []Control, controlType string) Control { // DecodeControl returns a control read from the given packet, or nil if no recognized control can be made func DecodeControl(packet *ber.Packet) Control { - ControlType := packet.Children[0].Value.(string) - Criticality := false + var ( + ControlType = "" + Criticality = false + value *ber.Packet + ) + + switch len(packet.Children) { + case 0: + // at least one child is required for control type + return nil + + case 1: + // just type, no criticality or value + packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" + ControlType = packet.Children[0].Value.(string) + + case 2: + packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" + ControlType = packet.Children[0].Value.(string) + + // Children[1] could be criticality or value (both are optional) + // duck-type on whether this is a boolean + if _, ok := packet.Children[1].Value.(bool); ok { + packet.Children[1].Description = "Criticality" + Criticality = packet.Children[1].Value.(bool) + } else { + packet.Children[1].Description = "Control Value" + value = packet.Children[1] + } + + case 3: + packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" + ControlType = packet.Children[0].Value.(string) - packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" - value := packet.Children[1] - if len(packet.Children) == 3 { - value = packet.Children[2] packet.Children[1].Description = "Criticality" Criticality = packet.Children[1].Value.(bool) + + packet.Children[2].Description = "Control Value" + value = packet.Children[2] + + default: + // more than 3 children is invalid + return nil } - value.Description = "Control Value" switch ControlType { + case ControlTypeManageDsaIT: + return NewControlManageDsaIT(Criticality) case ControlTypePaging: value.Description += " (Paging)" c := new(ControlPaging) @@ -341,13 +376,16 @@ func DecodeControl(packet *ber.Packet) Control { c.Expire = expire value.Value = c.Expire + return c + default: + c := new(ControlString) + c.ControlType = ControlType + c.Criticality = Criticality + if value != nil { + c.ControlValue = value.Value.(string) + } return c } - c := new(ControlString) - c.ControlType = ControlType - c.Criticality = Criticality - c.ControlValue = value.Value.(string) - return c } // NewControlString returns a generic control diff --git a/vendor/github.com/go-sql-driver/mysql/packets.go b/vendor/github.com/go-sql-driver/mysql/packets.go index 8d9166578..602539942 100644 --- a/vendor/github.com/go-sql-driver/mysql/packets.go +++ b/vendor/github.com/go-sql-driver/mysql/packets.go @@ -729,16 +729,19 @@ func (rows *textRows) readRow(dest []driver.Value) error { func (mc *mysqlConn) readUntilEOF() error { for { data, err := mc.readPacket() - - // No Err and no EOF Packet - if err == nil && data[0] != iEOF { - continue - } - if err == nil && data[0] == iEOF && len(data) == 5 { - mc.status = readStatus(data[3:]) + if err != nil { + return err } - return err // Err or EOF + switch data[0] { + case iERR: + return mc.handleErrorPacket(data) + case iEOF: + if len(data) == 5 { + mc.status = readStatus(data[3:]) + } + return nil + } } } diff --git a/vendor/github.com/gocql/gocql/AUTHORS b/vendor/github.com/gocql/gocql/AUTHORS index 33a6393c1..da600422d 100644 --- a/vendor/github.com/gocql/gocql/AUTHORS +++ b/vendor/github.com/gocql/gocql/AUTHORS @@ -73,3 +73,8 @@ Michael Highstead Sarah Brown Caleb Doxsey Frederic Hemery +Pekka Enberg +Mark M +Bartosz Burclaf +Marcus King +Andrew de Andrade diff --git a/vendor/github.com/gocql/gocql/README.md b/vendor/github.com/gocql/gocql/README.md index b970fb947..ef53f301e 100644 --- a/vendor/github.com/gocql/gocql/README.md +++ b/vendor/github.com/gocql/gocql/README.md @@ -201,6 +201,7 @@ The following community maintained tools are known to integrate with gocql: * [gocassa](https://github.com/hailocab/gocassa) provides query building, adds data binding, and provides easy-to-use "recipe" tables for common query use-cases. * [gocqltable](https://github.com/kristoiv/gocqltable) is a wrapper around gocql that aims to simplify common operations whilst working the library. * [gockle](https://github.com/willfaught/gockle) provides simple, mockable interfaces that wrap gocql types +* [scylladb](https://github.com/scylladb/scylla) is a fast Apache Cassandra-compatible NoSQL database Other Projects -------------- diff --git a/vendor/github.com/gocql/gocql/cluster.go b/vendor/github.com/gocql/gocql/cluster.go index a29bf80b1..3b1e6c77b 100644 --- a/vendor/github.com/gocql/gocql/cluster.go +++ b/vendor/github.com/gocql/gocql/cluster.go @@ -10,7 +10,7 @@ import ( ) // PoolConfig configures the connection pool used by the driver, it defaults to -// using a round robbin host selection policy and a round robbin connection selection +// using a round-robin host selection policy and a round-robin connection selection // policy for each host. type PoolConfig struct { // HostSelectionPolicy sets the policy for selecting which host to use for a @@ -23,9 +23,9 @@ func (p PoolConfig) buildPool(session *Session) *policyConnPool { } type DiscoveryConfig struct { - // If not empty will filter all discoverred hosts to a single Data Centre (default: "") + // If not empty will filter all discovered hosts to a single Data Centre (default: "") DcFilter string - // If not empty will filter all discoverred hosts to a single Rack (default: "") + // If not empty will filter all discovered hosts to a single Rack (default: "") RackFilter string // ignored Sleep time.Duration @@ -44,8 +44,8 @@ func (d DiscoveryConfig) matchFilter(host *HostInfo) bool { } // ClusterConfig is a struct to configure the default cluster implementation -// of gocoql. It has a varity of attributes that can be used to modify the -// behavior to fit the most common use cases. Applications that requre a +// of gocoql. It has a variety of attributes that can be used to modify the +// behavior to fit the most common use cases. Applications that require a // different setup must implement their own cluster. type ClusterConfig struct { Hosts []string // addresses for the initial connections @@ -79,7 +79,7 @@ type ClusterConfig struct { // receiving a schema change frame. (deault: 60s) MaxWaitSchemaAgreement time.Duration - // HostFilter will filter all incoming events for host, any which dont pass + // HostFilter will filter all incoming events for host, any which don't pass // the filter will be ignored. If set will take precedence over any options set // via Discovery HostFilter HostFilter @@ -113,7 +113,7 @@ type ClusterConfig struct { // DisableSkipMetadata will override the internal result metadata cache so that the driver does not // send skip_metadata for queries, this means that the result will always contain // the metadata to parse the rows and will not reuse the metadata from the prepared - // staement. + // statement. // // See https://issues.apache.org/jira/browse/CASSANDRA-10786 DisableSkipMetadata bool diff --git a/vendor/github.com/gocql/gocql/frame.go b/vendor/github.com/gocql/gocql/frame.go index 76c250ce2..e58736560 100644 --- a/vendor/github.com/gocql/gocql/frame.go +++ b/vendor/github.com/gocql/gocql/frame.go @@ -205,6 +205,22 @@ func ParseConsistency(s string) Consistency { } } +// ParseConsistencyWrapper wraps gocql.ParseConsistency to provide an err +// return instead of a panic +func ParseConsistencyWrapper(s string) (consistency Consistency, err error) { + defer func() { + if r := recover(); r != nil { + var ok bool + err, ok = r.(error) + if !ok { + err = fmt.Errorf("ParseConsistencyWrapper: %v", r) + } + } + }() + consistency = ParseConsistency(s) + return consistency, nil +} + type SerialConsistency uint16 const ( diff --git a/vendor/github.com/gocql/gocql/helpers.go b/vendor/github.com/gocql/gocql/helpers.go index b34ee0a09..084d8ff26 100644 --- a/vendor/github.com/gocql/gocql/helpers.go +++ b/vendor/github.com/gocql/gocql/helpers.go @@ -247,7 +247,7 @@ func (iter *Iter) SliceMap() ([]map[string]interface{}, error) { } // MapScan takes a map[string]interface{} and populates it with a row -// That is returned from cassandra. +// that is returned from cassandra. func (iter *Iter) MapScan(m map[string]interface{}) bool { if iter.err != nil { return false diff --git a/vendor/github.com/gocql/gocql/host_source.go b/vendor/github.com/gocql/gocql/host_source.go index 0f20e8c86..08fb02289 100644 --- a/vendor/github.com/gocql/gocql/host_source.go +++ b/vendor/github.com/gocql/gocql/host_source.go @@ -234,7 +234,7 @@ func (h *HostInfo) update(from *HostInfo) { } func (h *HostInfo) IsUp() bool { - return h.State() == NodeUp + return h != nil && h.State() == NodeUp } func (h *HostInfo) String() string { @@ -272,6 +272,22 @@ func checkSystemLocal(control *controlConn) (bool, error) { return true, nil } +// Returns true if we are using system_schema.keyspaces instead of system.schema_keyspaces +func checkSystemSchema(control *controlConn) (bool, error) { + iter := control.query("SELECT * FROM system_schema.keyspaces") + if err := iter.err; err != nil { + if errf, ok := err.(*errorFrame); ok { + if errf.code == errReadFailure { + return false, nil + } + } + + return false, err + } + + return true, nil +} + func (r *ringDescriber) GetHosts() (hosts []*HostInfo, partitioner string, err error) { r.mu.Lock() defer r.mu.Unlock() diff --git a/vendor/github.com/gocql/gocql/marshal.go b/vendor/github.com/gocql/gocql/marshal.go index c76bd5935..b8f543f57 100644 --- a/vendor/github.com/gocql/gocql/marshal.go +++ b/vendor/github.com/gocql/gocql/marshal.go @@ -1651,6 +1651,9 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error { udt := info.(UDTTypeInfo) for _, e := range udt.Elements { + if len(data) == 0 { + return nil + } size := readInt(data[:4]) data = data[4:] @@ -1689,6 +1692,9 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error { m := *v for _, e := range udt.Elements { + if len(data) == 0 { + return nil + } size := readInt(data[:4]) data = data[4:] diff --git a/vendor/github.com/gocql/gocql/policies.go b/vendor/github.com/gocql/gocql/policies.go index f03f9f482..82cb10e0e 100644 --- a/vendor/github.com/gocql/gocql/policies.go +++ b/vendor/github.com/gocql/gocql/policies.go @@ -13,7 +13,7 @@ import ( "github.com/hailocab/go-hostpool" ) -// cowHostList implements a copy on write host list, its equivilent type is []*HostInfo +// cowHostList implements a copy on write host list, its equivalent type is []*HostInfo type cowHostList struct { list atomic.Value mu sync.Mutex @@ -263,9 +263,6 @@ type tokenAwareHostPolicy struct { } func (t *tokenAwareHostPolicy) SetPartitioner(partitioner string) { - t.mu.Lock() - defer t.mu.Unlock() - if t.partitioner != partitioner { t.fallback.SetPartitioner(partitioner) t.partitioner = partitioner @@ -278,18 +275,14 @@ func (t *tokenAwareHostPolicy) AddHost(host *HostInfo) { t.hosts.add(host) t.fallback.AddHost(host) - t.mu.Lock() t.resetTokenRing() - t.mu.Unlock() } func (t *tokenAwareHostPolicy) RemoveHost(addr string) { t.hosts.remove(addr) t.fallback.RemoveHost(addr) - t.mu.Lock() t.resetTokenRing() - t.mu.Unlock() } func (t *tokenAwareHostPolicy) HostUp(host *HostInfo) { @@ -301,6 +294,9 @@ func (t *tokenAwareHostPolicy) HostDown(addr string) { } func (t *tokenAwareHostPolicy) resetTokenRing() { + t.mu.Lock() + defer t.mu.Unlock() + if t.partitioner == "" { // partitioner not yet set return @@ -377,7 +373,7 @@ func (t *tokenAwareHostPolicy) Pick(qry ExecutableQuery) NextHost { // // Create host selection policy using a simple host pool // cluster.PoolConfig.HostSelectionPolicy = HostPoolHostPolicy(hostpool.New(nil)) // -// // Create host selection policy using an epsilon greddy pool +// // Create host selection policy using an epsilon greedy pool // cluster.PoolConfig.HostSelectionPolicy = HostPoolHostPolicy( // hostpool.NewEpsilonGreedy(nil, 0, &hostpool.LinearEpsilonValueCalculator{}), // ) @@ -411,18 +407,20 @@ func (r *hostPoolHostPolicy) AddHost(host *HostInfo) { r.mu.Lock() defer r.mu.Unlock() - if _, ok := r.hostMap[host.Peer()]; ok { + // If the host addr is present and isn't nil return + if h, ok := r.hostMap[host.Peer()]; ok && h != nil{ return } - - hosts := make([]string, 0, len(r.hostMap)+1) + // otherwise, add the host to the map + r.hostMap[host.Peer()] = host + // and construct a new peer list to give to the HostPool + hosts := make([]string, 0, len(r.hostMap)) for addr := range r.hostMap { hosts = append(hosts, addr) } - hosts = append(hosts, host.Peer()) r.hp.SetHosts(hosts) - r.hostMap[host.Peer()] = host + } func (r *hostPoolHostPolicy) RemoveHost(addr string) { diff --git a/vendor/github.com/gocql/gocql/query_executor.go b/vendor/github.com/gocql/gocql/query_executor.go index 1aa397506..08b50d38c 100644 --- a/vendor/github.com/gocql/gocql/query_executor.go +++ b/vendor/github.com/gocql/gocql/query_executor.go @@ -24,7 +24,7 @@ func (q *queryExecutor) executeQuery(qry ExecutableQuery) (*Iter, error) { var iter *Iter for hostResponse := hostIter(); hostResponse != nil; hostResponse = hostIter() { host := hostResponse.Info() - if !host.IsUp() { + if host == nil || !host.IsUp() { continue } diff --git a/vendor/github.com/gocql/gocql/session.go b/vendor/github.com/gocql/gocql/session.go index d41309384..936704881 100644 --- a/vendor/github.com/gocql/gocql/session.go +++ b/vendor/github.com/gocql/gocql/session.go @@ -66,6 +66,8 @@ type Session struct { cfg ClusterConfig + quit chan struct{} + closeMu sync.RWMutex isClosed bool } @@ -183,6 +185,8 @@ func NewSession(cfg ClusterConfig) (*Session, error) { } } + s.quit = make(chan struct{}) + if cfg.ReconnectInterval > 0 { go s.reconnectDownedHosts(cfg.ReconnectInterval) } @@ -195,31 +199,46 @@ func NewSession(cfg ClusterConfig) (*Session, error) { return nil, ErrNoConnectionsStarted } - s.useSystemSchema = hosts[0].Version().Major >= 3 + // If we disable the initial host lookup, we need to still check if the + // cluster is using the newer system schema or not... however, if control + // connection is disable, we really have no choice, so we just make our + // best guess... + if !cfg.disableControlConn && cfg.DisableInitialHostLookup { + newer, _ := checkSystemSchema(s.control) + s.useSystemSchema = newer + } else { + s.useSystemSchema = hosts[0].Version().Major >= 3 + } return s, nil } func (s *Session) reconnectDownedHosts(intv time.Duration) { - for !s.Closed() { - time.Sleep(intv) + reconnectTicker := time.NewTicker(intv) + defer reconnectTicker.Stop() - hosts := s.ring.allHosts() + for { + select { + case <-reconnectTicker.C: + hosts := s.ring.allHosts() + + // Print session.ring for debug. + if gocqlDebug { + buf := bytes.NewBufferString("Session.ring:") + for _, h := range hosts { + buf.WriteString("[" + h.Peer() + ":" + h.State().String() + "]") + } + log.Println(buf.String()) + } - // Print session.ring for debug. - if gocqlDebug { - buf := bytes.NewBufferString("Session.ring:") for _, h := range hosts { - buf.WriteString("[" + h.Peer() + ":" + h.State().String() + "]") + if h.IsUp() { + continue + } + s.handleNodeUp(net.ParseIP(h.Peer()), h.Port(), true) } - log.Println(buf.String()) - } - - for _, h := range hosts { - if h.IsUp() { - continue - } - s.handleNodeUp(net.ParseIP(h.Peer()), h.Port(), true) + case <-s.quit: + return } } } @@ -332,6 +351,10 @@ func (s *Session) Close() { if s.schemaEvents != nil { s.schemaEvents.stop() } + + if s.quit != nil { + close(s.quit) + } } func (s *Session) Closed() bool { @@ -1141,7 +1164,7 @@ func (iter *Iter) PageState() []byte { } // NumRows returns the number of rows in this pagination, it will update when new -// pages are fetcehd, it is not the value of the total number of rows this iter +// pages are fetched, it is not the value of the total number of rows this iter // will return unless there is only a single page returned. func (iter *Iter) NumRows() int { return iter.numRows diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go index 8b16f951c..2ed1cf596 100644 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -54,13 +54,17 @@ Equality is defined in this way: in a proto3 .proto file, fields are not "set"; specifically, zero length proto3 "bytes" fields are equal (nil == {}). - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal (a "bytes" field, - although represented by []byte, is not a repeated field) + and their corresponding elements are equal. Note a "bytes" field, + although represented by []byte, is not a repeated field and the + rule for the scalar fields described above applies. - Two unset fields are equal. - Two unknown field sets are equal if their current encoded state is equal. - Two extension sets are equal iff they have corresponding elements that are pairwise equal. + - Two map fields are equal iff their lengths are the same, + and they contain the same set of elements. Zero-length map + fields are equal. - Every other combination of things are not equal. The return value is undefined if a and b are not protocol buffers. diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index 482f3e97e..6b9b36374 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -500,6 +500,9 @@ func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { registeredExtensions := RegisteredExtensions(pb) emap, mu := epb.extensionsRead() + if emap == nil { + return nil, nil + } mu.Lock() defer mu.Unlock() extensions := make([]*ExtensionDesc, 0, len(emap)) diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go index 170b8e87d..ac4ddbc07 100644 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -308,7 +308,7 @@ func GetStats() Stats { return stats } // temporary Buffer and are fine for most applications. type Buffer struct { buf []byte // encode/decode byte stream - index int // write point + index int // read point // pools of basic types to amortize allocation. bools []bool diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go index 69ddda8d4..ec2289c00 100644 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -844,7 +844,15 @@ func RegisterType(x Message, name string) { } // MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } +func MessageName(x Message) string { + type xname interface { + XXX_MessageName() string + } + if m, ok := x.(xname); ok { + return m.XXX_MessageName() + } + return revProtoTypes[reflect.TypeOf(x)] +} // MessageType returns the message type (pointer to struct) for a named message. func MessageType(name string) reflect.Type { return protoTypes[name] } diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go index 0b8c59f74..4fd053129 100644 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -44,6 +44,9 @@ import ( "unicode/utf8" ) +// Error string emitted when deserializing Any and fields are already set +const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" + type ParseError struct { Message string Line int // 1-based line number @@ -508,8 +511,16 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { if err != nil { return p.errorf("failed to marshal message of type %q: %v", messageName, err) } + if fieldSet["type_url"] { + return p.errorf(anyRepeatedlyUnpacked, "type_url") + } + if fieldSet["value"] { + return p.errorf(anyRepeatedlyUnpacked, "value") + } sv.FieldByName("TypeUrl").SetString(extName) sv.FieldByName("Value").SetBytes(b) + fieldSet["type_url"] = true + fieldSet["value"] = true continue } @@ -781,12 +792,12 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error { fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) return p.readAny(fv.Index(fv.Len()-1), props) case reflect.Bool: - // Either "true", "false", 1 or 0. + // true/1/t/True or false/f/0/False. switch tok.value { - case "true", "1": + case "true", "1", "t", "True": fv.SetBool(true) return nil - case "false", "0": + case "false", "0", "f", "False": fv.SetBool(false) return nil } diff --git a/vendor/github.com/google/go-github/github/authorizations.go b/vendor/github.com/google/go-github/github/authorizations.go index 58fcc4e5d..35ce9a97b 100644 --- a/vendor/github.com/google/go-github/github/authorizations.go +++ b/vendor/github.com/google/go-github/github/authorizations.go @@ -398,7 +398,7 @@ func (s *AuthorizationsService) DeleteGrant(id int) (*Response, error) { return s.client.Do(req, nil) } -// Create an impersonation OAuth token. +// CreateImpersonation creates an impersonation OAuth token. // // This requires admin permissions. With the returned Authorization.Token // you can e.g. create or delete a user's public SSH key. NOTE: creating a @@ -420,7 +420,7 @@ func (s *AuthorizationsService) CreateImpersonation(username string, authReq *Au return a, resp, err } -// Delete an impersonation OAuth token. +// DeleteImpersonation deletes an impersonation OAuth token. // // NOTE: there can be only one at a time. // diff --git a/vendor/github.com/google/go-github/github/doc.go b/vendor/github.com/google/go-github/github/doc.go index ba7b0895e..2b61068a1 100644 --- a/vendor/github.com/google/go-github/github/doc.go +++ b/vendor/github.com/google/go-github/github/doc.go @@ -22,8 +22,8 @@ Some API methods have optional parameters that can be passed. For example: client := github.NewClient(nil) - // list recently updated repositories for org "github" - opt := &github.RepositoryListByOrgOptions{Sort: "updated"} + // list public repositories for org "github" + opt := &github.RepositoryListByOrgOptions{Type: "public"} repos, _, err := client.Repositories.ListByOrg("github", opt) The services of a client divide the API into logical chunks and correspond to 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 f3e163d27..20f509a81 100644 --- a/vendor/github.com/google/go-github/github/event_types.go +++ b/vendor/github.com/google/go-github/github/event_types.go @@ -123,8 +123,9 @@ type GollumEvent struct { Sender *User `json:"sender,omitempty"` } -// DEPRECATED: IssueActivityEvent represents the payload delivered by Issue webhook -// Use IssuesEvent instead. +// IssueActivityEvent represents the payload delivered by Issue webhook. +// +// Deprecated: Use IssuesEvent instead. type IssueActivityEvent struct { Action *string `json:"action,omitempty"` Issue *Issue `json:"issue,omitempty"` diff --git a/vendor/github.com/google/go-github/github/gists.go b/vendor/github.com/google/go-github/github/gists.go index 697fcb506..a3327f840 100644 --- a/vendor/github.com/google/go-github/github/gists.go +++ b/vendor/github.com/google/go-github/github/gists.go @@ -42,6 +42,7 @@ type GistFilename string type GistFile struct { Size *int `json:"size,omitempty"` Filename *string `json:"filename,omitempty"` + Type *string `json:"type,omitempty"` RawURL *string `json:"raw_url,omitempty"` Content *string `json:"content,omitempty"` } diff --git a/vendor/github.com/google/go-github/github/github.go b/vendor/github.com/google/go-github/github/github.go index 591bc5409..8448982e7 100644 --- a/vendor/github.com/google/go-github/github/github.go +++ b/vendor/github.com/google/go-github/github/github.go @@ -84,6 +84,9 @@ const ( // https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/ mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json" + + // https://developer.github.com/v3/repos/traffic/ + mediaTypeTrafficPreview = "application/vnd.github.spiderman-preview+json" ) // A Client manages communication with the GitHub API. @@ -414,7 +417,7 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { // checkRateLimitBeforeDo does not make any network calls, but uses existing knowledge from // current client state in order to quickly check if *RateLimitError can be immediately returned -// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unneccessarily. +// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unnecessarily. // Otherwise it returns nil, and Client.Do should proceed normally. func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rateLimitCategory) error { c.rateMu.Lock() @@ -638,6 +641,8 @@ func category(path string) rateLimitCategory { } } +// RateLimit returns the core rate limit for the current client. +// // Deprecated: RateLimit is deprecated, use RateLimits instead. func (c *Client) RateLimit() (*Rate, *Response, error) { limits, resp, err := c.RateLimits() diff --git a/vendor/github.com/google/go-github/github/migrations_source_import.go b/vendor/github.com/google/go-github/github/migrations_source_import.go index 6ed4acfbd..44505fa91 100644 --- a/vendor/github.com/google/go-github/github/migrations_source_import.go +++ b/vendor/github.com/google/go-github/github/migrations_source_import.go @@ -163,7 +163,7 @@ func (s *MigrationService) StartImport(owner, repo string, in *Import) (*Import, return out, resp, err } -// QueryImport queries for the status and progress of an ongoing repository import. +// ImportProgress queries for the status and progress of an ongoing repository import. // // GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-import-progress func (s *MigrationService) ImportProgress(owner, repo string) (*Import, *Response, error) { diff --git a/vendor/github.com/google/go-github/github/orgs.go b/vendor/github.com/google/go-github/github/orgs.go index e71055c00..d137e3e82 100644 --- a/vendor/github.com/google/go-github/github/orgs.go +++ b/vendor/github.com/google/go-github/github/orgs.go @@ -27,6 +27,7 @@ type Organization struct { Blog *string `json:"blog,omitempty"` Location *string `json:"location,omitempty"` Email *string `json:"email,omitempty"` + Description *string `json:"description,omitempty"` PublicRepos *int `json:"public_repos,omitempty"` PublicGists *int `json:"public_gists,omitempty"` Followers *int `json:"followers,omitempty"` @@ -45,6 +46,8 @@ type Organization struct { // API URLs URL *string `json:"url,omitempty"` EventsURL *string `json:"events_url,omitempty"` + HooksURL *string `json:"hooks_url,omitempty"` + IssuesURL *string `json:"issues_url,omitempty"` MembersURL *string `json:"members_url,omitempty"` PublicMembersURL *string `json:"public_members_url,omitempty"` ReposURL *string `json:"repos_url,omitempty"` diff --git a/vendor/github.com/google/go-github/github/pulls.go b/vendor/github.com/google/go-github/github/pulls.go index 0900766e4..061150795 100644 --- a/vendor/github.com/google/go-github/github/pulls.go +++ b/vendor/github.com/google/go-github/github/pulls.go @@ -42,7 +42,8 @@ type PullRequest struct { StatusesURL *string `json:"statuses_url,omitempty"` DiffURL *string `json:"diff_url,omitempty"` PatchURL *string `json:"patch_url,omitempty"` - Assignee *User `json:"assignee,omitempty"` // probably only in webhooks + Assignee *User `json:"assignee,omitempty"` + Assignees []*User `json:"assignees,omitempty"` Head *PullRequestBranch `json:"head,omitempty"` Base *PullRequestBranch `json:"base,omitempty"` diff --git a/vendor/github.com/google/go-github/github/repos.go b/vendor/github.com/google/go-github/github/repos.go index fb402eef8..2bcaacc3f 100644 --- a/vendor/github.com/google/go-github/github/repos.go +++ b/vendor/github.com/google/go-github/github/repos.go @@ -54,6 +54,7 @@ type Repository struct { Private *bool `json:"private"` HasIssues *bool `json:"has_issues"` HasWiki *bool `json:"has_wiki"` + HasPages *bool `json:"has_pages"` HasDownloads *bool `json:"has_downloads"` // Creating an organization repository. Required for non-owners. TeamID *int `json:"team_id"` @@ -70,6 +71,7 @@ type Repository struct { CompareURL *string `json:"compare_url,omitempty"` ContentsURL *string `json:"contents_url,omitempty"` ContributorsURL *string `json:"contributors_url,omitempty"` + DeploymentsURL *string `json:"deployments_url,omitempty"` DownloadsURL *string `json:"downloads_url,omitempty"` EventsURL *string `json:"events_url,omitempty"` ForksURL *string `json:"forks_url,omitempty"` diff --git a/vendor/github.com/google/go-github/github/repos_traffic.go b/vendor/github.com/google/go-github/github/repos_traffic.go new file mode 100644 index 000000000..b6c8d83bc --- /dev/null +++ b/vendor/github.com/google/go-github/github/repos_traffic.go @@ -0,0 +1,173 @@ +// 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" + "strconv" + "time" +) + +// TrafficReferrer represent information about traffic from a referrer . +type TrafficReferrer struct { + Referrer *string `json:"referrer,omitempty"` + Count *int `json:"count,omitempty"` + Uniques *int `json:"uniques,omitempty"` +} + +// TrafficPath represent information about the traffic on a path of the repo. +type TrafficPath struct { + Path *string `json:"path,omitempty"` + Title *string `json:"title,omitempty"` + Count *int `json:"count,omitempty"` + Uniques *int `json:"uniques,omitempty"` +} + +// TimestampMS represents a timestamp as used in datapoint. +// +// It's only used to parse the result given by the API which are unix timestamp in milliseonds. +type TimestampMS struct { + time.Time +} + +// UnmarshalJSON parse unix timestamp. +func (t *TimestampMS) UnmarshalJSON(b []byte) error { + s := string(b) + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + // We can drop the reaminder as returned values are days and it will always be 0 + *t = TimestampMS{time.Unix(i/1000, 0)} + return nil +} + +// TrafficData represent information about a specific timestamp in views or clones list. +type TrafficData struct { + Timestamp *TimestampMS `json:"timestamp,omitempty"` + Count *int `json:"count,omitempty"` + Uniques *int `json:"uniques,omitempty"` +} + +// TrafficViews represent information about the number of views in the last 14 days. +type TrafficViews struct { + Views []*TrafficData `json:"views,omitempty"` + Count *int `json:"count,omitempty"` + Uniques *int `json:"uniques,omitempty"` +} + +// TrafficClones represent information about the number of clones in the last 14 days. +type TrafficClones struct { + Clones []*TrafficData `json:"clones,omitempty"` + Count *int `json:"count,omitempty"` + Uniques *int `json:"uniques,omitempty"` +} + +// TrafficBreakdownOptions specifies the parameters to methods that support breakdown per day or week. +// Can be one of: day, week. Default: day. +type TrafficBreakdownOptions struct { + Per string `url:"per,omitempty"` +} + +// ListTrafficReferrers list the top 10 referrers over the last 14 days. +// +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-referrers +func (s *RepositoriesService) ListTrafficReferrers(owner, repo string) ([]*TrafficReferrer, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/traffic/popular/referrers", owner, repo) + + 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", mediaTypeTrafficPreview) + + trafficReferrers := new([]*TrafficReferrer) + resp, err := s.client.Do(req, &trafficReferrers) + if err != nil { + return nil, resp, err + } + + return *trafficReferrers, resp, err +} + +// ListTrafficPaths list the top 10 popular content over the last 14 days. +// +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-paths +func (s *RepositoriesService) ListTrafficPaths(owner, repo string) ([]*TrafficPath, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/traffic/popular/paths", owner, repo) + + 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", mediaTypeTrafficPreview) + + var paths = new([]*TrafficPath) + resp, err := s.client.Do(req, &paths) + if err != nil { + return nil, resp, err + } + + return *paths, resp, err +} + +// ListTrafficViews get total number of views for the last 14 days and breaks it down either per day or week. +// +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views +func (s *RepositoriesService) ListTrafficViews(owner, repo string, opt *TrafficBreakdownOptions) (*TrafficViews, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/traffic/views", 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", mediaTypeTrafficPreview) + + trafficViews := new(TrafficViews) + resp, err := s.client.Do(req, &trafficViews) + if err != nil { + return nil, resp, err + } + + return trafficViews, resp, err +} + +// ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days. +// +// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views +func (s *RepositoriesService) ListTrafficClones(owner, repo string, opt *TrafficBreakdownOptions) (*TrafficClones, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/traffic/clones", 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", mediaTypeTrafficPreview) + + trafficClones := new(TrafficClones) + resp, err := s.client.Do(req, &trafficClones) + if err != nil { + return nil, resp, err + } + + return trafficClones, resp, err +} diff --git a/vendor/github.com/google/go-github/github/search.go b/vendor/github.com/google/go-github/github/search.go index 0c7ffcb69..579a57d7f 100644 --- a/vendor/github.com/google/go-github/github/search.go +++ b/vendor/github.com/google/go-github/github/search.go @@ -40,8 +40,9 @@ type SearchOptions struct { // RepositoriesSearchResult represents the result of a repositories search. type RepositoriesSearchResult struct { - Total *int `json:"total_count,omitempty"` - Repositories []Repository `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Repositories []Repository `json:"items,omitempty"` } // Repositories searches repositories via various criteria. @@ -55,8 +56,9 @@ func (s *SearchService) Repositories(query string, opt *SearchOptions) (*Reposit // IssuesSearchResult represents the result of an issues search. type IssuesSearchResult struct { - Total *int `json:"total_count,omitempty"` - Issues []Issue `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Issues []Issue `json:"items,omitempty"` } // Issues searches issues via various criteria. @@ -68,10 +70,11 @@ func (s *SearchService) Issues(query string, opt *SearchOptions) (*IssuesSearchR return result, resp, err } -// UsersSearchResult represents the result of an issues search. +// UsersSearchResult represents the result of a users search. type UsersSearchResult struct { - Total *int `json:"total_count,omitempty"` - Users []User `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + Users []User `json:"items,omitempty"` } // Users searches users via various criteria. @@ -102,10 +105,11 @@ func (tm TextMatch) String() string { return Stringify(tm) } -// CodeSearchResult represents the result of an code search. +// CodeSearchResult represents the result of a code search. type CodeSearchResult struct { - Total *int `json:"total_count,omitempty"` - CodeResults []CodeResult `json:"items,omitempty"` + Total *int `json:"total_count,omitempty"` + IncompleteResults *bool `json:"incomplete_results,omitempty"` + CodeResults []CodeResult `json:"items,omitempty"` } // CodeResult represents a single search result. diff --git a/vendor/github.com/hashicorp/consul/api/agent.go b/vendor/github.com/hashicorp/consul/api/agent.go index 3df013cc5..87a6c1001 100644 --- a/vendor/github.com/hashicorp/consul/api/agent.go +++ b/vendor/github.com/hashicorp/consul/api/agent.go @@ -62,8 +62,7 @@ type AgentCheckRegistration struct { AgentServiceCheck } -// AgentServiceCheck is used to create an associated -// check for a service +// AgentServiceCheck is used to define a node or service level check type AgentServiceCheck struct { Script string `json:",omitempty"` DockerContainerID string `json:",omitempty"` @@ -74,6 +73,14 @@ type AgentServiceCheck struct { HTTP string `json:",omitempty"` TCP string `json:",omitempty"` Status string `json:",omitempty"` + + // In Consul 0.7 and later, checks that are associated with a service + // may also contain this optional DeregisterCriticalServiceAfter field, + // which is a timeout in the same Go time format as Interval and TTL. If + // a check is in the critical state for more than this configured value, + // then its associated service (and all of its associated checks) will + // automatically be deregistered. + DeregisterCriticalServiceAfter string `json:",omitempty"` } type AgentServiceChecks []*AgentServiceCheck diff --git a/vendor/github.com/hashicorp/consul/api/api.go b/vendor/github.com/hashicorp/consul/api/api.go index b0fe6d83b..dd811fde4 100644 --- a/vendor/github.com/hashicorp/consul/api/api.go +++ b/vendor/github.com/hashicorp/consul/api/api.go @@ -80,6 +80,9 @@ type QueryMeta struct { // How long did the request take RequestTime time.Duration + + // Is address translation enabled for HTTP responses on this agent + AddressTranslationEnabled bool } // WriteMeta is used to return meta data about a write @@ -542,6 +545,15 @@ func parseQueryMeta(resp *http.Response, q *QueryMeta) error { default: q.KnownLeader = false } + + // Parse X-Consul-Translate-Addresses + switch header.Get("X-Consul-Translate-Addresses") { + case "true": + q.AddressTranslationEnabled = true + default: + q.AddressTranslationEnabled = false + } + return nil } diff --git a/vendor/github.com/hashicorp/consul/api/catalog.go b/vendor/github.com/hashicorp/consul/api/catalog.go index 52a00b304..337772ec0 100644 --- a/vendor/github.com/hashicorp/consul/api/catalog.go +++ b/vendor/github.com/hashicorp/consul/api/catalog.go @@ -1,13 +1,15 @@ package api type Node struct { - Node string - Address string + Node string + Address string + TaggedAddresses map[string]string } type CatalogService struct { Node string Address string + TaggedAddresses map[string]string ServiceID string ServiceName string ServiceAddress string @@ -22,11 +24,12 @@ type CatalogNode struct { } type CatalogRegistration struct { - Node string - Address string - Datacenter string - Service *AgentService - Check *AgentCheck + Node string + Address string + TaggedAddresses map[string]string + Datacenter string + Service *AgentService + Check *AgentCheck } type CatalogDeregistration struct { diff --git a/vendor/github.com/hashicorp/consul/api/health.go b/vendor/github.com/hashicorp/consul/api/health.go index 5bb403f55..74da949c8 100644 --- a/vendor/github.com/hashicorp/consul/api/health.go +++ b/vendor/github.com/hashicorp/consul/api/health.go @@ -8,7 +8,6 @@ const ( // HealthAny is special, and is used as a wild card, // not as a specific state. HealthAny = "any" - HealthUnknown = "unknown" HealthPassing = "passing" HealthWarning = "warning" HealthCritical = "critical" @@ -122,7 +121,6 @@ func (h *Health) State(state string, q *QueryOptions) ([]*HealthCheck, *QueryMet case HealthWarning: case HealthCritical: case HealthPassing: - case HealthUnknown: default: return nil, nil, fmt.Errorf("Unsupported state: %v", state) } diff --git a/vendor/github.com/hashicorp/consul/api/operator.go b/vendor/github.com/hashicorp/consul/api/operator.go new file mode 100644 index 000000000..48d74f3ca --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/operator.go @@ -0,0 +1,81 @@ +package api + +// Operator can be used to perform low-level operator tasks for Consul. +type Operator struct { + c *Client +} + +// Operator returns a handle to the operator endpoints. +func (c *Client) Operator() *Operator { + return &Operator{c} +} + +// RaftServer has information about a server in the Raft configuration. +type RaftServer struct { + // ID is the unique ID for the server. These are currently the same + // as the address, but they will be changed to a real GUID in a future + // release of Consul. + ID string + + // Node is the node name of the server, as known by Consul, or this + // will be set to "(unknown)" otherwise. + Node string + + // Address is the IP:port of the server, used for Raft communications. + Address string + + // Leader is true if this server is the current cluster leader. + Leader bool + + // Voter is true if this server has a vote in the cluster. This might + // be false if the server is staging and still coming online, or if + // it's a non-voting server, which will be added in a future release of + // Consul. + Voter bool +} + +// RaftConfigration is returned when querying for the current Raft configuration. +type RaftConfiguration struct { + // Servers has the list of servers in the Raft configuration. + Servers []*RaftServer + + // Index has the Raft index of this configuration. + Index uint64 +} + +// RaftGetConfiguration is used to query the current Raft peer set. +func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, error) { + r := op.c.newRequest("GET", "/v1/operator/raft/configuration") + r.setQueryOptions(q) + _, resp, err := requireOK(op.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out RaftConfiguration + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return &out, nil +} + +// RaftRemovePeerByAddress is used to kick a stale peer (one that it in the Raft +// quorum but no longer known to Serf or the catalog) by address in the form of +// "IP:port". +func (op *Operator) RaftRemovePeerByAddress(address string, q *WriteOptions) error { + r := op.c.newRequest("DELETE", "/v1/operator/raft/peer") + r.setWriteOptions(q) + + // TODO (slackpad) Currently we made address a query parameter. Once + // IDs are in place this will be DELETE /v1/operator/raft/peer/. + r.params.Set("address", string(address)) + + _, resp, err := requireOK(op.c.doRequest(r)) + if err != nil { + return err + } + + resp.Body.Close() + return nil +} diff --git a/vendor/github.com/hashicorp/go-multierror/Makefile b/vendor/github.com/hashicorp/go-multierror/Makefile new file mode 100644 index 000000000..b97cd6ed0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/Makefile @@ -0,0 +1,31 @@ +TEST?=./... + +default: test + +# test runs the test suite and vets the code. +test: generate + @echo "==> Running tests..." + @go list $(TEST) \ + | grep -v "/vendor/" \ + | xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS} + +# testrace runs the race checker +testrace: generate + @echo "==> Running tests (race)..." + @go list $(TEST) \ + | grep -v "/vendor/" \ + | xargs -n1 go test -timeout=60s -race ${TESTARGS} + +# updatedeps installs all the dependencies needed to run and build. +updatedeps: + @sh -c "'${CURDIR}/scripts/deps.sh' '${NAME}'" + +# generate runs `go generate` to build the dynamically generated source files. +generate: + @echo "==> Generating..." + @find . -type f -name '.DS_Store' -delete + @go list ./... \ + | grep -v "/vendor/" \ + | xargs -n1 go generate + +.PHONY: default test testrace updatedeps generate diff --git a/vendor/github.com/hashicorp/go-multierror/README.md b/vendor/github.com/hashicorp/go-multierror/README.md index e81be50e0..ead5830f7 100644 --- a/vendor/github.com/hashicorp/go-multierror/README.md +++ b/vendor/github.com/hashicorp/go-multierror/README.md @@ -1,5 +1,11 @@ # go-multierror +[![Build Status](http://img.shields.io/travis/hashicorp/go-multierror.svg?style=flat-square)][travis] +[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs] + +[travis]: https://travis-ci.org/hashicorp/go-multierror +[godocs]: https://godoc.org/github.com/hashicorp/go-multierror + `go-multierror` is a package for Go that provides a mechanism for representing a list of `error` values as a single `error`. diff --git a/vendor/github.com/hashicorp/go-retryablehttp/client.go b/vendor/github.com/hashicorp/go-retryablehttp/client.go index cec59b853..d0ec6b2ab 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/client.go +++ b/vendor/github.com/hashicorp/go-retryablehttp/client.go @@ -38,6 +38,10 @@ var ( // defaultClient is used for performing requests without explicitly making // a new client. It is purposely private to avoid modifications. defaultClient = NewClient() + + // We need to consume response bodies to maintain http connections, but + // limit the size we consume to respReadLimit. + respReadLimit = int64(4096) ) // LenReader is an interface implemented by many in-memory io.Reader's. Used @@ -93,6 +97,16 @@ type RequestLogHook func(*log.Logger, *http.Request, int) // from this method, this will affect the response returned from Do(). type ResponseLogHook func(*log.Logger, *http.Response) +// CheckRetry specifies a policy for handling retries. It is called +// following each request with the response and error values returned by +// the http.Client. If CheckRetry returns false, the Client stops retrying +// and returns the response to the caller. If CheckRetry returns an error, +// that error value is returned in lieu of the error from the request. The +// Client will close any response body when retrying, but if the retry is +// aborted it is up to the CheckResponse callback to properly close any +// response body before returning. +type CheckRetry func(resp *http.Response, err error) (bool, error) + // Client is used to make HTTP requests. It adds additional functionality // like automatic retries to tolerate minor outages. type Client struct { @@ -110,6 +124,10 @@ type Client struct { // ResponseLogHook allows a user-supplied function to be called // with the response from each HTTP request executed. ResponseLogHook ResponseLogHook + + // CheckRetry specifies the policy for handling retries, and is called + // after each request. The default policy is DefaultRetryPolicy. + CheckRetry CheckRetry } // NewClient creates a new Client with default settings. @@ -120,9 +138,27 @@ func NewClient() *Client { RetryWaitMin: defaultRetryWaitMin, RetryWaitMax: defaultRetryWaitMax, RetryMax: defaultRetryMax, + CheckRetry: DefaultRetryPolicy, } } +// DefaultRetryPolicy provides a default callback for Client.CheckRetry, which +// will retry on connection errors and server errors. +func DefaultRetryPolicy(resp *http.Response, err error) (bool, error) { + if err != nil { + return true, err + } + // Check the response code. We retry on 500-range responses to allow + // the server time to recover, as 500's are typically not permanent + // errors and may relate to outages on the server side. This will catch + // invalid response codes as well, like 0 and 999. + if resp.StatusCode == 0 || resp.StatusCode >= 500 { + return true, nil + } + + return false, nil +} + // Do wraps calling an HTTP method with retries. func (c *Client) Do(req *Request) (*http.Response, error) { c.Logger.Printf("[DEBUG] %s %s", req.Method, req.URL) @@ -143,27 +179,34 @@ func (c *Client) Do(req *Request) (*http.Response, error) { // Attempt the request resp, err := c.HTTPClient.Do(req.Request) + + // Check if we should continue with retries. + checkOK, checkErr := c.CheckRetry(resp, err) + if err != nil { c.Logger.Printf("[ERR] %s %s request failed: %v", req.Method, req.URL, err) - goto RETRY - } - code = resp.StatusCode - - // Call the response logger function if provided. - if c.ResponseLogHook != nil { - c.ResponseLogHook(c.Logger, resp) + } else { + // Call this here to maintain the behavior of logging all requests, + // even if CheckRetry signals to stop. + if c.ResponseLogHook != nil { + // Call the response logger function if provided. + c.ResponseLogHook(c.Logger, resp) + } } - // Check the response code. We retry on 500-range responses to allow - // the server time to recover, as 500's are typically not permanent - // errors and may relate to outages on the server side. - if code%500 < 100 { - resp.Body.Close() - goto RETRY + // Now decide if we should continue. + if !checkOK { + if checkErr != nil { + err = checkErr + } + return resp, err + } + + // We're going to retry, consume any response to reuse the connection. + if err == nil { + c.drainBody(resp.Body) } - return resp, nil - RETRY: remain := c.RetryMax - i if remain == 0 { break @@ -182,6 +225,15 @@ func (c *Client) Do(req *Request) (*http.Response, error) { req.Method, req.URL, c.RetryMax+1) } +// Try to read the response body so we can reuse this connection. +func (c *Client) drainBody(body io.ReadCloser) { + defer body.Close() + _, err := io.Copy(ioutil.Discard, io.LimitReader(body, respReadLimit)) + if err != nil { + c.Logger.Printf("[ERR] error reading response body: %v", err) + } +} + // Get is a shortcut for doing a GET request without making a new client. func Get(url string) (*http.Response, error) { return defaultClient.Get(url) diff --git a/vendor/github.com/hashicorp/go-syslog/unix.go b/vendor/github.com/hashicorp/go-syslog/unix.go index 8b1af3ec0..6251c4e8c 100644 --- a/vendor/github.com/hashicorp/go-syslog/unix.go +++ b/vendor/github.com/hashicorp/go-syslog/unix.go @@ -1,4 +1,4 @@ -// +build linux darwin freebsd openbsd solaris +// +build linux darwin dragonfly freebsd netbsd openbsd solaris package gsyslog diff --git a/vendor/github.com/hashicorp/go-syslog/unsupported.go b/vendor/github.com/hashicorp/go-syslog/unsupported.go index 30a6d5c20..f52f0c26d 100644 --- a/vendor/github.com/hashicorp/go-syslog/unsupported.go +++ b/vendor/github.com/hashicorp/go-syslog/unsupported.go @@ -1,4 +1,4 @@ -// +build windows plan9 netbsd +// +build windows plan9 package gsyslog diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go index 68d097a1c..cb416b394 100644 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go @@ -47,7 +47,7 @@ func (c *LRU) Purge() { c.evictList.Init() } -// Add adds a value to the cache. Returns true if an eviction occured. +// Add adds a value to the cache. Returns true if an eviction occurred. func (c *LRU) Add(key, value interface{}) bool { // Check for existing item if ent, ok := c.items[key]; ok { diff --git a/vendor/github.com/hashicorp/hcl/README.md b/vendor/github.com/hashicorp/hcl/README.md index e292d5999..c8223326d 100644 --- a/vendor/github.com/hashicorp/hcl/README.md +++ b/vendor/github.com/hashicorp/hcl/README.md @@ -103,6 +103,16 @@ variable "ami" { description = "the AMI to use" } ``` +This would be equivalent to the following json: +``` json +{ + "variable": { + "ami": { + "description": "the AMI to use" + } + } +} +``` ## Thanks diff --git a/vendor/github.com/hashicorp/hcl/decoder.go b/vendor/github.com/hashicorp/hcl/decoder.go index cfddbf360..a6938feb3 100644 --- a/vendor/github.com/hashicorp/hcl/decoder.go +++ b/vendor/github.com/hashicorp/hcl/decoder.go @@ -489,7 +489,7 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) // the yacc parser would always ensure top-level elements were arrays. The new // parser does not make the same guarantees, thus we need to convert any // top-level literal elements into a list. - if _, ok := node.(*ast.LiteralType); ok { + if _, ok := node.(*ast.LiteralType); ok && item != nil { node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} } diff --git a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go index 692ac24e2..ea3734f09 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go +++ b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go @@ -214,4 +214,5 @@ func (c *CommentGroup) Pos() token.Pos { // GoStringer //------------------------------------------------------------------- -func (o *ObjectKey) GoString() string { return fmt.Sprintf("*%#v", *o) } +func (o *ObjectKey) GoString() string { return fmt.Sprintf("*%#v", *o) } +func (o *ObjectList) GoString() string { return fmt.Sprintf("*%#v", *o) } diff --git a/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go b/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go index b20416539..0735d95e0 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go +++ b/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go @@ -224,6 +224,11 @@ func (s *Scanner) Scan() token.Token { func (s *Scanner) scanComment(ch rune) { // single line comments if ch == '#' || (ch == '/' && s.peek() != '*') { + if ch == '/' && s.peek() != '/' { + s.err("expected '/' for comment") + return + } + ch = s.next() for ch != '\n' && ch >= 0 && ch != eof { ch = s.next() diff --git a/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go b/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go index 477f71ff3..dd5c72bb3 100644 --- a/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go +++ b/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go @@ -296,7 +296,7 @@ func (s *Scanner) scanString() { return } - if ch == '"' && braces == 0 { + if ch == '"' { break } diff --git a/vendor/github.com/hashicorp/logutils/LICENSE b/vendor/github.com/hashicorp/logutils/LICENSE deleted file mode 100644 index c33dcc7c9..000000000 --- a/vendor/github.com/hashicorp/logutils/LICENSE +++ /dev/null @@ -1,354 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. “Contributor” - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. “Contributor Version” - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. - -1.3. “Contribution” - - means Covered Software of a particular Contributor. - -1.4. “Covered Software” - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. “Incompatible With Secondary Licenses” - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of version - 1.1 or earlier of the License, but not also under the terms of a - Secondary License. - -1.6. “Executable Form” - - means any form of the work other than Source Code Form. - -1.7. “Larger Work” - - means a work that combines Covered Software with other material, in a separate - file or files, that is not Covered Software. - -1.8. “License” - - means this document. - -1.9. “Licensable” - - means having the right to grant, to the maximum extent possible, whether at the - time of the initial grant or subsequently, any and all of the rights conveyed by - this License. - -1.10. “Modifications” - - means any of the following: - - a. any file in Source Code Form that results from an addition to, deletion - from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. “Patent Claims” of a Contributor - - means any patent claim(s), including without limitation, method, process, - and apparatus claims, in any patent Licensable by such Contributor that - would be infringed, but for the grant of the License, by the making, - using, selling, offering for sale, having made, import, or transfer of - either its Contributions or its Contributor Version. - -1.12. “Secondary License” - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. “Source Code Form” - - means the form of the work preferred for making modifications. - -1.14. “You” (or “Your”) - - means an individual or a legal entity exercising rights under this - License. For legal entities, “You” includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, “control” means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or as - part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its Contributions - or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution become - effective for each Contribution on the date the Contributor first distributes - such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under this - License. No additional rights or licenses will be implied from the distribution - or licensing of Covered Software under this License. Notwithstanding Section - 2.1(b) above, no patent license is granted by a Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party’s - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of its - Contributions. - - This License does not grant any rights in the trademarks, service marks, or - logos of any Contributor (except as may be necessary to comply with the - notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this License - (see Section 10.2) or under the terms of a Secondary License (if permitted - under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its Contributions - are its original creation(s) or it has sufficient rights to grant the - rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under applicable - copyright doctrines of fair use, fair dealing, or other equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under the - terms of this License. You must inform recipients that the Source Code Form - of the Covered Software is governed by the terms of this License, and how - they can obtain a copy of this License. You may not attempt to alter or - restrict the recipients’ rights in the Source Code Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this License, - or sublicense it under different terms, provided that the license for - the Executable Form does not attempt to limit or alter the recipients’ - rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for the - Covered Software. If the Larger Work is a combination of Covered Software - with a work governed by one or more Secondary Licenses, and the Covered - Software is not Incompatible With Secondary Licenses, this License permits - You to additionally distribute such Covered Software under the terms of - such Secondary License(s), so that the recipient of the Larger Work may, at - their option, further distribute the Covered Software under the terms of - either this License or such Secondary License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices (including - copyright notices, patent notices, disclaimers of warranty, or limitations - of liability) contained within the Source Code Form of the Covered - Software, except that You may alter any license notices to the extent - required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on behalf - of any Contributor. You must make it absolutely clear that any such - warranty, support, indemnity, or liability obligation is offered by You - alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, judicial - order, or regulation then You must: (a) comply with the terms of this License - to the maximum extent possible; and (b) describe the limitations and the code - they affect. Such description must be placed in a text file included with all - distributions of the Covered Software under this License. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing basis, - if such Contributor fails to notify You of the non-compliance by some - reasonable means prior to 60 days after You have come back into compliance. - Moreover, Your grants from a particular Contributor are reinstated on an - ongoing basis if such Contributor notifies You of the non-compliance by - some reasonable means, this is the first time You have received notice of - non-compliance with this License from such Contributor, and You become - compliant prior to 30 days after Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, counter-claims, - and cross-claims) alleging that a Contributor Version directly or - indirectly infringes any patent, then the rights granted to You by any and - all Contributors for the Covered Software under Section 2.1 of this License - shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an “as is” basis, without - warranty of any kind, either expressed, implied, or statutory, including, - without limitation, warranties that the Covered Software is free of defects, - merchantable, fit for a particular purpose or non-infringing. The entire - risk as to the quality and performance of the Covered Software is with You. - Should any Covered Software prove defective in any respect, You (not any - Contributor) assume the cost of any necessary servicing, repair, or - correction. This disclaimer of warranty constitutes an essential part of this - License. No use of any Covered Software is authorized under this License - except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from such - party’s negligence to the extent applicable law prohibits such limitation. - Some jurisdictions do not allow the exclusion or limitation of incidental or - consequential damages, so this exclusion and limitation may not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts of - a jurisdiction where the defendant maintains its principal place of business - and such litigation shall be governed by laws of that jurisdiction, without - reference to its conflict-of-law provisions. Nothing in this Section shall - prevent a party’s ability to bring cross-claims or counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. Any law or regulation which provides that the language of a - contract shall be construed against the drafter shall not be used to construe - this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version of - the License under which You originally received the Covered Software, or - under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a modified - version of this License if you rename the license and remove any - references to the name of the license steward (except to note that such - modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, then -You may include the notice in a location (such as a LICENSE file in a relevant -directory) where a recipient would be likely to look for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - “Incompatible With Secondary Licenses” Notice - - This Source Code Form is “Incompatible - With Secondary Licenses”, as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/logutils/README.md b/vendor/github.com/hashicorp/logutils/README.md deleted file mode 100644 index 49490eaeb..000000000 --- a/vendor/github.com/hashicorp/logutils/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# logutils - -logutils is a Go package that augments the standard library "log" package -to make logging a bit more modern, without fragmenting the Go ecosystem -with new logging packages. - -## The simplest thing that could possibly work - -Presumably your application already uses the default `log` package. To switch, you'll want your code to look like the following: - -```go -package main - -import ( - "log" - "os" - - "github.com/hashicorp/logutils" -) - -func main() { - filter := &logutils.LevelFilter{ - Levels: []logutils.LogLevel{"DEBUG", "WARN", "ERROR"}, - MinLevel: logutils.LogLevel("WARN"), - Writer: os.Stderr, - } - log.SetOutput(filter) - - log.Print("[DEBUG] Debugging") // this will not print - log.Print("[WARN] Warning") // this will - log.Print("[ERROR] Erring") // and so will this - log.Print("Message I haven't updated") // and so will this -} -``` - -This logs to standard error exactly like go's standard logger. Any log messages you haven't converted to have a level will continue to print as before. diff --git a/vendor/github.com/hashicorp/logutils/level.go b/vendor/github.com/hashicorp/logutils/level.go deleted file mode 100644 index 6381bf162..000000000 --- a/vendor/github.com/hashicorp/logutils/level.go +++ /dev/null @@ -1,81 +0,0 @@ -// Package logutils augments the standard log package with levels. -package logutils - -import ( - "bytes" - "io" - "sync" -) - -type LogLevel string - -// LevelFilter is an io.Writer that can be used with a logger that -// will filter out log messages that aren't at least a certain level. -// -// Once the filter is in use somewhere, it is not safe to modify -// the structure. -type LevelFilter struct { - // Levels is the list of log levels, in increasing order of - // severity. Example might be: {"DEBUG", "WARN", "ERROR"}. - Levels []LogLevel - - // MinLevel is the minimum level allowed through - MinLevel LogLevel - - // The underlying io.Writer where log messages that pass the filter - // will be set. - Writer io.Writer - - badLevels map[LogLevel]struct{} - once sync.Once -} - -// Check will check a given line if it would be included in the level -// filter. -func (f *LevelFilter) Check(line []byte) bool { - f.once.Do(f.init) - - // Check for a log level - var level LogLevel - x := bytes.IndexByte(line, '[') - if x >= 0 { - y := bytes.IndexByte(line[x:], ']') - if y >= 0 { - level = LogLevel(line[x+1 : x+y]) - } - } - - _, ok := f.badLevels[level] - return !ok -} - -func (f *LevelFilter) Write(p []byte) (n int, err error) { - // Note in general that io.Writer can receive any byte sequence - // to write, but the "log" package always guarantees that we only - // get a single line. We use that as a slight optimization within - // this method, assuming we're dealing with a single, complete line - // of log data. - - if !f.Check(p) { - return len(p), nil - } - - return f.Writer.Write(p) -} - -// SetMinLevel is used to update the minimum log level -func (f *LevelFilter) SetMinLevel(min LogLevel) { - f.MinLevel = min - f.init() -} - -func (f *LevelFilter) init() { - badLevels := make(map[LogLevel]struct{}) - for _, level := range f.Levels { - if level == f.MinLevel { - break - } - badLevels[level] = struct{}{} - } - f.badLevels = badLevels -} diff --git a/vendor/github.com/keybase/go-crypto/openpgp/packet/public_key.go b/vendor/github.com/keybase/go-crypto/openpgp/packet/public_key.go index d5637a75c..ff82a5be2 100644 --- a/vendor/github.com/keybase/go-crypto/openpgp/packet/public_key.go +++ b/vendor/github.com/keybase/go-crypto/openpgp/packet/public_key.go @@ -64,7 +64,7 @@ func (e *edDSAkey) Verify(payload []byte, r parsedMPI, s parsedMPI) bool { var key [ed25519.PublicKeySize]byte var sig [ed25519.SignatureSize]byte - // note(mnk): I'm not entirely sure why we need to ignore the first byte. + // NOTE(maxtaco): I'm not entirely sure why we need to ignore the first byte. copy(key[:], e.p.bytes[1:]) n := copy(sig[:], r.bytes) copy(sig[n:], s.bytes) @@ -570,9 +570,18 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro signed.Write(sig.HashSuffix) hashBytes := signed.Sum(nil) - if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { - return errors.SignatureError("hash tag doesn't match") - } + // NOTE(maxtaco) 2016-08-22 + // + // We used to do this: + // + // if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { + // return errors.SignatureError("hash tag doesn't match") + // } + // + // But don't do anything in this case. Some GPGs generate bad + // 2-byte hash prefixes, but GPG also doesn't seem to care on + // import. See BrentMaxwell's key. I think it's safe to disable + // this check! if pk.PubKeyAlgo != sig.PubKeyAlgo { return errors.InvalidArgumentError("public key and signature use different algorithms") diff --git a/vendor/github.com/lib/pq/array.go b/vendor/github.com/lib/pq/array.go new file mode 100644 index 000000000..27eb07a9e --- /dev/null +++ b/vendor/github.com/lib/pq/array.go @@ -0,0 +1,727 @@ +package pq + +import ( + "bytes" + "database/sql" + "database/sql/driver" + "encoding/hex" + "fmt" + "reflect" + "strconv" + "strings" +) + +var typeByteSlice = reflect.TypeOf([]byte{}) +var typeDriverValuer = reflect.TypeOf((*driver.Valuer)(nil)).Elem() +var typeSqlScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem() + +// Array returns the optimal driver.Valuer and sql.Scanner for an array or +// slice of any dimension. +// +// For example: +// db.Query(`SELECT * FROM t WHERE id = ANY($1)`, pq.Array([]int{235, 401})) +// +// var x []sql.NullInt64 +// db.QueryRow('SELECT ARRAY[235, 401]').Scan(pq.Array(&x)) +// +// Scanning multi-dimensional arrays is not supported. Arrays where the lower +// bound is not one (such as `[0:0]={1}') are not supported. +func Array(a interface{}) interface { + driver.Valuer + sql.Scanner +} { + switch a := a.(type) { + case []bool: + return (*BoolArray)(&a) + case []float64: + return (*Float64Array)(&a) + case []int64: + return (*Int64Array)(&a) + case []string: + return (*StringArray)(&a) + + case *[]bool: + return (*BoolArray)(a) + case *[]float64: + return (*Float64Array)(a) + case *[]int64: + return (*Int64Array)(a) + case *[]string: + return (*StringArray)(a) + } + + return GenericArray{a} +} + +// ArrayDelimiter may be optionally implemented by driver.Valuer or sql.Scanner +// to override the array delimiter used by GenericArray. +type ArrayDelimiter interface { + // ArrayDelimiter returns the delimiter character(s) for this element's type. + ArrayDelimiter() string +} + +// BoolArray represents a one-dimensional array of the PostgreSQL boolean type. +type BoolArray []bool + +// Scan implements the sql.Scanner interface. +func (a *BoolArray) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + } + + return fmt.Errorf("pq: cannot convert %T to BoolArray", src) +} + +func (a *BoolArray) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "BoolArray") + if err != nil { + return err + } + if len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(BoolArray, len(elems)) + for i, v := range elems { + if len(v) != 1 { + return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", i, v) + } + switch v[0] { + case 't': + b[i] = true + case 'f': + b[i] = false + default: + return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", i, v) + } + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. +func (a BoolArray) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be exactly two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 1+2*n) + + for i := 0; i < n; i++ { + b[2*i] = ',' + if a[i] { + b[1+2*i] = 't' + } else { + b[1+2*i] = 'f' + } + } + + b[0] = '{' + b[2*n] = '}' + + return string(b), nil + } + + return "{}", nil +} + +// ByteaArray represents a one-dimensional array of the PostgreSQL bytea type. +type ByteaArray [][]byte + +// Scan implements the sql.Scanner interface. +func (a *ByteaArray) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + } + + return fmt.Errorf("pq: cannot convert %T to ByteaArray", src) +} + +func (a *ByteaArray) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "ByteaArray") + if err != nil { + return err + } + if len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(ByteaArray, len(elems)) + for i, v := range elems { + b[i], err = parseBytea(v) + if err != nil { + return fmt.Errorf("could not parse bytea array index %d: %s", i, err.Error()) + } + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. It uses the "hex" format which +// is only supported on PostgreSQL 9.0 or newer. +func (a ByteaArray) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, 2*N bytes of quotes, + // 3*N bytes of hex formatting, and N-1 bytes of delimiters. + size := 1 + 6*n + for _, x := range a { + size += hex.EncodedLen(len(x)) + } + + b := make([]byte, size) + + for i, s := 0, b; i < n; i++ { + o := copy(s, `,"\\x`) + o += hex.Encode(s[o:], a[i]) + s[o] = '"' + s = s[o+1:] + } + + b[0] = '{' + b[size-1] = '}' + + return string(b), nil + } + + return "{}", nil +} + +// Float64Array represents a one-dimensional array of the PostgreSQL double +// precision type. +type Float64Array []float64 + +// Scan implements the sql.Scanner interface. +func (a *Float64Array) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + } + + return fmt.Errorf("pq: cannot convert %T to Float64Array", src) +} + +func (a *Float64Array) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "Float64Array") + if err != nil { + return err + } + if len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(Float64Array, len(elems)) + for i, v := range elems { + if b[i], err = strconv.ParseFloat(string(v), 64); err != nil { + return fmt.Errorf("pq: parsing array element index %d: %v", i, err) + } + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. +func (a Float64Array) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+2*n) + b[0] = '{' + + b = strconv.AppendFloat(b, a[0], 'f', -1, 64) + for i := 1; i < n; i++ { + b = append(b, ',') + b = strconv.AppendFloat(b, a[i], 'f', -1, 64) + } + + return string(append(b, '}')), nil + } + + return "{}", nil +} + +// GenericArray implements the driver.Valuer and sql.Scanner interfaces for +// an array or slice of any dimension. +type GenericArray struct{ A interface{} } + +func (GenericArray) evaluateDestination(rt reflect.Type) (reflect.Type, func([]byte, reflect.Value) error, string) { + var assign func([]byte, reflect.Value) error + var del = "," + + // TODO calculate the assign function for other types + // TODO repeat this section on the element type of arrays or slices (multidimensional) + { + if reflect.PtrTo(rt).Implements(typeSqlScanner) { + // dest is always addressable because it is an element of a slice. + assign = func(src []byte, dest reflect.Value) (err error) { + ss := dest.Addr().Interface().(sql.Scanner) + if src == nil { + err = ss.Scan(nil) + } else { + err = ss.Scan(src) + } + return + } + goto FoundType + } + + assign = func([]byte, reflect.Value) error { + return fmt.Errorf("pq: scanning to %s is not implemented; only sql.Scanner", rt) + } + } + +FoundType: + + if ad, ok := reflect.Zero(rt).Interface().(ArrayDelimiter); ok { + del = ad.ArrayDelimiter() + } + + return rt, assign, del +} + +// Scan implements the sql.Scanner interface. +func (a GenericArray) Scan(src interface{}) error { + dpv := reflect.ValueOf(a.A) + switch { + case dpv.Kind() != reflect.Ptr: + return fmt.Errorf("pq: destination %T is not a pointer to array or slice", a.A) + case dpv.IsNil(): + return fmt.Errorf("pq: destination %T is nil", a.A) + } + + dv := dpv.Elem() + switch dv.Kind() { + case reflect.Slice: + case reflect.Array: + default: + return fmt.Errorf("pq: destination %T is not a pointer to array or slice", a.A) + } + + switch src := src.(type) { + case []byte: + return a.scanBytes(src, dv) + case string: + return a.scanBytes([]byte(src), dv) + } + + return fmt.Errorf("pq: cannot convert %T to %s", src, dv.Type()) +} + +func (a GenericArray) scanBytes(src []byte, dv reflect.Value) error { + dtype, assign, del := a.evaluateDestination(dv.Type().Elem()) + dims, elems, err := parseArray(src, []byte(del)) + if err != nil { + return err + } + + // TODO allow multidimensional + + if len(dims) > 1 { + return fmt.Errorf("pq: scanning from multidimensional ARRAY%s is not implemented", + strings.Replace(fmt.Sprint(dims), " ", "][", -1)) + } + + // Treat a zero-dimensional array like an array with a single dimension of zero. + if len(dims) == 0 { + dims = append(dims, 0) + } + + for i, rt := 0, dv.Type(); i < len(dims); i, rt = i+1, rt.Elem() { + switch rt.Kind() { + case reflect.Slice: + case reflect.Array: + if rt.Len() != dims[i] { + return fmt.Errorf("pq: cannot convert ARRAY%s to %s", + strings.Replace(fmt.Sprint(dims), " ", "][", -1), dv.Type()) + } + default: + // TODO handle multidimensional + } + } + + values := reflect.MakeSlice(reflect.SliceOf(dtype), len(elems), len(elems)) + for i, e := range elems { + if err := assign(e, values.Index(i)); err != nil { + return fmt.Errorf("pq: parsing array element index %d: %v", i, err) + } + } + + // TODO handle multidimensional + + switch dv.Kind() { + case reflect.Slice: + dv.Set(values.Slice(0, dims[0])) + case reflect.Array: + for i := 0; i < dims[0]; i++ { + dv.Index(i).Set(values.Index(i)) + } + } + + return nil +} + +// Value implements the driver.Valuer interface. +func (a GenericArray) Value() (driver.Value, error) { + if a.A == nil { + return nil, nil + } + + rv := reflect.ValueOf(a.A) + + if k := rv.Kind(); k != reflect.Array && k != reflect.Slice { + return nil, fmt.Errorf("pq: Unable to convert %T to array", a.A) + } + + if n := rv.Len(); n > 0 { + // There will be at least two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 0, 1+2*n) + + b, _, err := appendArray(b, rv, n) + return string(b), err + } + + return "{}", nil +} + +// Int64Array represents a one-dimensional array of the PostgreSQL integer types. +type Int64Array []int64 + +// Scan implements the sql.Scanner interface. +func (a *Int64Array) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + } + + return fmt.Errorf("pq: cannot convert %T to Int64Array", src) +} + +func (a *Int64Array) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "Int64Array") + if err != nil { + return err + } + if len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(Int64Array, len(elems)) + for i, v := range elems { + if b[i], err = strconv.ParseInt(string(v), 10, 64); err != nil { + return fmt.Errorf("pq: parsing array element index %d: %v", i, err) + } + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. +func (a Int64Array) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+2*n) + b[0] = '{' + + b = strconv.AppendInt(b, a[0], 10) + for i := 1; i < n; i++ { + b = append(b, ',') + b = strconv.AppendInt(b, a[i], 10) + } + + return string(append(b, '}')), nil + } + + return "{}", nil +} + +// StringArray represents a one-dimensional array of the PostgreSQL character types. +type StringArray []string + +// Scan implements the sql.Scanner interface. +func (a *StringArray) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return a.scanBytes(src) + case string: + return a.scanBytes([]byte(src)) + } + + return fmt.Errorf("pq: cannot convert %T to StringArray", src) +} + +func (a *StringArray) scanBytes(src []byte) error { + elems, err := scanLinearArray(src, []byte{','}, "StringArray") + if err != nil { + return err + } + if len(elems) == 0 { + *a = (*a)[:0] + } else { + b := make(StringArray, len(elems)) + for i, v := range elems { + if b[i] = string(v); v == nil { + return fmt.Errorf("pq: parsing array element index %d: cannot convert nil to string", i) + } + } + *a = b + } + return nil +} + +// Value implements the driver.Valuer interface. +func (a StringArray) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, 2*N bytes of quotes, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+3*n) + b[0] = '{' + + b = appendArrayQuotedBytes(b, []byte(a[0])) + for i := 1; i < n; i++ { + b = append(b, ',') + b = appendArrayQuotedBytes(b, []byte(a[i])) + } + + return string(append(b, '}')), nil + } + + return "{}", nil +} + +// appendArray appends rv to the buffer, returning the extended buffer and +// the delimiter used between elements. +// +// It panics when n <= 0 or rv's Kind is not reflect.Array nor reflect.Slice. +func appendArray(b []byte, rv reflect.Value, n int) ([]byte, string, error) { + var del string + var err error + + b = append(b, '{') + + if b, del, err = appendArrayElement(b, rv.Index(0)); err != nil { + return b, del, err + } + + for i := 1; i < n; i++ { + b = append(b, del...) + if b, del, err = appendArrayElement(b, rv.Index(i)); err != nil { + return b, del, err + } + } + + return append(b, '}'), del, nil +} + +// appendArrayElement appends rv to the buffer, returning the extended buffer +// and the delimiter to use before the next element. +// +// When rv's Kind is neither reflect.Array nor reflect.Slice, it is converted +// using driver.DefaultParameterConverter and the resulting []byte or string +// is double-quoted. +// +// See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO +func appendArrayElement(b []byte, rv reflect.Value) ([]byte, string, error) { + if k := rv.Kind(); k == reflect.Array || k == reflect.Slice { + if t := rv.Type(); t != typeByteSlice && !t.Implements(typeDriverValuer) { + if n := rv.Len(); n > 0 { + return appendArray(b, rv, n) + } + + return b, "", nil + } + } + + var del string = "," + var err error + var iv interface{} = rv.Interface() + + if ad, ok := iv.(ArrayDelimiter); ok { + del = ad.ArrayDelimiter() + } + + if iv, err = driver.DefaultParameterConverter.ConvertValue(iv); err != nil { + return b, del, err + } + + switch v := iv.(type) { + case nil: + return append(b, "NULL"...), del, nil + case []byte: + return appendArrayQuotedBytes(b, v), del, nil + case string: + return appendArrayQuotedBytes(b, []byte(v)), del, nil + } + + b, err = appendValue(b, iv) + return b, del, err +} + +func appendArrayQuotedBytes(b, v []byte) []byte { + b = append(b, '"') + for { + i := bytes.IndexAny(v, `"\`) + if i < 0 { + b = append(b, v...) + break + } + if i > 0 { + b = append(b, v[:i]...) + } + b = append(b, '\\', v[i]) + v = v[i+1:] + } + return append(b, '"') +} + +func appendValue(b []byte, v driver.Value) ([]byte, error) { + return append(b, encode(nil, v, 0)...), nil +} + +// parseArray extracts the dimensions and elements of an array represented in +// text format. Only representations emitted by the backend are supported. +// Notably, whitespace around brackets and delimiters is significant, and NULL +// is case-sensitive. +// +// See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO +func parseArray(src, del []byte) (dims []int, elems [][]byte, err error) { + var depth, i int + + if len(src) < 1 || src[0] != '{' { + return nil, nil, fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '{', 0) + } + +Open: + for i < len(src) { + switch src[i] { + case '{': + depth++ + i++ + case '}': + elems = make([][]byte, 0) + goto Close + default: + break Open + } + } + dims = make([]int, i) + +Element: + for i < len(src) { + switch src[i] { + case '{': + depth++ + dims[depth-1] = 0 + i++ + case '"': + var elem = []byte{} + var escape bool + for i++; i < len(src); i++ { + if escape { + elem = append(elem, src[i]) + escape = false + } else { + switch src[i] { + default: + elem = append(elem, src[i]) + case '\\': + escape = true + case '"': + elems = append(elems, elem) + i++ + break Element + } + } + } + default: + for start := i; i < len(src); i++ { + if bytes.HasPrefix(src[i:], del) || src[i] == '}' { + elem := src[start:i] + if len(elem) == 0 { + return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i) + } + if bytes.Equal(elem, []byte("NULL")) { + elem = nil + } + elems = append(elems, elem) + break Element + } + } + } + } + + for i < len(src) { + if bytes.HasPrefix(src[i:], del) { + dims[depth-1]++ + i += len(del) + goto Element + } else if src[i] == '}' { + dims[depth-1]++ + depth-- + i++ + } else { + return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i) + } + } + +Close: + for i < len(src) { + if src[i] == '}' && depth > 0 { + depth-- + i++ + } else { + return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i) + } + } + if depth > 0 { + err = fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '}', i) + } + if err == nil { + for _, d := range dims { + if (len(elems) % d) != 0 { + err = fmt.Errorf("pq: multidimensional arrays must have elements with matching dimensions") + } + } + } + return +} + +func scanLinearArray(src, del []byte, typ string) (elems [][]byte, err error) { + dims, elems, err := parseArray(src, del) + if err != nil { + return nil, err + } + if len(dims) > 1 { + return nil, fmt.Errorf("pq: cannot convert ARRAY%s to %s", strings.Replace(fmt.Sprint(dims), " ", "][", -1), typ) + } + return elems, err +} diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go index 0ca9bbcbe..29e8f6ff7 100644 --- a/vendor/github.com/lib/pq/encode.go +++ b/vendor/github.com/lib/pq/encode.go @@ -89,7 +89,11 @@ func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interfa case oid.T_char, oid.T_varchar, oid.T_text: return string(s) case oid.T_bytea: - return parseBytea(s) + b, err := parseBytea(s) + if err != nil { + errorf("%s", err) + } + return b case oid.T_timestamptz: return parseTs(parameterStatus.currentLocation, string(s)) case oid.T_timestamp, oid.T_date: @@ -492,14 +496,14 @@ func FormatTimestamp(t time.Time) []byte { // Parse a bytea value received from the server. Both "hex" and the legacy // "escape" format are supported. -func parseBytea(s []byte) (result []byte) { +func parseBytea(s []byte) (result []byte, err error) { if len(s) >= 2 && bytes.Equal(s[:2], []byte("\\x")) { // bytea_output = hex s = s[2:] // trim off leading "\\x" result = make([]byte, hex.DecodedLen(len(s))) _, err := hex.Decode(result, s) if err != nil { - errorf("%s", err) + return nil, err } } else { // bytea_output = escape @@ -514,11 +518,11 @@ func parseBytea(s []byte) (result []byte) { // '\\' followed by an octal number if len(s) < 4 { - errorf("invalid bytea sequence %v", s) + return nil, fmt.Errorf("invalid bytea sequence %v", s) } r, err := strconv.ParseInt(string(s[1:4]), 8, 9) if err != nil { - errorf("could not parse bytea value: %s", err.Error()) + return nil, fmt.Errorf("could not parse bytea value: %s", err.Error()) } result = append(result, byte(r)) s = s[4:] @@ -536,7 +540,7 @@ func parseBytea(s []byte) (result []byte) { } } - return result + return result, nil } func encodeBytea(serverVersion int, v []byte) (result []byte) { diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index 98ffe86a4..42f2514d1 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,4 +1,4 @@ -// +build darwin freebsd openbsd netbsd +// +build darwin freebsd openbsd netbsd dragonfly // +build !appengine package isatty diff --git a/vendor/github.com/mitchellh/cli/cli.go b/vendor/github.com/mitchellh/cli/cli.go index bd663671d..fbc0722f4 100644 --- a/vendor/github.com/mitchellh/cli/cli.go +++ b/vendor/github.com/mitchellh/cli/cli.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "os" + "regexp" "sort" "strings" "sync" @@ -405,16 +406,24 @@ func (c *CLI) processArgs() { } // If we didn't find a subcommand yet and this is the first non-flag - // argument, then this is our subcommand. j + // argument, then this is our subcommand. if c.subcommand == "" && arg != "" && arg[0] != '-' { c.subcommand = arg if c.commandNested { // Nested CLI, the subcommand is actually the entire // arg list up to a flag that is still a valid subcommand. - k, _, ok := c.commandTree.LongestPrefix(strings.Join(c.Args[i:], " ")) + searchKey := strings.Join(c.Args[i:], " ") + k, _, ok := c.commandTree.LongestPrefix(searchKey) if ok { - c.subcommand = k - i += strings.Count(k, " ") + // k could be a prefix that doesn't contain the full + // command such as "foo" instead of "foobar", so we + // need to verify that we have an entire key. To do that, + // we look for an ending in a space or an end of string. + reVerify := regexp.MustCompile(regexp.QuoteMeta(k) + `( |$)`) + if reVerify.MatchString(searchKey) { + c.subcommand = k + i += strings.Count(k, " ") + } } } diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go index fc8faaba3..036b00e06 100644 --- a/vendor/github.com/mitchellh/copystructure/copystructure.go +++ b/vendor/github.com/mitchellh/copystructure/copystructure.go @@ -2,27 +2,14 @@ package copystructure import ( "reflect" + "sync" "github.com/mitchellh/reflectwalk" ) // Copy returns a deep copy of v. func Copy(v interface{}) (interface{}, error) { - w := new(walker) - err := reflectwalk.Walk(v, w) - if err != nil { - return nil, err - } - - // Get the result. If the result is nil, then we want to turn it - // into a typed nil if we can. - result := w.Result - if result == nil { - val := reflect.ValueOf(v) - result = reflect.Indirect(reflect.New(val.Type())).Interface() - } - - return result, nil + return Config{}.Copy(v) } // CopierFunc is a function that knows how to deep copy a specific type. @@ -40,6 +27,42 @@ type CopierFunc func(interface{}) (interface{}, error) // this map as well as to Copy in a mutex. var Copiers map[reflect.Type]CopierFunc = make(map[reflect.Type]CopierFunc) +type Config struct { + // Lock any types that are a sync.Locker and are not a mutex while copying. + // If there is an RLocker method, use that to get the sync.Locker. + Lock bool + + // Copiers is a map of types associated with a CopierFunc. Use the global + // Copiers map if this is nil. + Copiers map[reflect.Type]CopierFunc +} + +func (c Config) Copy(v interface{}) (interface{}, error) { + w := new(walker) + if c.Lock { + w.useLocks = true + } + + if c.Copiers == nil { + c.Copiers = Copiers + } + + err := reflectwalk.Walk(v, w) + if err != nil { + return nil, err + } + + // Get the result. If the result is nil, then we want to turn it + // into a typed nil if we can. + result := w.Result + if result == nil { + val := reflect.ValueOf(v) + result = reflect.Indirect(reflect.New(val.Type())).Interface() + } + + return result, nil +} + type walker struct { Result interface{} @@ -48,14 +71,31 @@ type walker struct { vals []reflect.Value cs []reflect.Value ps []bool + + // any locks we've taken, indexed by depth + locks []sync.Locker + // take locks while walking the structure + useLocks bool } func (w *walker) Enter(l reflectwalk.Location) error { w.depth++ + + // ensure we have enough elements to index via w.depth + for w.depth >= len(w.locks) { + w.locks = append(w.locks, nil) + } + return nil } func (w *walker) Exit(l reflectwalk.Location) error { + locker := w.locks[w.depth] + w.locks[w.depth] = nil + if locker != nil { + defer locker.Unlock() + } + w.depth-- if w.ignoreDepth > w.depth { w.ignoreDepth = 0 @@ -76,13 +116,25 @@ func (w *walker) Exit(l reflectwalk.Location) error { mv := w.valPop() mk := w.valPop() m := w.cs[len(w.cs)-1] + + // If mv is the zero value, SetMapIndex deletes the key form the map, + // or in this case never adds it. We need to create a properly typed + // zero value so that this key can be set. + if !mv.IsValid() { + mv = reflect.Zero(m.Type().Elem()) + } m.SetMapIndex(mk, mv) case reflectwalk.SliceElem: // Pop off the value and the index and set it on the slice v := w.valPop() - i := w.valPop().Interface().(int) - s := w.cs[len(w.cs)-1] - s.Index(i).Set(v) + if v.IsValid() { + i := w.valPop().Interface().(int) + s := w.cs[len(w.cs)-1] + se := s.Index(i) + if se.CanSet() { + se.Set(v) + } + } case reflectwalk.Struct: w.replacePointerMaybe() @@ -95,7 +147,9 @@ func (w *walker) Exit(l reflectwalk.Location) error { if v.IsValid() { s := w.cs[len(w.cs)-1] sf := reflect.Indirect(s).FieldByName(f.Name) - sf.Set(v) + if sf.CanSet() { + sf.Set(v) + } } case reflectwalk.WalkLoc: // Clear out the slices for GC @@ -110,6 +164,7 @@ func (w *walker) Map(m reflect.Value) error { if w.ignoring() { return nil } + w.lock(m) // Create the map. If the map itself is nil, then just make a nil map var newMap reflect.Value @@ -150,6 +205,7 @@ func (w *walker) Primitive(v reflect.Value) error { if w.ignoring() { return nil } + w.lock(v) // IsValid verifies the v is non-zero and CanInterface verifies // that we're allowed to read this value (unexported fields). @@ -168,6 +224,7 @@ func (w *walker) Slice(s reflect.Value) error { if w.ignoring() { return nil } + w.lock(s) var newS reflect.Value if s.IsNil() { @@ -197,6 +254,7 @@ func (w *walker) Struct(s reflect.Value) error { if w.ignoring() { return nil } + w.lock(s) var v reflect.Value if c, ok := Copiers[s.Type()]; ok { @@ -275,3 +333,58 @@ func (w *walker) replacePointerMaybe() { w.valPush(reflect.Indirect(w.valPop())) } } + +// if this value is a Locker, lock it and add it to the locks slice +func (w *walker) lock(v reflect.Value) { + if !w.useLocks { + return + } + + if !v.IsValid() || !v.CanInterface() { + return + } + + type rlocker interface { + RLocker() sync.Locker + } + + var locker sync.Locker + + // first check if we can get a locker from the value + switch l := v.Interface().(type) { + case rlocker: + // don't lock a mutex directly + if _, ok := l.(*sync.RWMutex); !ok { + locker = l.RLocker() + } + case sync.Locker: + locker = l + } + + // the value itself isn't a locker, so check the method on a pointer too + if locker == nil && v.CanAddr() { + switch l := v.Addr().Interface().(type) { + case rlocker: + // don't lock a mutex directly + if _, ok := l.(*sync.RWMutex); !ok { + locker = l.RLocker() + } + case sync.Locker: + locker = l + } + } + + // still no callable locker + if locker == nil { + return + } + + // don't lock a mutex directly + switch locker.(type) { + case *sync.Mutex, *sync.RWMutex: + return + } + + locker.Lock() + w.locks[w.depth] = locker +} diff --git a/vendor/github.com/ory-am/dockertest/README.md b/vendor/github.com/ory-am/dockertest/README.md index bc2f1844a..d53ba09b2 100644 --- a/vendor/github.com/ory-am/dockertest/README.md +++ b/vendor/github.com/ory-am/dockertest/README.md @@ -36,11 +36,12 @@ Dockertest ships with support for these backends: - [Write awesome tests](#write-awesome-tests) - [Setting up Travis-CI](#setting-up-travis-ci) - [Troubleshoot & FAQ](#troubleshoot-&-faq) - - [I want to use a specific image version](#i-want-to-use-a-specific-image-version) + - [I need to use a specific container version for XYZ](#i-need-to-use-a-specific-container-version-for-xyz) - [My build is broken!](#my-build-is-broken) - [Out of disk space](#out-of-disk-space) + - [I am using docker machine (OSX / Linux)](#i-am-using-docker-machine-osx--linux) - [Removing old containers](#removing-old-containers) - - [Customized database] (#Customized-database) + - [Customized database](#customized-database) @@ -48,7 +49,7 @@ Dockertest ships with support for these backends: When developing applications, it is often necessary to use services that talk to a database system. Unit Testing these services can be cumbersome because mocking database/DBAL is strenuous. Making slight changes to the -schema implies rewriting at least some, if not all of the mocks. The same goes for API changes in the DBAL. +schema implies rewriting at least some, if not all of the mocks. The same goes for API changes in the DBAL. To avoid this, it is smarter to test these specific services against a real database that is destroyed after testing. Docker is the perfect system for running unit tests as you can spin up containers in a few seconds and kill them when the test completes. The Dockertest library provides easy to use commands for spinning up Docker containers and using @@ -71,7 +72,7 @@ where `X` is your desired version. For example: go get gopkg.in/ory-am/dockertest.v2 ``` -**Note:** +**Note:** When using the Docker Toolbox (Windows / OSX), make sure that the VM is started by running `docker-machine start default`. ### Start a container @@ -90,33 +91,65 @@ func main() { c, err := dockertest.ConnectToMongoDB(15, time.Millisecond*500, func(url string) bool { // This callback function checks if the image's process is responsive. // Sometimes, docker images are booted but the process (in this case MongoDB) is still doing maintenance - // before being fully responsive which might cause issues like "TCP Connection reset by peer". + // before being fully responsive which might cause issues like "TCP Connection reset by peer". var err error db, err = mgo.Dial(url) if err != nil { return false } - + // Sometimes, dialing the database is not enough because the port is already open but the process is not responsive. // Most database conenctors implement a ping function which can be used to test if the process is responsive. // Alternatively, you could execute a query to see if an error occurs or not. return db.Ping() == nil }) - + if err != nil { log.Fatalf("Could not connect to database: %s", err) } - + // Close db connection and kill the container when we leave this function body. defer db.Close() defer c.KillRemove() - + // The image is now responsive. } ``` You can start PostgreSQL and MySQL in a similar fashion. +There are some cases where it's useful to test how your application/code handles +remote resources failing / shutting down. For example, what if your database +goes offline? Does your application handle it gracefully? + +This can be tested by stopping and starting an existing container: + +```go + var hosts []string + c, err := ConnectToZooKeeper(15, time.Millisecond*500, func(url string) bool { + conn, _, err := zk.Connect([]string{url}, time.Second) + if err != nil { + return false + } + defer conn.Close() + hosts = []string{url} + + return true + }) + defer c.KillRemove() + + conn, _, _ := zk.Connect(hosts, time.Second) + conn.Create("/test", []byte("hello"), 0, zk.WorldACL(zk.PermAll)) + + c.Stop() + + _, _, err = zk.Get("/test") // err == zk.ErrNoServer + + c.Start() + + data, _, _ = zk.Get("/test") // data == []byte("hello") +``` + It is also possible to start a custom container (in this example, a RabbitMQ container): ```go @@ -170,18 +203,18 @@ func TestMain(m *testing.M) { if err != nil { log.Fatalf("Could not connect to database: %s", err) } - + // Execute tasks like setting up schemata. - + // Run tests result := m.Run() - + // Close database connection. db.Close() - + // Clean up image. c.KillRemove() - + // Exit tests. os.Exit(result) } @@ -225,6 +258,13 @@ If you relied on these, run `go get gopkg.in/ory-am/dockertest.v1` and replace Try cleaning up the images with [docker-cleanup-volumes](https://github.com/chadoe/docker-cleanup-volumes). +### I am using docker machine (OSX / Linux) + +First of all, consider upgrading! If that's not an option, there are some steps you need to take: + +* Set `dockertest.UseDockerMachine = "1"` or set the environment variable `DOCKERTEST_LEGACY_DOCKER_MACHINE=1` +* Set `docker.BindDockerToLocalhost = ""` or alternatively `DOCKER_BIND_LOCALHOST=` + ### Removing old containers Sometimes container clean up fails. Check out diff --git a/vendor/github.com/ory-am/dockertest/container.go b/vendor/github.com/ory-am/dockertest/container.go index 0c939d454..964fedcdb 100644 --- a/vendor/github.com/ory-am/dockertest/container.go +++ b/vendor/github.com/ory-am/dockertest/container.go @@ -1,13 +1,28 @@ package dockertest import ( - "camlistore.org/pkg/netutil" "fmt" + "net" "os/exec" "strings" "time" ) +// AwaitReachable tries to make a TCP connection to addr regularly. +// It returns an error if it's unable to make a connection before maxWait. +func AwaitReachable(addr string, maxWait time.Duration) error { + done := time.Now().Add(maxWait) + for time.Now().Before(done) { + c, err := net.Dial("tcp", addr) + if err == nil { + c.Close() + return nil + } + time.Sleep(100 * time.Millisecond) + } + return fmt.Errorf("%v unreachable for %v", addr, maxWait) +} + // ContainerID represents a container and offers methods like Kill or IP. type ContainerID string @@ -21,6 +36,16 @@ func (c ContainerID) Kill() error { return KillContainer(string(c)) } +// Start runs "docker start" on the container. +func (c ContainerID) Start() error { + return StartContainer(string(c)) +} + +// Stop runs "docker stop" on the container. +func (c ContainerID) Stop() error { + return StopContainer(string(c)) +} + // Remove runs "docker rm" on the container func (c ContainerID) Remove() error { if Debug || c == "nil" { @@ -56,7 +81,7 @@ func (c ContainerID) lookup(ports []int, timeout time.Duration) (ip string, err } for _, port := range ports { addr := fmt.Sprintf("%s:%d", ip, port) - err = netutil.AwaitReachable(addr, timeout) + err = AwaitReachable(addr, timeout) if err != nil { return } diff --git a/vendor/github.com/ory-am/dockertest/docker.go b/vendor/github.com/ory-am/dockertest/docker.go index 3c428b088..9a1e34a8f 100644 --- a/vendor/github.com/ory-am/dockertest/docker.go +++ b/vendor/github.com/ory-am/dockertest/docker.go @@ -37,7 +37,7 @@ import ( // based on image. func runLongTest(image string) error { DockerMachineAvailable = false - if haveDockerMachine() { + if haveDockerMachine() && UseDockerMachine != "" { DockerMachineAvailable = true if !startDockerMachine() { log.Printf(`Starting docker machine "%s" failed. @@ -177,6 +177,22 @@ func KillContainer(container string) error { return nil } +// StartContainer runs 'docker start' on a container. +func StartContainer(container string) error { + if container != "" { + return runDockerCommand("docker", "start", container).Run() + } + return nil +} + +// StopContainer runs 'docker stop' on a container. +func StopContainer(container string) error { + if container != "" { + return runDockerCommand("docker", "stop", container).Run() + } + return nil +} + // Pull retrieves the docker image with 'docker pull'. func Pull(image string) error { out, err := runDockerCommand("docker", "pull", image).CombinedOutput() @@ -257,4 +273,4 @@ func GenerateContainerID() string { func init() { rand.Seed(time.Now().UTC().UnixNano()) -} \ No newline at end of file +} diff --git a/vendor/github.com/ory-am/dockertest/glide.lock b/vendor/github.com/ory-am/dockertest/glide.lock new file mode 100644 index 000000000..c3a3b5de3 --- /dev/null +++ b/vendor/github.com/ory-am/dockertest/glide.lock @@ -0,0 +1,114 @@ +hash: ea1ce82416f8736cf3fd1f562146f135ee5071c7aed0dcbb4e33b4c18cdeaf6d +updated: 2016-08-08T16:52:24.58116408+02:00 +imports: +- name: github.com/go-errors/errors + version: a41850380601eeb43f4350f7d17c6bbd8944aaf8 +- name: github.com/go-sql-driver/mysql + version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685 +- name: github.com/lib/pq + version: 80f8150043c80fb52dee6bc863a709cdac7ec8f8 + subpackages: + - oid +- name: github.com/ory-am/common + version: 930cc805232909c38f2e68310b1e21f71b056d59 + subpackages: + - env +- name: github.com/pborman/uuid + version: a97ce2ca70fa5a848076093f05e639a89ca34d06 +testImports: +- name: github.com/araddon/gou + version: 50a94aa4a3fb69e8fbde05df290fcb49fa685e07 +- name: github.com/bitly/go-hostpool + version: d0e59c22a56e8dadfed24f74f452cea5a52722d2 +- name: github.com/cenk/backoff + version: cdf48bbc1eb78d1349cbda326a4a037f7ba565c6 +- name: github.com/dancannon/gorethink + version: 27d3045458910e2fc56025a0b52caaaa96414a26 +- name: github.com/davecgh/go-spew + version: 2df174808ee097f90d259e432cc04442cf60be21 + subpackages: + - spew +- name: github.com/garyburd/redigo + version: 8873b2f1995f59d4bcdd2b0dc9858e2cb9bf0c13 + subpackages: + - internal + - redis +- name: github.com/go-stomp/stomp + version: 364e36fe21291dd5aec3cba10ea15b0e654d9b40 + subpackages: + - frame +- name: github.com/gocql/gocql + version: b2caded3d0f457e42515c06d4092c02055cebaa0 + subpackages: + - internal/lru + - internal/murmur + - internal/streams +- name: github.com/golang/protobuf + version: c3cefd437628a0b7d31b34fe44b3a7a540e98527 + subpackages: + - proto +- name: github.com/golang/snappy + version: d9eb7a3d35ec988b8585d4a0068e462c27d28380 +- name: github.com/hailocab/go-hostpool + version: e80d13ce29ede4452c43dea11e79b9bc8a15b478 +- name: github.com/hashicorp/consul + version: d8262e1ffcdd216bcb26dfb69b670102ff13156c + subpackages: + - api +- name: github.com/hashicorp/go-cleanhttp + version: 875fb671b3ddc66f8e2f0acc33829c8cb989a38d +- name: github.com/hashicorp/serf + version: 6c4672d66fc6312ddde18399262943e21175d831 + subpackages: + - coordinate + - serf +- name: github.com/mattbaird/elastigo + version: 34c4c4d8425cbdcbc8e257943a2044d5e9f7dab5 + subpackages: + - lib +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/samuel/go-zookeeper + version: e64db453f3512cade908163702045e0f31137843 + subpackages: + - zk +- name: github.com/Sirupsen/logrus + version: a283a10442df8dc09befd873fab202bf8a253d6a +- name: github.com/streadway/amqp + version: 2e25825abdbd7752ff08b270d313b93519a0a232 +- name: github.com/stretchr/testify + version: f390dcf405f7b83c997eac1b06768bb9f44dec18 + subpackages: + - assert + - require +- name: golang.org/x/crypto + version: e0d166c33c321d0ff863f459a5882096e334f508 + subpackages: + - pbkdf2 +- name: golang.org/x/net + version: 075e191f18186a8ff2becaf64478e30f4545cdad + subpackages: + - context +- name: golang.org/x/sys + version: 20457ee8ea8546920d3f4e19e405da45250dc5a5 + subpackages: + - unix +- name: gopkg.in/dancannon/gorethink.v2 + version: 27d3045458910e2fc56025a0b52caaaa96414a26 + subpackages: + - encoding + - ql2 + - types +- name: gopkg.in/fatih/pool.v2 + version: 20a0a429c5f93de45c90f5f09ea297c25e0929b3 +- name: gopkg.in/inf.v0 + version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 +- name: gopkg.in/mgo.v2 + version: 01084657862d7b12d3b10ffd0394357abf8f8bc2 + subpackages: + - bson + - internal/json + - internal/sasl + - internal/scram diff --git a/vendor/github.com/ory-am/dockertest/glide.yaml b/vendor/github.com/ory-am/dockertest/glide.yaml new file mode 100644 index 000000000..7ce277b9a --- /dev/null +++ b/vendor/github.com/ory-am/dockertest/glide.yaml @@ -0,0 +1,39 @@ +package: github.com/ory-am/dockertest +import: +- package: github.com/go-errors/errors +- package: github.com/go-sql-driver/mysql + version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685 +- package: github.com/lib/pq +- package: github.com/ory-am/common + subpackages: + - env +- package: github.com/pborman/uuid + version: ~1.0.0 +testImport: +- package: github.com/dancannon/gorethink + version: ~2.1.3 +- package: github.com/garyburd/redigo + version: ~1.0.0 + subpackages: + - redis +- package: github.com/go-stomp/stomp + version: 364e36fe21291dd5aec3cba10ea15b0e654d9b40 +- package: github.com/gocql/gocql +- package: github.com/hashicorp/consul + version: ~0.7.0-test2 + subpackages: + - api +- package: github.com/mattbaird/elastigo + version: 34c4c4d8425cbdcbc8e257943a2044d5e9f7dab5 + subpackages: + - lib +- package: github.com/samuel/go-zookeeper + subpackages: + - zk +- package: github.com/streadway/amqp +- package: github.com/stretchr/testify + version: ~1.1.3 + subpackages: + - assert + - require +- package: gopkg.in/mgo.v2 diff --git a/vendor/github.com/ory-am/dockertest/mockserver.go b/vendor/github.com/ory-am/dockertest/mockserver.go index f7e6d7729..0bdf15396 100644 --- a/vendor/github.com/ory-am/dockertest/mockserver.go +++ b/vendor/github.com/ory-am/dockertest/mockserver.go @@ -2,9 +2,9 @@ package dockertest import ( "fmt" - "time" - "log" "github.com/go-errors/errors" + "log" + "time" ) // SetupMockserverContainer sets up a real Mockserver instance for testing purposes @@ -22,7 +22,7 @@ func SetupMockserverContainer() (c ContainerID, ip string, mockPort, proxyPort i proxyForward = "127.0.0.1:" + proxyForward } - c, ip, err = SetupMultiportContainer(RabbitMQImageName, []int{ mockPort, proxyPort}, 10*time.Second, func() (string, error) { + c, ip, err = SetupMultiportContainer(RabbitMQImageName, []int{mockPort, proxyPort}, 10*time.Second, func() (string, error) { res, err := run("--name", GenerateContainerID(), "-d", "-P", "-p", mockForward, "-p", proxyForward, MockserverImageName) return res, err }) @@ -63,4 +63,4 @@ func ConnectToMockserver(tries int, delay time.Duration, mockConnector func(url } else { return c, errors.New("Could not set up Mockserver container.") } -} \ No newline at end of file +} diff --git a/vendor/github.com/ory-am/dockertest/vars.go b/vendor/github.com/ory-am/dockertest/vars.go index 6ee66bd92..34c7759a4 100644 --- a/vendor/github.com/ory-am/dockertest/vars.go +++ b/vendor/github.com/ory-am/dockertest/vars.go @@ -17,7 +17,10 @@ var ( // BindDockerToLocalhost if set, forces docker to bind the image to localhost. This for example is required when running tests on travis-ci. // You can set this variable either directly or by defining a DOCKERTEST_BIND_LOCALHOST env variable. // FIXME DOCKER_BIND_LOCALHOST remove legacy support - BindDockerToLocalhost = env.Getenv("DOCKERTEST_BIND_LOCALHOST", env.Getenv("DOCKER_BIND_LOCALHOST", "")) + BindDockerToLocalhost = env.Getenv("DOCKERTEST_BIND_LOCALHOST", env.Getenv("DOCKER_BIND_LOCALHOST", "1")) + + // UseDockerMachine if set, forces docker to use the legacy docker-machine on OSX/Windows. + UseDockerMachine = env.Getenv("DOCKERTEST_LEGACY_DOCKER_MACHINE", "") // ContainerPrefix will be prepended to all containers started by dockertest to make identification of these "test images" hassle-free. ContainerPrefix = env.Getenv("DOCKERTEST_CONTAINER_PREFIX", "dockertest-") diff --git a/vendor/github.com/pborman/uuid/dce.go b/vendor/github.com/pborman/uuid/dce.go old mode 100755 new mode 100644 diff --git a/vendor/github.com/pborman/uuid/doc.go b/vendor/github.com/pborman/uuid/doc.go old mode 100755 new mode 100644 diff --git a/vendor/github.com/pborman/uuid/node.go b/vendor/github.com/pborman/uuid/node.go old mode 100755 new mode 100644 diff --git a/vendor/github.com/pborman/uuid/time.go b/vendor/github.com/pborman/uuid/time.go old mode 100755 new mode 100644 diff --git a/vendor/github.com/pborman/uuid/uuid.go b/vendor/github.com/pborman/uuid/uuid.go index 82c9e7ee7..7c643cf0a 100644 --- a/vendor/github.com/pborman/uuid/uuid.go +++ b/vendor/github.com/pborman/uuid/uuid.go @@ -186,7 +186,7 @@ func (v Variant) String() string { return fmt.Sprintf("BadVariant%d", int(v)) } -// SetRand sets the random number generator to r, which implents io.Reader. +// SetRand sets the random number generator to r, which implements io.Reader. // If r.Read returns an error when the package requests random data then // a panic will be issued. // diff --git a/vendor/github.com/samuel/go-zookeeper/zk/conn.go b/vendor/github.com/samuel/go-zookeeper/zk/conn.go index ed87ca5ec..b6b8dbc1a 100644 --- a/vendor/github.com/samuel/go-zookeeper/zk/conn.go +++ b/vendor/github.com/samuel/go-zookeeper/zk/conn.go @@ -44,9 +44,9 @@ const ( type watchType int const ( - watchTypeData = iota - watchTypeExist = iota - watchTypeChild = iota + watchTypeData = iota + watchTypeExist + watchTypeChild ) type watchPathType struct { @@ -61,6 +61,11 @@ type Logger interface { Printf(string, ...interface{}) } +type authCreds struct { + scheme string + auth []byte +} + type Conn struct { lastZxid int64 sessionID int64 @@ -75,21 +80,28 @@ type Conn struct { server string // remember the address/port of the current server conn net.Conn eventChan chan Event + eventCallback EventCallback // may be nil shouldQuit chan struct{} pingInterval time.Duration recvTimeout time.Duration connectTimeout time.Duration + creds []authCreds + credsMu sync.Mutex // protects server + sendChan chan *request requests map[int32]*request // Xid -> pending request requestsLock sync.Mutex watchers map[watchPathType][]chan Event watchersLock sync.Mutex + closeChan chan struct{} // channel to tell send loop stop // Debug (used by unit tests) reconnectDelay time.Duration logger Logger + + buf []byte } // connOption represents a connection option. @@ -185,6 +197,7 @@ func Connect(servers []string, sessionTimeout time.Duration, options ...connOpti watchers: make(map[watchPathType][]chan Event), passwd: emptyPassword, logger: DefaultLogger, + buf: make([]byte, bufferSize), // Debug reconnectDelay: 0, @@ -224,6 +237,18 @@ func WithHostProvider(hostProvider HostProvider) connOption { } } +// EventCallback is a function that is called when an Event occurs. +type EventCallback func(Event) + +// WithEventCallback returns a connection option that specifies an event +// callback. +// The callback must not block - doing so would delay the ZK go routines. +func WithEventCallback(cb EventCallback) connOption { + return func(c *Conn) { + c.eventCallback = cb + } +} + func (c *Conn) Close() { close(c.shouldQuit) @@ -238,7 +263,7 @@ func (c *Conn) State() State { return State(atomic.LoadInt32((*int32)(&c.state))) } -// SessionId returns the current session id of the connection. +// SessionID returns the current session id of the connection. func (c *Conn) SessionID() int64 { return atomic.LoadInt64(&c.sessionID) } @@ -258,8 +283,16 @@ func (c *Conn) setTimeouts(sessionTimeoutMs int32) { func (c *Conn) setState(state State) { atomic.StoreInt32((*int32)(&c.state), int32(state)) + c.sendEvent(Event{Type: EventSession, State: state, Server: c.Server()}) +} + +func (c *Conn) sendEvent(evt Event) { + if c.eventCallback != nil { + c.eventCallback(evt) + } + select { - case c.eventChan <- Event{Type: EventSession, State: state, Server: c.Server()}: + case c.eventChan <- evt: default: // panic("zk: event channel full - it must be monitored and never allowed to be full") } @@ -296,6 +329,65 @@ func (c *Conn) connect() error { } } +func (c *Conn) resendZkAuth(reauthReadyChan chan struct{}) { + c.credsMu.Lock() + defer c.credsMu.Unlock() + + defer close(reauthReadyChan) + + c.logger.Printf("Re-submitting `%d` credentials after reconnect", + len(c.creds)) + + for _, cred := range c.creds { + resChan, err := c.sendRequest( + opSetAuth, + &setAuthRequest{Type: 0, + Scheme: cred.scheme, + Auth: cred.auth, + }, + &setAuthResponse{}, + nil) + + if err != nil { + c.logger.Printf("Call to sendRequest failed during credential resubmit: %s", err) + // FIXME(prozlach): lets ignore errors for now + continue + } + + res := <-resChan + if res.err != nil { + c.logger.Printf("Credential re-submit failed: %s", res.err) + // FIXME(prozlach): lets ignore errors for now + continue + } + } +} + +func (c *Conn) sendRequest( + opcode int32, + req interface{}, + res interface{}, + recvFunc func(*request, *responseHeader, error), +) ( + <-chan response, + error, +) { + rq := &request{ + xid: c.nextXid(), + opcode: opcode, + pkt: req, + recvStruct: res, + recvChan: make(chan response, 1), + recvFunc: recvFunc, + } + + if err := c.sendData(rq); err != nil { + return nil, err + } + + return rq.recvChan, nil +} + func (c *Conn) loop() { for { if err := c.connect(); err != nil { @@ -313,13 +405,15 @@ func (c *Conn) loop() { c.conn.Close() case err == nil: c.logger.Printf("Authenticated: id=%d, timeout=%d", c.SessionID(), c.sessionTimeoutMs) - c.hostProvider.Connected() // mark success - closeChan := make(chan struct{}) // channel to tell send loop stop - var wg sync.WaitGroup + c.hostProvider.Connected() // mark success + c.closeChan = make(chan struct{}) // channel to tell send loop stop + reauthChan := make(chan struct{}) // channel to tell send loop that authdata has been resubmitted + var wg sync.WaitGroup wg.Add(1) go func() { - err := c.sendLoop(c.conn, closeChan) + <-reauthChan + err := c.sendLoop() c.logger.Printf("Send loop terminated: err=%v", err) c.conn.Close() // causes recv loop to EOF/exit wg.Done() @@ -332,10 +426,12 @@ func (c *Conn) loop() { if err == nil { panic("zk: recvLoop should never return nil error") } - close(closeChan) // tell send loop to exit + close(c.closeChan) // tell send loop to exit wg.Done() }() + c.resendZkAuth(reauthChan) + c.sendSetWatches() wg.Wait() } @@ -507,66 +603,73 @@ func (c *Conn) authenticate() error { return nil } -func (c *Conn) sendLoop(conn net.Conn, closeChan <-chan struct{}) error { +func (c *Conn) sendData(req *request) error { + header := &requestHeader{req.xid, req.opcode} + n, err := encodePacket(c.buf[4:], header) + if err != nil { + req.recvChan <- response{-1, err} + return nil + } + + n2, err := encodePacket(c.buf[4+n:], req.pkt) + if err != nil { + req.recvChan <- response{-1, err} + return nil + } + + n += n2 + + binary.BigEndian.PutUint32(c.buf[:4], uint32(n)) + + c.requestsLock.Lock() + select { + case <-c.closeChan: + req.recvChan <- response{-1, ErrConnectionClosed} + c.requestsLock.Unlock() + return ErrConnectionClosed + default: + } + c.requests[req.xid] = req + c.requestsLock.Unlock() + + c.conn.SetWriteDeadline(time.Now().Add(c.recvTimeout)) + _, err = c.conn.Write(c.buf[:n+4]) + c.conn.SetWriteDeadline(time.Time{}) + if err != nil { + req.recvChan <- response{-1, err} + c.conn.Close() + return err + } + + return nil +} + +func (c *Conn) sendLoop() error { pingTicker := time.NewTicker(c.pingInterval) defer pingTicker.Stop() - buf := make([]byte, bufferSize) for { select { case req := <-c.sendChan: - header := &requestHeader{req.xid, req.opcode} - n, err := encodePacket(buf[4:], header) - if err != nil { - req.recvChan <- response{-1, err} - continue - } - - n2, err := encodePacket(buf[4+n:], req.pkt) - if err != nil { - req.recvChan <- response{-1, err} - continue - } - - n += n2 - - binary.BigEndian.PutUint32(buf[:4], uint32(n)) - - c.requestsLock.Lock() - select { - case <-closeChan: - req.recvChan <- response{-1, ErrConnectionClosed} - c.requestsLock.Unlock() - return ErrConnectionClosed - default: - } - c.requests[req.xid] = req - c.requestsLock.Unlock() - - conn.SetWriteDeadline(time.Now().Add(c.recvTimeout)) - _, err = conn.Write(buf[:n+4]) - conn.SetWriteDeadline(time.Time{}) - if err != nil { - req.recvChan <- response{-1, err} - conn.Close() + if err := c.sendData(req); err != nil { return err } case <-pingTicker.C: - n, err := encodePacket(buf[4:], &requestHeader{Xid: -2, Opcode: opPing}) + n, err := encodePacket(c.buf[4:], &requestHeader{Xid: -2, Opcode: opPing}) if err != nil { panic("zk: opPing should never fail to serialize") } - binary.BigEndian.PutUint32(buf[:4], uint32(n)) + binary.BigEndian.PutUint32(c.buf[:4], uint32(n)) - conn.SetWriteDeadline(time.Now().Add(c.recvTimeout)) - _, err = conn.Write(buf[:n+4]) - conn.SetWriteDeadline(time.Time{}) + c.conn.SetWriteDeadline(time.Now().Add(c.recvTimeout)) + _, err = c.conn.Write(c.buf[:n+4]) + c.conn.SetWriteDeadline(time.Time{}) if err != nil { - conn.Close() + c.conn.Close() return err } - case <-closeChan: + case <-c.closeChan: return nil } } @@ -611,10 +714,7 @@ func (c *Conn) recvLoop(conn net.Conn) error { Path: res.Path, Err: nil, } - select { - case c.eventChan <- ev: - default: - } + c.sendEvent(ev) wTypes := make([]watchType, 0, 2) switch res.Type { case EventNodeCreated: @@ -706,7 +806,28 @@ func (c *Conn) request(opcode int32, req interface{}, res interface{}, recvFunc func (c *Conn) AddAuth(scheme string, auth []byte) error { _, err := c.request(opSetAuth, &setAuthRequest{Type: 0, Scheme: scheme, Auth: auth}, &setAuthResponse{}, nil) - return err + + if err != nil { + return err + } + + // Remember authdata so that it can be re-submitted on reconnect + // + // FIXME(prozlach): For now we treat "userfoo:passbar" and "userfoo:passbar2" + // as two different entries, which will be re-submitted on reconnet. Some + // research is needed on how ZK treats these cases and + // then maybe switch to something like "map[username] = password" to allow + // only single password for given user with users being unique. + obj := authCreds{ + scheme: scheme, + auth: auth, + } + + c.credsMu.Lock() + c.creds = append(c.creds, obj) + c.credsMu.Unlock() + + return nil } func (c *Conn) Children(path string) ([]string, *Stat, error) { @@ -867,6 +988,7 @@ func (c *Conn) Sync(path string) (string, error) { type MultiResponse struct { Stat *Stat String string + Error error } // Multi executes multiple ZooKeeper operations or none of them. The provided @@ -897,7 +1019,7 @@ func (c *Conn) Multi(ops ...interface{}) ([]MultiResponse, error) { _, err := c.request(opMulti, req, res, nil) mr := make([]MultiResponse, len(res.Ops)) for i, op := range res.Ops { - mr[i] = MultiResponse{Stat: op.Stat, String: op.String} + mr[i] = MultiResponse{Stat: op.Stat, String: op.String, Error: op.Err.toError()} } return mr, err } diff --git a/vendor/github.com/samuel/go-zookeeper/zk/constants.go b/vendor/github.com/samuel/go-zookeeper/zk/constants.go index f9b39b904..33b5563b9 100644 --- a/vendor/github.com/samuel/go-zookeeper/zk/constants.go +++ b/vendor/github.com/samuel/go-zookeeper/zk/constants.go @@ -28,18 +28,19 @@ const ( opClose = -11 opSetAuth = 100 opSetWatches = 101 + opError = -1 // Not in protocol, used internally opWatcherEvent = -2 ) const ( - EventNodeCreated = EventType(1) - EventNodeDeleted = EventType(2) - EventNodeDataChanged = EventType(3) - EventNodeChildrenChanged = EventType(4) + EventNodeCreated EventType = 1 + EventNodeDeleted EventType = 2 + EventNodeDataChanged EventType = 3 + EventNodeChildrenChanged EventType = 4 - EventSession = EventType(-1) - EventNotWatching = EventType(-2) + EventSession EventType = -1 + EventNotWatching EventType = -2 ) var ( @@ -54,14 +55,13 @@ var ( ) const ( - StateUnknown = State(-1) - StateDisconnected = State(0) - StateConnecting = State(1) - StateAuthFailed = State(4) - StateConnectedReadOnly = State(5) - StateSaslAuthenticated = State(6) - StateExpired = State(-112) - // StateAuthFailed = State(-113) + StateUnknown State = -1 + StateDisconnected State = 0 + StateConnecting State = 1 + StateAuthFailed State = 4 + StateConnectedReadOnly State = 5 + StateSaslAuthenticated State = 6 + StateExpired State = -112 StateConnected = State(100) StateHasSession = State(101) @@ -154,20 +154,20 @@ const ( errBadArguments = -8 errInvalidState = -9 // API errors - errAPIError = ErrCode(-100) - errNoNode = ErrCode(-101) // * - errNoAuth = ErrCode(-102) - errBadVersion = ErrCode(-103) // * - errNoChildrenForEphemerals = ErrCode(-108) - errNodeExists = ErrCode(-110) // * - errNotEmpty = ErrCode(-111) - errSessionExpired = ErrCode(-112) - errInvalidCallback = ErrCode(-113) - errInvalidAcl = ErrCode(-114) - errAuthFailed = ErrCode(-115) - errClosing = ErrCode(-116) - errNothing = ErrCode(-117) - errSessionMoved = ErrCode(-118) + errAPIError ErrCode = -100 + errNoNode ErrCode = -101 // * + errNoAuth ErrCode = -102 + errBadVersion ErrCode = -103 // * + errNoChildrenForEphemerals ErrCode = -108 + errNodeExists ErrCode = -110 // * + errNotEmpty ErrCode = -111 + errSessionExpired ErrCode = -112 + errInvalidCallback ErrCode = -113 + errInvalidAcl ErrCode = -114 + errAuthFailed ErrCode = -115 + errClosing ErrCode = -116 + errNothing ErrCode = -117 + errSessionMoved ErrCode = -118 ) // Constants for ACL permissions diff --git a/vendor/github.com/samuel/go-zookeeper/zk/lock.go b/vendor/github.com/samuel/go-zookeeper/zk/lock.go index f13a8b0ba..af257491f 100644 --- a/vendor/github.com/samuel/go-zookeeper/zk/lock.go +++ b/vendor/github.com/samuel/go-zookeeper/zk/lock.go @@ -58,8 +58,16 @@ func (l *Lock) Lock() error { parts := strings.Split(l.path, "/") pth := "" for _, p := range parts[1:] { + var exists bool pth += "/" + p - _, err := l.c.Create(pth, []byte{}, 0, l.acl) + exists, _, err = l.c.Exists(pth) + if err != nil { + return err + } + if exists == true { + continue + } + _, err = l.c.Create(pth, []byte{}, 0, l.acl) if err != nil && err != ErrNodeExists { return err } diff --git a/vendor/github.com/samuel/go-zookeeper/zk/server_help.go b/vendor/github.com/samuel/go-zookeeper/zk/server_help.go index 618185a23..3663064ca 100644 --- a/vendor/github.com/samuel/go-zookeeper/zk/server_help.go +++ b/vendor/github.com/samuel/go-zookeeper/zk/server_help.go @@ -99,37 +99,41 @@ func StartTestCluster(size int, stdout, stderr io.Writer) (*TestCluster, error) return cluster, nil } -func (ts *TestCluster) Connect(idx int) (*Conn, error) { - zk, _, err := Connect([]string{fmt.Sprintf("127.0.0.1:%d", ts.Servers[idx].Port)}, time.Second*15) +func (tc *TestCluster) Connect(idx int) (*Conn, error) { + zk, _, err := Connect([]string{fmt.Sprintf("127.0.0.1:%d", tc.Servers[idx].Port)}, time.Second*15) return zk, err } -func (ts *TestCluster) ConnectAll() (*Conn, <-chan Event, error) { - return ts.ConnectAllTimeout(time.Second * 15) +func (tc *TestCluster) ConnectAll() (*Conn, <-chan Event, error) { + return tc.ConnectAllTimeout(time.Second * 15) } -func (ts *TestCluster) ConnectAllTimeout(sessionTimeout time.Duration) (*Conn, <-chan Event, error) { - hosts := make([]string, len(ts.Servers)) - for i, srv := range ts.Servers { +func (tc *TestCluster) ConnectAllTimeout(sessionTimeout time.Duration) (*Conn, <-chan Event, error) { + return tc.ConnectWithOptions(sessionTimeout) +} + +func (tc *TestCluster) ConnectWithOptions(sessionTimeout time.Duration, options ...connOption) (*Conn, <-chan Event, error) { + hosts := make([]string, len(tc.Servers)) + for i, srv := range tc.Servers { hosts[i] = fmt.Sprintf("127.0.0.1:%d", srv.Port) } - zk, ch, err := Connect(hosts, sessionTimeout) + zk, ch, err := Connect(hosts, sessionTimeout, options...) return zk, ch, err } -func (ts *TestCluster) Stop() error { - for _, srv := range ts.Servers { +func (tc *TestCluster) Stop() error { + for _, srv := range tc.Servers { srv.Srv.Stop() } - defer os.RemoveAll(ts.Path) - return ts.waitForStop(5, time.Second) + defer os.RemoveAll(tc.Path) + return tc.waitForStop(5, time.Second) } // waitForStart blocks until the cluster is up -func (ts *TestCluster) waitForStart(maxRetry int, interval time.Duration) error { +func (tc *TestCluster) waitForStart(maxRetry int, interval time.Duration) error { // verify that the servers are up with SRVR - serverAddrs := make([]string, len(ts.Servers)) - for i, s := range ts.Servers { + serverAddrs := make([]string, len(tc.Servers)) + for i, s := range tc.Servers { serverAddrs[i] = fmt.Sprintf("127.0.0.1:%d", s.Port) } @@ -144,10 +148,10 @@ func (ts *TestCluster) waitForStart(maxRetry int, interval time.Duration) error } // waitForStop blocks until the cluster is down -func (ts *TestCluster) waitForStop(maxRetry int, interval time.Duration) error { +func (tc *TestCluster) waitForStop(maxRetry int, interval time.Duration) error { // verify that the servers are up with RUOK - serverAddrs := make([]string, len(ts.Servers)) - for i, s := range ts.Servers { + serverAddrs := make([]string, len(tc.Servers)) + for i, s := range tc.Servers { serverAddrs[i] = fmt.Sprintf("127.0.0.1:%d", s.Port) } @@ -188,3 +192,25 @@ func (tc *TestCluster) StopServer(server string) { } panic(fmt.Sprintf("Unknown server: %s", server)) } + +func (tc *TestCluster) StartAllServers() error { + for _, s := range tc.Servers { + if err := s.Srv.Start(); err != nil { + return fmt.Errorf( + "Failed to start server listening on port `%d` : %+v", s.Port, err) + } + } + + return nil +} + +func (tc *TestCluster) StopAllServers() error { + for _, s := range tc.Servers { + if err := s.Srv.Stop(); err != nil { + return fmt.Errorf( + "Failed to stop server listening on port `%d` : %+v", s.Port, err) + } + } + + return nil +} diff --git a/vendor/github.com/samuel/go-zookeeper/zk/structs.go b/vendor/github.com/samuel/go-zookeeper/zk/structs.go index 02cd3f353..d4af27dea 100644 --- a/vendor/github.com/samuel/go-zookeeper/zk/structs.go +++ b/vendor/github.com/samuel/go-zookeeper/zk/structs.go @@ -270,6 +270,7 @@ type multiResponseOp struct { Header multiHeader String string Stat *Stat + Err ErrCode } type multiResponse struct { Ops []multiResponseOp @@ -327,6 +328,8 @@ func (r *multiRequest) Decode(buf []byte) (int, error) { } func (r *multiResponse) Decode(buf []byte) (int, error) { + var multiErr error + r.Ops = make([]multiResponseOp, 0) r.DoneHeader = multiHeader{-1, true, -1} total := 0 @@ -347,6 +350,8 @@ func (r *multiResponse) Decode(buf []byte) (int, error) { switch header.Type { default: return total, ErrAPIError + case opError: + w = reflect.ValueOf(&res.Err) case opCreate: w = reflect.ValueOf(&res.String) case opSetData: @@ -362,8 +367,12 @@ func (r *multiResponse) Decode(buf []byte) (int, error) { total += n } r.Ops = append(r.Ops, res) + if multiErr == nil && res.Err != errOk { + // Use the first error as the error returned from Multi(). + multiErr = res.Err.toError() + } } - return total, nil + return total, multiErr } type watcherEvent struct { diff --git a/vendor/github.com/ugorji/go/codec/0doc.go b/vendor/github.com/ugorji/go/codec/0doc.go index 7548d7d0c..209f9ebad 100644 --- a/vendor/github.com/ugorji/go/codec/0doc.go +++ b/vendor/github.com/ugorji/go/codec/0doc.go @@ -181,7 +181,7 @@ package codec // - Decoding using a chan is good, but incurs concurrency costs. // This is because there's no fast way to use a channel without it // having to switch goroutines constantly. -// Callback pattern is still the best. Maybe cnsider supporting something like: +// Callback pattern is still the best. Maybe consider supporting something like: // type X struct { // Name string // Ys []Y diff --git a/vendor/github.com/ugorji/go/codec/encode.go b/vendor/github.com/ugorji/go/codec/encode.go index 4d1a2b9f4..e3e3bc267 100644 --- a/vendor/github.com/ugorji/go/codec/encode.go +++ b/vendor/github.com/ugorji/go/codec/encode.go @@ -119,6 +119,12 @@ type EncodeOptions struct { // This is opt-in, as there may be a performance hit to checking circular references. CheckCircularRef bool + // RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers + // when checking if a value is empty. + // + // Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls. + RecursiveEmptyCheck bool + // AsSymbols defines what should be encoded as symbols. // // Encoding as symbols can reduce the encoded size significantly. @@ -524,20 +530,20 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { } newlen = 0 var kv stringRv + recur := e.h.RecursiveEmptyCheck for _, si := range tisfi { kv.r = si.field(rv, false) if toMap { - if si.omitEmpty && isEmptyValue(kv.r) { + if si.omitEmpty && isEmptyValue(kv.r, recur, recur) { continue } kv.v = si.encName } else { // use the zero value. // if a reference or struct, set to nil (so you do not output too much) - if si.omitEmpty && isEmptyValue(kv.r) { + if si.omitEmpty && isEmptyValue(kv.r, recur, recur) { switch kv.r.Kind() { - case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, - reflect.Map, reflect.Slice: + case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice: kv.r = reflect.Value{} //encode as nil } } diff --git a/vendor/github.com/ugorji/go/codec/gen.go b/vendor/github.com/ugorji/go/codec/gen.go index e3998444a..0a51fa9ba 100644 --- a/vendor/github.com/ugorji/go/codec/gen.go +++ b/vendor/github.com/ugorji/go/codec/gen.go @@ -987,6 +987,14 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { } func (x *genRunner) encListFallback(varname string, t reflect.Type) { + if t.AssignableTo(uint8SliceTyp) { + x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, []byte(%s))", x.xs, varname) + return + } + if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 { + x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, ([%v]byte(%s))[:])", x.xs, t.Len(), varname) + return + } i := x.varsfx() g := genTempVarPfx x.line("r.EncodeArrayStart(len(" + varname + "))") @@ -1306,6 +1314,14 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs } func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) { + if t.AssignableTo(uint8SliceTyp) { + x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false, false)") + return + } + if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 { + x.linef("r.DecodeBytes( ((*[%s]byte)(%s))[:], false, true)", t.Len(), varname) + return + } type tstruc struct { TempVar string Rand string diff --git a/vendor/github.com/ugorji/go/codec/gen_17.go b/vendor/github.com/ugorji/go/codec/gen_17.go new file mode 100644 index 000000000..3881a43ce --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/gen_17.go @@ -0,0 +1,10 @@ +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// +build go1.7 + +package codec + +func init() { + genCheckVendor = true +} diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go index ec8dedfb3..46adb76af 100644 --- a/vendor/github.com/ugorji/go/codec/helper.go +++ b/vendor/github.com/ugorji/go/codec/helper.go @@ -137,13 +137,6 @@ const ( // Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic. recoverPanicToErr = true - // if checkStructForEmptyValue, check structs fields to see if an empty value. - // This could be an expensive call, so possibly disable it. - checkStructForEmptyValue = false - - // if derefForIsEmptyValue, deref pointers and interfaces when checking isEmptyValue - derefForIsEmptyValue = false - // if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first. // Only concern is that, if the slice already contained some garbage, we will decode into that garbage. // The chances of this are slim, so leave this "optimization". @@ -213,10 +206,10 @@ const ( containerArrayEnd ) -// sfiIdx used for tracking where a fieldName is seen in a []*structFieldInfo +// sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo type sfiIdx struct { - fieldName string - index int + name string + index int } // do not recurse if a containing type refers to an embedded type @@ -1003,26 +996,35 @@ LOOP: } } -// resolves the struct field info get from a call to rget2. +// resolves the struct field info got from a call to rget. // Returns a trimmed, unsorted and sorted []*structFieldInfo. func rgetResolveSFI(x []*structFieldInfo, pv []sfiIdx) (y, z []*structFieldInfo) { var n int for i, v := range x { - xf := v.fieldName + xn := v.encName //TODO: fieldName or encName? use encName for now. var found bool - for _, k := range pv { - if k.fieldName == xf { - if len(v.is) < len(x[k.index].is) { - x[k.index] = nil - k.index = i - n++ + for j, k := range pv { + if k.name == xn { + // one of them must be reset to nil, and the index updated appropriately to the other one + if len(v.is) == len(x[k.index].is) { + } else if len(v.is) < len(x[k.index].is) { + pv[j].index = i + if x[k.index] != nil { + x[k.index] = nil + n++ + } + } else { + if x[i] != nil { + x[i] = nil + n++ + } } found = true break } } if !found { - pv = append(pv, sfiIdx{xf, i}) + pv = append(pv, sfiIdx{xn, i}) } } diff --git a/vendor/github.com/ugorji/go/codec/helper_internal.go b/vendor/github.com/ugorji/go/codec/helper_internal.go index dea981fbb..5d0727f77 100644 --- a/vendor/github.com/ugorji/go/codec/helper_internal.go +++ b/vendor/github.com/ugorji/go/codec/helper_internal.go @@ -70,8 +70,8 @@ func hIsEmptyValue(v reflect.Value, deref, checkStruct bool) bool { return false } -func isEmptyValue(v reflect.Value) bool { - return hIsEmptyValue(v, derefForIsEmptyValue, checkStructForEmptyValue) +func isEmptyValue(v reflect.Value, deref, checkStruct bool) bool { + return hIsEmptyValue(v, deref, checkStruct) } func pruneSignExt(v []byte, pos bool) (n int) { diff --git a/vendor/github.com/ugorji/go/codec/simple.go b/vendor/github.com/ugorji/go/codec/simple.go index daf71f23c..9619b2bff 100644 --- a/vendor/github.com/ugorji/go/codec/simple.go +++ b/vendor/github.com/ugorji/go/codec/simple.go @@ -474,7 +474,7 @@ func (d *simpleDecDriver) DecodeNaked() { // SimpleHandle is a Handle for a very simple encoding format. // // simple is a simplistic codec similar to binc, but not as compact. -// - Encoding of a value is always precedeed by the descriptor byte (bd) +// - Encoding of a value is always preceded by the descriptor byte (bd) // - True, false, nil are encoded fully in 1 byte (the descriptor) // - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte). // There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers. diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go index 979d919e8..e786f2f9a 100644 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ b/vendor/golang.org/x/crypto/ssh/connection.go @@ -23,7 +23,6 @@ func (e *OpenChannelError) Error() string { // ConnMetadata holds metadata for the connection. type ConnMetadata interface { // User returns the user ID for this connection. - // It is empty if no authentication is used. User() string // SessionID returns the sesson hash, also denoted by H. diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index e73a1c1ae..37df1b302 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -284,7 +284,6 @@ userAuthLoop: switch userAuthReq.Method { case "none": if config.NoClientAuth { - s.user = "" authErr = nil } case "password": diff --git a/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go new file mode 100644 index 000000000..b4c52ecec --- /dev/null +++ b/vendor/golang.org/x/net/http2/go17_not18.go @@ -0,0 +1,36 @@ +// Copyright 2016 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. + +// +build go1.7,!go1.8 + +package http2 + +import "crypto/tls" + +// temporary copy of Go 1.7's private tls.Config.clone: +func cloneTLSConfig(c *tls.Config) *tls.Config { + return &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, + Renegotiation: c.Renegotiation, + } +} diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go new file mode 100644 index 000000000..c2ae16731 --- /dev/null +++ b/vendor/golang.org/x/net/http2/go18.go @@ -0,0 +1,11 @@ +// Copyright 2015 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. + +// +build go1.8 + +package http2 + +import "crypto/tls" + +func cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() } diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index f06e87b3e..401923bc7 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -350,3 +350,13 @@ func (s *sorter) SortStrings(ss []string) { sort.Sort(s) s.v = save } + +// 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. +// 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] != '/') +} diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go index 28df0c16b..667867f4d 100644 --- a/vendor/golang.org/x/net/http2/not_go17.go +++ b/vendor/golang.org/x/net/http2/not_go17.go @@ -7,6 +7,7 @@ package http2 import ( + "crypto/tls" "net" "net/http" ) @@ -49,3 +50,28 @@ func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { func requestWithContext(req *http.Request, ctx contextContext) *http.Request { return req } + +// temporary copy of Go 1.6's private tls.Config.clone: +func cloneTLSConfig(c *tls.Config) *tls.Config { + return &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + } +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 3cefc22a6..47c66d9b0 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -356,7 +356,7 @@ func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, er func (t *Transport) newTLSConfig(host string) *tls.Config { cfg := new(tls.Config) if t.TLSClientConfig != nil { - *cfg = *t.TLSClientConfig + *cfg = *cloneTLSConfig(t.TLSClientConfig) } if !strSliceContains(cfg.NextProtos, NextProtoTLS) { cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...) @@ -622,15 +622,18 @@ func bodyAndLength(req *http.Request) (body io.Reader, contentLen int64) { // We have a body but a zero content length. Test to see if // it's actually zero or just unset. var buf [1]byte - n, rerr := io.ReadFull(body, buf[:]) + n, rerr := body.Read(buf[:]) if rerr != nil && rerr != io.EOF { return errorReader{rerr}, -1 } if n == 1 { // Oh, guess there is data in this Body Reader after all. // The ContentLength field just wasn't set. - // Stich the Body back together again, re-attaching our + // Stitch the Body back together again, re-attaching our // consumed byte. + if rerr == io.EOF { + return bytes.NewReader(buf[:]), 1 + } return io.MultiReader(bytes.NewReader(buf[:]), body), -1 } // Body is actually zero bytes. @@ -901,10 +904,11 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( err = cc.fr.WriteData(cs.ID, sentEnd, data) if err == nil { // TODO(bradfitz): this flush is for latency, not bandwidth. - // Most requests won't need this. Make this opt-in or opt-out? - // Use some heuristic on the body type? Nagel-like timers? - // Based on 'n'? Only last chunk of this for loop, unless flow control - // tokens are low? For now, always: + // Most requests won't need this. Make this opt-in or + // opt-out? Use some heuristic on the body type? Nagel-like + // timers? Based on 'n'? Only last chunk of this for loop, + // unless flow control tokens are low? For now, always. + // If we change this, see comment below. err = cc.bw.Flush() } cc.wmu.Unlock() @@ -914,8 +918,15 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( } } + if sentEnd { + // Already sent END_STREAM (which implies we have no + // trailers) and flushed, because currently all + // WriteData frames above get a flush. So we're done. + return nil + } + var trls []byte - if !sentEnd && hasTrailers { + if hasTrailers { cc.mu.Lock() defer cc.mu.Unlock() trls = cc.encodeTrailers(req) @@ -924,8 +935,8 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( cc.wmu.Lock() defer cc.wmu.Unlock() - // Avoid forgetting to send an END_STREAM if the encoded - // trailers are 0 bytes. Both results produce and END_STREAM. + // Two ways to send END_STREAM: either with trailers, or + // with an empty DATA frame. if len(trls) > 0 { err = cc.writeHeaders(cs.ID, true, trls) } else { @@ -987,6 +998,22 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail host = req.URL.Host } + var path string + if req.Method != "CONNECT" { + path = req.URL.RequestURI() + if !validPseudoPath(path) { + orig := path + path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) + if !validPseudoPath(path) { + if req.URL.Opaque != "" { + return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) + } else { + return nil, fmt.Errorf("invalid request :path %q", orig) + } + } + } + } + // Check for any invalid headers and return an error before we // potentially pollute our hpack state. (We want to be able to // continue to reuse the hpack encoder for future requests) @@ -1009,7 +1036,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail cc.writeHeader(":authority", host) cc.writeHeader(":method", req.Method) if req.Method != "CONNECT" { - cc.writeHeader(":path", req.URL.RequestURI()) + cc.writeHeader(":path", path) cc.writeHeader(":scheme", "https") } if trailers != "" { diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md index 0d5141733..1643c08ef 100644 --- a/vendor/golang.org/x/oauth2/README.md +++ b/vendor/golang.org/x/oauth2/README.md @@ -1,6 +1,7 @@ # OAuth2 for Go [![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) +[![GoDoc](https://godoc.org/golang.org/x/oauth2?status.svg)](https://godoc.org/golang.org/x/oauth2) oauth2 package contains a client implementation for OAuth 2.0 spec. diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go index d54ee26f6..7b06bfe1e 100644 --- a/vendor/golang.org/x/oauth2/oauth2.go +++ b/vendor/golang.org/x/oauth2/oauth2.go @@ -21,6 +21,8 @@ import ( // NoContext is the default context you should supply if not using // your own context.Context (see https://golang.org/x/net/context). +// +// Deprecated: Use context.Background() or context.TODO() instead. var NoContext = context.TODO() // RegisterBrokenAuthHeaderProvider registers an OAuth2 server @@ -37,6 +39,8 @@ func RegisterBrokenAuthHeaderProvider(tokenURL string) { // Config describes a typical 3-legged OAuth2 flow, with both the // client application information and the server's endpoint URLs. +// For the client credentials 2-legged OAuth2 flow, see the clientcredentials +// package (https://golang.org/x/oauth2/clientcredentials). type Config struct { // ClientID is the application's ID. ClientID string diff --git a/vendor/google.golang.org/appengine/internal/internal.go b/vendor/google.golang.org/appengine/internal/internal.go index 66e8d7686..051ea3980 100644 --- a/vendor/google.golang.org/appengine/internal/internal.go +++ b/vendor/google.golang.org/appengine/internal/internal.go @@ -10,11 +10,6 @@ package internal import ( "fmt" - "io" - "log" - "net/http" - "net/url" - "os" "github.com/golang/protobuf/proto" @@ -109,35 +104,6 @@ func (e *CallError) IsTimeout() bool { return e.Timeout } -func Main() { - installHealthChecker(http.DefaultServeMux) - - port := "8080" - if s := os.Getenv("PORT"); s != "" { - port = s - } - - if err := http.ListenAndServe(":"+port, http.HandlerFunc(handleHTTP)); err != nil { - log.Fatalf("http.ListenAndServe: %v", err) - } -} - -func installHealthChecker(mux *http.ServeMux) { - // If no health check handler has been installed by this point, add a trivial one. - const healthPath = "/_ah/health" - hreq := &http.Request{ - Method: "GET", - URL: &url.URL{ - Path: healthPath, - }, - } - if _, pat := mux.Handler(hreq); pat != healthPath { - mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) { - io.WriteString(w, "ok") - }) - } -} - // NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace. // The function should be prepared to be called on the same message more than once; it should only modify the // RPC request the first time. diff --git a/vendor/google.golang.org/appengine/internal/main.go b/vendor/google.golang.org/appengine/internal/main.go new file mode 100644 index 000000000..49036163c --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/main.go @@ -0,0 +1,15 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build appengine + +package internal + +import ( + "appengine_internal" +) + +func Main() { + appengine_internal.Main() +} diff --git a/vendor/google.golang.org/appengine/internal/main_vm.go b/vendor/google.golang.org/appengine/internal/main_vm.go new file mode 100644 index 000000000..57331ad17 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/main_vm.go @@ -0,0 +1,44 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build !appengine + +package internal + +import ( + "io" + "log" + "net/http" + "net/url" + "os" +) + +func Main() { + installHealthChecker(http.DefaultServeMux) + + port := "8080" + if s := os.Getenv("PORT"); s != "" { + port = s + } + + if err := http.ListenAndServe(":"+port, http.HandlerFunc(handleHTTP)); err != nil { + log.Fatalf("http.ListenAndServe: %v", err) + } +} + +func installHealthChecker(mux *http.ServeMux) { + // If no health check handler has been installed by this point, add a trivial one. + const healthPath = "/_ah/health" + hreq := &http.Request{ + Method: "GET", + URL: &url.URL{ + Path: healthPath, + }, + } + if _, pat := mux.Handler(hreq); pat != healthPath { + mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "ok") + }) + } +} diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index 90e9453d5..660658bed 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -28,5 +28,5 @@ See [API documentation](https://godoc.org/google.golang.org/grpc) for package an Status ------ -Beta release +GA diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index fea07998d..fbd55a49b 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -96,7 +96,7 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd } outBuf, err := encode(codec, args, compressor, cbuf) if err != nil { - return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err) + return nil, Errorf(codes.Internal, "grpc: %v", err) } err = t.Write(stream, outBuf, opts) // t.NewStream(...) could lead to an early rejection of the RPC (e.g., the service/method diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index f5bdafb90..1d3b46c60 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -220,14 +220,29 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) { return DialContext(context.Background(), target, opts...) } -// DialContext creates a client connection to the given target -// using the supplied context. -func DialContext(ctx context.Context, target string, opts ...DialOption) (*ClientConn, error) { +// DialContext creates a client connection to the given target. ctx can be used to +// cancel or expire the pending connecting. Once this function returns, the +// cancellation and expiration of ctx will be noop. Users should call ClientConn.Close +// to terminate all the pending operations after this function returns. +// This is the EXPERIMENTAL API. +func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ target: target, conns: make(map[Address]*addrConn), } - cc.ctx, cc.cancel = context.WithCancel(ctx) + cc.ctx, cc.cancel = context.WithCancel(context.Background()) + defer func() { + select { + case <-ctx.Done(): + conn, err = nil, ctx.Err() + default: + } + + if err != nil { + cc.Close() + } + }() + for _, opt := range opts { opt(&cc.dopts) } @@ -277,16 +292,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (*Clien timeoutCh = time.After(cc.dopts.timeout) } select { + case <-ctx.Done(): + return nil, ctx.Err() case err := <-waitC: if err != nil { - cc.Close() return nil, err } - case <-cc.ctx.Done(): - cc.Close() - return nil, cc.ctx.Err() case <-timeoutCh: - cc.Close() return nil, ErrClientConnTimeout } // If balancer is nil or balancer.Notify() is nil, ok will be false here. @@ -479,6 +491,10 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) if cc.dopts.balancer == nil { // If balancer is nil, there should be only one addrConn available. cc.mu.RLock() + if cc.conns == nil { + cc.mu.RUnlock() + return nil, nil, toRPCErr(ErrClientConnClosing) + } for _, ac = range cc.conns { // Break after the first iteration to get the first addrConn. ok = true diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 3f17b7062..13be45742 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -40,6 +40,7 @@ package credentials // import "google.golang.org/grpc/credentials" import ( "crypto/tls" "crypto/x509" + "errors" "fmt" "io/ioutil" "net" @@ -86,6 +87,12 @@ type AuthInfo interface { AuthType() string } +var ( + // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC + // and the caller should not close rawConn. + ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC") +) + // TransportCredentials defines the common interface for all the live gRPC wire // protocols and supported transport security protocols (e.g., TLS, SSL). type TransportCredentials interface { diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 35ac9cc7b..6b60095d5 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -303,10 +303,10 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er case compressionNone: case compressionMade: if dc == nil || recvCompress != dc.Type() { - return transport.StreamErrorf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) + return Errorf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) } default: - return transport.StreamErrorf(codes.Internal, "grpc: received unexpected payload format %d", pf) + return Errorf(codes.Internal, "grpc: received unexpected payload format %d", pf) } return nil } diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 1ed8aac9e..2524dd229 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -324,7 +324,7 @@ func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credenti // Serve accepts incoming connections on the listener lis, creating a new // ServerTransport and service goroutine for each. The service goroutines // read gRPC requests and then call the registered handlers to reply to them. -// Service returns when lis.Accept fails. lis will be closed when +// Serve returns when lis.Accept fails. lis will be closed when // this method returns. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() @@ -367,7 +367,10 @@ func (s *Server) handleRawConn(rawConn net.Conn) { s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) s.mu.Unlock() grpclog.Printf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) - rawConn.Close() + // If serverHandShake returns ErrConnDispatched, keep rawConn open. + if err != credentials.ErrConnDispatched { + rawConn.Close() + } return } @@ -544,7 +547,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. return err } if err == io.ErrUnexpectedEOF { - err = transport.StreamError{Code: codes.Internal, Desc: "io.ErrUnexpectedEOF"} + err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error()) } if err != nil { switch err := err.(type) { @@ -566,8 +569,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil { switch err := err.(type) { - case transport.StreamError: - if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { + case *rpcError: + if err := t.WriteStatus(stream, err.code, err.desc); err != nil { grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) } default: diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 51df3f01d..ff68fc78b 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -296,7 +296,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } }() if err != nil { - return transport.StreamErrorf(codes.Internal, "grpc: %v", err) + return Errorf(codes.Internal, "grpc: %v", err) } return cs.t.Write(cs.s, out, &transport.Options{Last: false}) } @@ -468,10 +468,13 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { } }() if err != nil { - err = transport.StreamErrorf(codes.Internal, "grpc: %v", err) + err = Errorf(codes.Internal, "grpc: %v", err) return err } - return ss.t.Write(ss.s, out, &transport.Options{Last: false}) + if err := ss.t.Write(ss.s, out, &transport.Options{Last: false}); err != nil { + return toRPCErr(err) + } + return nil } func (ss *serverStream) RecvMsg(m interface{}) (err error) { @@ -489,5 +492,14 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { ss.mu.Unlock() } }() - return recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize) + if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize); err != nil { + if err == io.EOF { + return err + } + if err == io.ErrUnexpectedEOF { + err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error()) + } + return toRPCErr(err) + } + return nil } diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go index 30e21ac0f..114e34906 100644 --- a/vendor/google.golang.org/grpc/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/transport/handler_server.go @@ -85,7 +85,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTr if v := r.Header.Get("grpc-timeout"); v != "" { to, err := decodeTimeout(v) if err != nil { - return nil, StreamErrorf(codes.Internal, "malformed time-out: %v", err) + return nil, streamErrorf(codes.Internal, "malformed time-out: %v", err) } st.timeoutSet = true st.timeout = to @@ -393,5 +393,5 @@ func mapRecvMsgError(err error) error { } } } - return ConnectionError{Desc: err.Error()} + return connectionErrorf(true, err, err.Error()) } diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go index 5819cb8a4..4892faab0 100644 --- a/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/transport/http2_client.go @@ -114,14 +114,42 @@ func dial(fn func(context.Context, string) (net.Conn, error), ctx context.Contex return dialContext(ctx, "tcp", addr) } +func isTemporary(err error) bool { + switch err { + case io.EOF: + // Connection closures may be resolved upon retry, and are thus + // treated as temporary. + return true + case context.DeadlineExceeded: + // In Go 1.7, context.DeadlineExceeded implements Timeout(), and this + // special case is not needed. Until then, we need to keep this + // clause. + return true + } + + switch err := err.(type) { + case interface { + Temporary() bool + }: + return err.Temporary() + case interface { + Timeout() bool + }: + // Timeouts may be resolved upon retry, and are thus treated as + // temporary. + return err.Timeout() + } + return false +} + // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ ClientTransport, err error) { scheme := "http" - conn, connErr := dial(opts.Dialer, ctx, addr) - if connErr != nil { - return nil, ConnectionErrorf(true, connErr, "transport: %v", connErr) + conn, err := dial(opts.Dialer, ctx, addr) + if err != nil { + return nil, connectionErrorf(true, err, "transport: %v", err) } // Any further errors will close the underlying connection defer func(conn net.Conn) { @@ -132,12 +160,13 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl var authInfo credentials.AuthInfo if creds := opts.TransportCredentials; creds != nil { scheme = "https" - conn, authInfo, connErr = creds.ClientHandshake(ctx, addr, conn) - } - if connErr != nil { - // Credentials handshake error is not a temporary error (unless the error - // was the connection closing). - return nil, ConnectionErrorf(connErr == io.EOF, connErr, "transport: %v", connErr) + conn, authInfo, err = creds.ClientHandshake(ctx, addr, conn) + if err != nil { + // Credentials handshake errors are typically considered permanent + // to avoid retrying on e.g. bad certificates. + temp := isTemporary(err) + return nil, connectionErrorf(temp, err, "transport: %v", err) + } } ua := primaryUA if opts.UserAgent != "" { @@ -176,11 +205,11 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl n, err := t.conn.Write(clientPreface) if err != nil { t.Close() - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } if n != len(clientPreface) { t.Close() - return nil, ConnectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) + return nil, connectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) } if initialWindowSize != defaultWindowSize { err = t.framer.writeSettings(true, http2.Setting{ @@ -192,13 +221,13 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl } if err != nil { t.Close() - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } // Adjust the connection flow control window if needed. if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 { if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil { t.Close() - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } } go t.controller() @@ -266,12 +295,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } pos := strings.LastIndex(callHdr.Method, "/") if pos == -1 { - return nil, StreamErrorf(codes.InvalidArgument, "transport: malformed method name: %q", callHdr.Method) + return nil, streamErrorf(codes.InvalidArgument, "transport: malformed method name: %q", callHdr.Method) } audience := "https://" + callHdr.Host + port + callHdr.Method[:pos] data, err := c.GetRequestMetadata(ctx, audience) if err != nil { - return nil, StreamErrorf(codes.InvalidArgument, "transport: %v", err) + return nil, streamErrorf(codes.InvalidArgument, "transport: %v", err) } for k, v := range data { authData[k] = v @@ -408,7 +437,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } if err != nil { t.notifyError(err) - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } } t.writableChan <- 0 @@ -454,7 +483,7 @@ func (t *http2Client) CloseStream(s *Stream, err error) { } s.state = streamDone s.mu.Unlock() - if _, ok := err.(StreamError); ok { + if se, ok := err.(StreamError); ok && se.Code != codes.DeadlineExceeded { t.controlBuf.put(&resetStream{s.id, http2.ErrCodeCancel}) } } @@ -622,7 +651,7 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error { // invoked. if err := t.framer.writeData(forceFlush, s.id, endStream, p); err != nil { t.notifyError(err) - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } if t.framer.adjustNumWriters(-1) == 0 { t.framer.flushWrite() @@ -670,7 +699,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { func (t *http2Client) handleData(f *http2.DataFrame) { size := len(f.Data()) if err := t.fc.onData(uint32(size)); err != nil { - t.notifyError(ConnectionErrorf(true, err, "%v", err)) + t.notifyError(connectionErrorf(true, err, "%v", err)) return } // Select the right stream to dispatch. @@ -776,7 +805,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { if t.state == reachable || t.state == draining { if f.LastStreamID > 0 && f.LastStreamID%2 != 1 { t.mu.Unlock() - t.notifyError(ConnectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID)) + t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID)) return } select { @@ -785,7 +814,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { // t.goAway has been closed (i.e.,multiple GoAways). if id < f.LastStreamID { t.mu.Unlock() - t.notifyError(ConnectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID)) + t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID)) return } t.prevGoAwayID = id @@ -900,7 +929,7 @@ func (t *http2Client) reader() { t.mu.Unlock() if s != nil { // use error detail to provide better err message - handleMalformedHTTP2(s, StreamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail())) + handleMalformedHTTP2(s, streamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail())) } continue } else { diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go index 16010d55f..f753c4f1e 100644 --- a/vendor/google.golang.org/grpc/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/transport/http2_server.go @@ -111,12 +111,12 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI Val: uint32(initialWindowSize)}) } if err := framer.writeSettings(true, settings...); err != nil { - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } // Adjust the connection flow control window if needed. if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 { if err := framer.writeWindowUpdate(true, 0, delta); err != nil { - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } } var buf bytes.Buffer @@ -448,7 +448,7 @@ func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) e } if err != nil { t.Close() - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } } return nil @@ -544,7 +544,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { s.mu.Lock() if s.state == streamDone { s.mu.Unlock() - return StreamErrorf(codes.Unknown, "the stream has been done") + return streamErrorf(codes.Unknown, "the stream has been done") } if !s.headerOk { writeHeaderFrame = true @@ -568,7 +568,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { } if err := t.framer.writeHeaders(false, p); err != nil { t.Close() - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } t.writableChan <- 0 } @@ -642,7 +642,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { } if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil { t.Close() - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } if t.framer.adjustNumWriters(-1) == 0 { t.framer.flushWrite() diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go index 3e16e4df4..b024594e7 100644 --- a/vendor/google.golang.org/grpc/transport/http_util.go +++ b/vendor/google.golang.org/grpc/transport/http_util.go @@ -53,7 +53,7 @@ import ( const ( // The primary user agent - primaryUA = "grpc-go/0.11" + primaryUA = "grpc-go/1.0" // http2MaxFrameLen specifies the max length of a HTTP2 frame. http2MaxFrameLen = 16384 // 16KB frame // http://http2.github.io/http2-spec/#SettingValues @@ -162,7 +162,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { switch f.Name { case "content-type": if !validContentType(f.Value) { - d.setErr(StreamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value)) + d.setErr(streamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value)) return } case "grpc-encoding": @@ -170,7 +170,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { case "grpc-status": code, err := strconv.Atoi(f.Value) if err != nil { - d.setErr(StreamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)) + d.setErr(streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)) return } d.statusCode = codes.Code(code) @@ -181,7 +181,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { var err error d.timeout, err = decodeTimeout(f.Value) if err != nil { - d.setErr(StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err)) + d.setErr(streamErrorf(codes.Internal, "transport: malformed time-out: %v", err)) return } case ":path": diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go index d59e51137..f4d8dafae 100644 --- a/vendor/google.golang.org/grpc/transport/transport.go +++ b/vendor/google.golang.org/grpc/transport/transport.go @@ -476,16 +476,16 @@ type ServerTransport interface { Drain() } -// StreamErrorf creates an StreamError with the specified error code and description. -func StreamErrorf(c codes.Code, format string, a ...interface{}) StreamError { +// streamErrorf creates an StreamError with the specified error code and description. +func streamErrorf(c codes.Code, format string, a ...interface{}) StreamError { return StreamError{ Code: c, Desc: fmt.Sprintf(format, a...), } } -// ConnectionErrorf creates an ConnectionError with the specified error description. -func ConnectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { +// connectionErrorf creates an ConnectionError with the specified error description. +func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { return ConnectionError{ Desc: fmt.Sprintf(format, a...), temp: temp, @@ -522,10 +522,10 @@ func (e ConnectionError) Origin() error { var ( // ErrConnClosing indicates that the transport is closing. - ErrConnClosing = ConnectionError{Desc: "transport is closing", temp: true} + ErrConnClosing = connectionErrorf(true, nil, "transport is closing") // ErrStreamDrain indicates that the stream is rejected by the server because // the server stops accepting new RPCs. - ErrStreamDrain = StreamErrorf(codes.Unavailable, "the server stops accepting new RPCs") + ErrStreamDrain = streamErrorf(codes.Unavailable, "the server stops accepting new RPCs") ) // StreamError is an error that only affects one stream within a connection. @@ -542,9 +542,9 @@ func (e StreamError) Error() string { func ContextErr(err error) StreamError { switch err { case context.DeadlineExceeded: - return StreamErrorf(codes.DeadlineExceeded, "%v", err) + return streamErrorf(codes.DeadlineExceeded, "%v", err) case context.Canceled: - return StreamErrorf(codes.Canceled, "%v", err) + return streamErrorf(codes.Canceled, "%v", err) } panic(fmt.Sprintf("Unexpected error from context packet: %v", err)) } diff --git a/vendor/gopkg.in/mgo.v2/Makefile b/vendor/gopkg.in/mgo.v2/Makefile index 51bee7322..d1027d450 100644 --- a/vendor/gopkg.in/mgo.v2/Makefile +++ b/vendor/gopkg.in/mgo.v2/Makefile @@ -1,5 +1,5 @@ startdb: - @testdb/setup.sh start + @harness/setup.sh start stopdb: - @testdb/setup.sh stop + @harness/setup.sh stop diff --git a/vendor/gopkg.in/mgo.v2/bson/bson.go b/vendor/gopkg.in/mgo.v2/bson/bson.go index 579aec13f..7fb7f8cae 100644 --- a/vendor/gopkg.in/mgo.v2/bson/bson.go +++ b/vendor/gopkg.in/mgo.v2/bson/bson.go @@ -38,6 +38,7 @@ import ( "crypto/rand" "encoding/binary" "encoding/hex" + "encoding/json" "errors" "fmt" "io" @@ -204,6 +205,7 @@ func readRandomUint32() uint32 { // machineId stores machine id generated once and used in subsequent calls // to NewObjectId function. var machineId = readMachineId() +var processId = os.Getpid() // readMachineId generates and returns a machine id. // If this function fails to get the hostname it will cause a runtime error. @@ -234,9 +236,8 @@ func NewObjectId() ObjectId { b[5] = machineId[1] b[6] = machineId[2] // Pid, 2 bytes, specs don't specify endianness, but we use big endian. - pid := os.Getpid() - b[7] = byte(pid >> 8) - b[8] = byte(pid) + b[7] = byte(processId >> 8) + b[8] = byte(processId) // Increment, 3 bytes, big endian i := atomic.AddUint32(&objectIdCounter, 1) b[9] = byte(i >> 16) @@ -276,6 +277,22 @@ var nullBytes = []byte("null") // UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller. func (id *ObjectId) UnmarshalJSON(data []byte) error { + if len(data) > 0 && (data[0] == '{' || data[0] == 'O') { + var v struct { + Id json.RawMessage `json:"$oid"` + Func struct { + Id json.RawMessage + } `json:"$oidFunc"` + } + err := jdec(data, &v) + if err == nil { + if len(v.Id) > 0 { + data = []byte(v.Id) + } else { + data = []byte(v.Func.Id) + } + } + } if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) { *id = "" return nil diff --git a/vendor/gopkg.in/mgo.v2/bson/decimal.go b/vendor/gopkg.in/mgo.v2/bson/decimal.go new file mode 100644 index 000000000..3d2f70020 --- /dev/null +++ b/vendor/gopkg.in/mgo.v2/bson/decimal.go @@ -0,0 +1,310 @@ +// BSON library for Go +// +// Copyright (c) 2010-2012 - Gustavo Niemeyer +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package bson + +import ( + "fmt" + "strconv" + "strings" +) + +// Decimal128 holds decimal128 BSON values. +type Decimal128 struct { + h, l uint64 +} + +func (d Decimal128) String() string { + var pos int // positive sign + var e int // exponent + var h, l uint64 // significand high/low + + if d.h>>63&1 == 0 { + pos = 1 + } + + switch d.h >> 58 & (1<<5 - 1) { + case 0x1F: + return "NaN" + case 0x1E: + return "-Inf"[pos:] + } + + l = d.l + if d.h>>61&3 == 3 { + // Bits: 1*sign 2*ignored 14*exponent 111*significand. + // Implicit 0b100 prefix in significand. + e = int(d.h>>47&(1<<14-1)) - 6176 + //h = 4<<47 | d.h&(1<<47-1) + // Spec says all of these values are out of range. + h, l = 0, 0 + } else { + // Bits: 1*sign 14*exponent 113*significand + e = int(d.h>>49&(1<<14-1)) - 6176 + h = d.h & (1<<49 - 1) + } + + // Would be handled by the logic below, but that's trivial and common. + if h == 0 && l == 0 && e == 0 { + return "-0"[pos:] + } + + var repr [48]byte // Loop 5 times over 9 digits plus dot, negative sign, and leading zero. + var last = len(repr) + var i = len(repr) + var dot = len(repr) + e + var rem uint32 +Loop: + for d9 := 0; d9 < 5; d9++ { + h, l, rem = divmod(h, l, 1e9) + for d1 := 0; d1 < 9; d1++ { + // Handle "-0.0", "0.00123400", "-1.00E-6", "1.050E+3", etc. + if i < len(repr) && (dot == i || l == 0 && h == 0 && rem > 0 && rem < 10 && (dot < i-6 || e > 0)) { + e += len(repr) - i + i-- + repr[i] = '.' + last = i - 1 + dot = len(repr) // Unmark. + } + c := '0' + byte(rem%10) + rem /= 10 + i-- + repr[i] = c + // Handle "0E+3", "1E+3", etc. + if l == 0 && h == 0 && rem == 0 && i == len(repr)-1 && (dot < i-5 || e > 0) { + last = i + break Loop + } + if c != '0' { + last = i + } + // Break early. Works without it, but why. + if dot > i && l == 0 && h == 0 && rem == 0 { + break Loop + } + } + } + repr[last-1] = '-' + last-- + + if e > 0 { + return string(repr[last+pos:]) + "E+" + strconv.Itoa(e) + } + if e < 0 { + return string(repr[last+pos:]) + "E" + strconv.Itoa(e) + } + return string(repr[last+pos:]) +} + +func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) { + div64 := uint64(div) + a := h >> 32 + aq := a / div64 + ar := a % div64 + b := ar<<32 + h&(1<<32-1) + bq := b / div64 + br := b % div64 + c := br<<32 + l>>32 + cq := c / div64 + cr := c % div64 + d := cr<<32 + l&(1<<32-1) + dq := d / div64 + dr := d % div64 + return (aq<<32 | bq), (cq<<32 | dq), uint32(dr) +} + +var dNaN = Decimal128{0x1F << 58, 0} +var dPosInf = Decimal128{0x1E << 58, 0} +var dNegInf = Decimal128{0x3E << 58, 0} + +func dErr(s string) (Decimal128, error) { + return dNaN, fmt.Errorf("cannot parse %q as a decimal128", s) +} + +func ParseDecimal128(s string) (Decimal128, error) { + orig := s + if s == "" { + return dErr(orig) + } + neg := s[0] == '-' + if neg || s[0] == '+' { + s = s[1:] + } + + if (len(s) == 3 || len(s) == 8) && (s[0] == 'N' || s[0] == 'n' || s[0] == 'I' || s[0] == 'i') { + if s == "NaN" || s == "nan" || strings.EqualFold(s, "nan") { + return dNaN, nil + } + if s == "Inf" || s == "inf" || strings.EqualFold(s, "inf") || strings.EqualFold(s, "infinity") { + if neg { + return dNegInf, nil + } + return dPosInf, nil + } + return dErr(orig) + } + + var h, l uint64 + var e int + + var add, ovr uint32 + var mul uint32 = 1 + var dot = -1 + var digits = 0 + var i = 0 + for i < len(s) { + c := s[i] + if mul == 1e9 { + h, l, ovr = muladd(h, l, mul, add) + mul, add = 1, 0 + if ovr > 0 || h&((1<<15-1)<<49) > 0 { + return dErr(orig) + } + } + if c >= '0' && c <= '9' { + i++ + if c > '0' || digits > 0 { + digits++ + } + if digits > 34 { + if c == '0' { + // Exact rounding. + e++ + continue + } + return dErr(orig) + } + mul *= 10 + add *= 10 + add += uint32(c - '0') + continue + } + if c == '.' { + i++ + if dot >= 0 || i == 1 && len(s) == 1 { + return dErr(orig) + } + if i == len(s) { + break + } + if s[i] < '0' || s[i] > '9' || e > 0 { + return dErr(orig) + } + dot = i + continue + } + break + } + if i == 0 { + return dErr(orig) + } + if mul > 1 { + h, l, ovr = muladd(h, l, mul, add) + if ovr > 0 || h&((1<<15-1)<<49) > 0 { + return dErr(orig) + } + } + if dot >= 0 { + e += dot - i + } + if i+1 < len(s) && (s[i] == 'E' || s[i] == 'e') { + i++ + eneg := s[i] == '-' + if eneg || s[i] == '+' { + i++ + if i == len(s) { + return dErr(orig) + } + } + n := 0 + for i < len(s) && n < 1e4 { + c := s[i] + i++ + if c < '0' || c > '9' { + return dErr(orig) + } + n *= 10 + n += int(c - '0') + } + if eneg { + n = -n + } + e += n + for e < -6176 { + // Subnormal. + var div uint32 = 1 + for div < 1e9 && e < -6176 { + div *= 10 + e++ + } + var rem uint32 + h, l, rem = divmod(h, l, div) + if rem > 0 { + return dErr(orig) + } + } + for e > 6111 { + // Clamped. + var mul uint32 = 1 + for mul < 1e9 && e > 6111 { + mul *= 10 + e-- + } + h, l, ovr = muladd(h, l, mul, 0) + if ovr > 0 || h&((1<<15-1)<<49) > 0 { + return dErr(orig) + } + } + if e < -6176 || e > 6111 { + return dErr(orig) + } + } + + if i < len(s) { + return dErr(orig) + } + + h |= uint64(e+6176) & uint64(1<<14-1) << 49 + if neg { + h |= 1 << 63 + } + return Decimal128{h, l}, nil +} + +func muladd(h, l uint64, mul uint32, add uint32) (resh, resl uint64, overflow uint32) { + mul64 := uint64(mul) + a := mul64 * (l & (1<<32 - 1)) + b := a>>32 + mul64*(l>>32) + c := b>>32 + mul64*(h&(1<<32-1)) + d := c>>32 + mul64*(h>>32) + + a = a&(1<<32-1) + uint64(add) + b = b&(1<<32-1) + a>>32 + c = c&(1<<32-1) + b>>32 + d = d&(1<<32-1) + c>>32 + + return (d<<32 | c&(1<<32-1)), (b<<32 | a&(1<<32-1)), uint32(d >> 32) +} diff --git a/vendor/gopkg.in/mgo.v2/bson/decode.go b/vendor/gopkg.in/mgo.v2/bson/decode.go index 9bd73f966..7c2d8416a 100644 --- a/vendor/gopkg.in/mgo.v2/bson/decode.go +++ b/vendor/gopkg.in/mgo.v2/bson/decode.go @@ -539,6 +539,11 @@ func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) { in = MongoTimestamp(d.readInt64()) case 0x12: // Int64 in = d.readInt64() + case 0x13: // Decimal128 + in = Decimal128{ + l: uint64(d.readInt64()), + h: uint64(d.readInt64()), + } case 0x7F: // Max key in = MaxKey case 0xFF: // Min key diff --git a/vendor/gopkg.in/mgo.v2/bson/encode.go b/vendor/gopkg.in/mgo.v2/bson/encode.go index c228e28d3..add39e865 100644 --- a/vendor/gopkg.in/mgo.v2/bson/encode.go +++ b/vendor/gopkg.in/mgo.v2/bson/encode.go @@ -247,7 +247,7 @@ func (e *encoder) addElemName(kind byte, name string) { func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { if !v.IsValid() { - e.addElemName('\x0A', name) + e.addElemName(0x0A, name) return } @@ -276,29 +276,29 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { panic("ObjectIDs must be exactly 12 bytes long (got " + strconv.Itoa(len(s)) + ")") } - e.addElemName('\x07', name) + e.addElemName(0x07, name) e.addBytes([]byte(s)...) case typeSymbol: - e.addElemName('\x0E', name) + e.addElemName(0x0E, name) e.addStr(s) case typeJSONNumber: n := v.Interface().(json.Number) if i, err := n.Int64(); err == nil { - e.addElemName('\x12', name) + e.addElemName(0x12, name) e.addInt64(i) } else if f, err := n.Float64(); err == nil { - e.addElemName('\x01', name) + e.addElemName(0x01, name) e.addFloat64(f) } else { panic("failed to convert json.Number to a number: " + s) } default: - e.addElemName('\x02', name) + e.addElemName(0x02, name) e.addStr(s) } case reflect.Float32, reflect.Float64: - e.addElemName('\x01', name) + e.addElemName(0x01, name) e.addFloat64(v.Float()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: @@ -306,40 +306,40 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { if int64(u) < 0 { panic("BSON has no uint64 type, and value is too large to fit correctly in an int64") } else if u <= math.MaxInt32 && (minSize || v.Kind() <= reflect.Uint32) { - e.addElemName('\x10', name) + e.addElemName(0x10, name) e.addInt32(int32(u)) } else { - e.addElemName('\x12', name) + e.addElemName(0x12, name) e.addInt64(int64(u)) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch v.Type() { case typeMongoTimestamp: - e.addElemName('\x11', name) + e.addElemName(0x11, name) e.addInt64(v.Int()) case typeOrderKey: if v.Int() == int64(MaxKey) { - e.addElemName('\x7F', name) + e.addElemName(0x7F, name) } else { - e.addElemName('\xFF', name) + e.addElemName(0xFF, name) } default: i := v.Int() if (minSize || v.Type().Kind() != reflect.Int64) && i >= math.MinInt32 && i <= math.MaxInt32 { // It fits into an int32, encode as such. - e.addElemName('\x10', name) + e.addElemName(0x10, name) e.addInt32(int32(i)) } else { - e.addElemName('\x12', name) + e.addElemName(0x12, name) e.addInt64(i) } } case reflect.Bool: - e.addElemName('\x08', name) + e.addElemName(0x08, name) if v.Bool() { e.addBytes(1) } else { @@ -347,40 +347,40 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { } case reflect.Map: - e.addElemName('\x03', name) + e.addElemName(0x03, name) e.addDoc(v) case reflect.Slice: vt := v.Type() et := vt.Elem() if et.Kind() == reflect.Uint8 { - e.addElemName('\x05', name) - e.addBinary('\x00', v.Bytes()) + e.addElemName(0x05, name) + e.addBinary(0x00, v.Bytes()) } else if et == typeDocElem || et == typeRawDocElem { - e.addElemName('\x03', name) + e.addElemName(0x03, name) e.addDoc(v) } else { - e.addElemName('\x04', name) + e.addElemName(0x04, name) e.addDoc(v) } case reflect.Array: et := v.Type().Elem() if et.Kind() == reflect.Uint8 { - e.addElemName('\x05', name) + e.addElemName(0x05, name) if v.CanAddr() { - e.addBinary('\x00', v.Slice(0, v.Len()).Interface().([]byte)) + e.addBinary(0x00, v.Slice(0, v.Len()).Interface().([]byte)) } else { n := v.Len() e.addInt32(int32(n)) - e.addBytes('\x00') + e.addBytes(0x00) for i := 0; i < n; i++ { el := v.Index(i) e.addBytes(byte(el.Uint())) } } } else { - e.addElemName('\x04', name) + e.addElemName(0x04, name) e.addDoc(v) } @@ -399,11 +399,16 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { e.addBytes(s.Data...) case Binary: - e.addElemName('\x05', name) + e.addElemName(0x05, name) e.addBinary(s.Kind, s.Data) + case Decimal128: + e.addElemName(0x13, name) + e.addInt64(int64(s.l)) + e.addInt64(int64(s.h)) + case DBPointer: - e.addElemName('\x0C', name) + e.addElemName(0x0C, name) e.addStr(s.Namespace) if len(s.Id) != 12 { panic("ObjectIDs must be exactly 12 bytes long (got " + @@ -412,16 +417,16 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { e.addBytes([]byte(s.Id)...) case RegEx: - e.addElemName('\x0B', name) + e.addElemName(0x0B, name) e.addCStr(s.Pattern) e.addCStr(s.Options) case JavaScript: if s.Scope == nil { - e.addElemName('\x0D', name) + e.addElemName(0x0D, name) e.addStr(s.Code) } else { - e.addElemName('\x0F', name) + e.addElemName(0x0F, name) start := e.reserveInt32() e.addStr(s.Code) e.addDoc(reflect.ValueOf(s.Scope)) @@ -430,18 +435,18 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { case time.Time: // MongoDB handles timestamps as milliseconds. - e.addElemName('\x09', name) + e.addElemName(0x09, name) e.addInt64(s.Unix()*1000 + int64(s.Nanosecond()/1e6)) case url.URL: - e.addElemName('\x02', name) + e.addElemName(0x02, name) e.addStr(s.String()) case undefined: - e.addElemName('\x06', name) + e.addElemName(0x06, name) default: - e.addElemName('\x03', name) + e.addElemName(0x03, name) e.addDoc(v) } diff --git a/vendor/gopkg.in/mgo.v2/bson/json.go b/vendor/gopkg.in/mgo.v2/bson/json.go new file mode 100644 index 000000000..09df8260a --- /dev/null +++ b/vendor/gopkg.in/mgo.v2/bson/json.go @@ -0,0 +1,380 @@ +package bson + +import ( + "bytes" + "encoding/base64" + "fmt" + "gopkg.in/mgo.v2/internal/json" + "strconv" + "time" +) + +// UnmarshalJSON unmarshals a JSON value that may hold non-standard +// syntax as defined in BSON's extended JSON specification. +func UnmarshalJSON(data []byte, value interface{}) error { + d := json.NewDecoder(bytes.NewBuffer(data)) + d.Extend(&jsonExt) + return d.Decode(value) +} + +// MarshalJSON marshals a JSON value that may hold non-standard +// syntax as defined in BSON's extended JSON specification. +func MarshalJSON(value interface{}) ([]byte, error) { + var buf bytes.Buffer + e := json.NewEncoder(&buf) + e.Extend(&jsonExt) + err := e.Encode(value) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// jdec is used internally by the JSON decoding functions +// so they may unmarshal functions without getting into endless +// recursion due to keyed objects. +func jdec(data []byte, value interface{}) error { + d := json.NewDecoder(bytes.NewBuffer(data)) + d.Extend(&funcExt) + return d.Decode(value) +} + +var jsonExt json.Extension +var funcExt json.Extension + +// TODO +// - Shell regular expressions ("/regexp/opts") + +func init() { + jsonExt.DecodeUnquotedKeys(true) + jsonExt.DecodeTrailingCommas(true) + + funcExt.DecodeFunc("BinData", "$binaryFunc", "$type", "$binary") + jsonExt.DecodeKeyed("$binary", jdecBinary) + jsonExt.DecodeKeyed("$binaryFunc", jdecBinary) + jsonExt.EncodeType([]byte(nil), jencBinarySlice) + jsonExt.EncodeType(Binary{}, jencBinaryType) + + funcExt.DecodeFunc("ISODate", "$dateFunc", "S") + funcExt.DecodeFunc("new Date", "$dateFunc", "S") + jsonExt.DecodeKeyed("$date", jdecDate) + jsonExt.DecodeKeyed("$dateFunc", jdecDate) + jsonExt.EncodeType(time.Time{}, jencDate) + + funcExt.DecodeFunc("Timestamp", "$timestamp", "t", "i") + jsonExt.DecodeKeyed("$timestamp", jdecTimestamp) + jsonExt.EncodeType(MongoTimestamp(0), jencTimestamp) + + funcExt.DecodeConst("undefined", Undefined) + + jsonExt.DecodeKeyed("$regex", jdecRegEx) + jsonExt.EncodeType(RegEx{}, jencRegEx) + + funcExt.DecodeFunc("ObjectId", "$oidFunc", "Id") + jsonExt.DecodeKeyed("$oid", jdecObjectId) + jsonExt.DecodeKeyed("$oidFunc", jdecObjectId) + jsonExt.EncodeType(ObjectId(""), jencObjectId) + + funcExt.DecodeFunc("DBRef", "$dbrefFunc", "$ref", "$id") + jsonExt.DecodeKeyed("$dbrefFunc", jdecDBRef) + + funcExt.DecodeFunc("NumberLong", "$numberLongFunc", "N") + jsonExt.DecodeKeyed("$numberLong", jdecNumberLong) + jsonExt.DecodeKeyed("$numberLongFunc", jdecNumberLong) + jsonExt.EncodeType(int64(0), jencNumberLong) + jsonExt.EncodeType(int(0), jencInt) + + funcExt.DecodeConst("MinKey", MinKey) + funcExt.DecodeConst("MaxKey", MaxKey) + jsonExt.DecodeKeyed("$minKey", jdecMinKey) + jsonExt.DecodeKeyed("$maxKey", jdecMaxKey) + jsonExt.EncodeType(orderKey(0), jencMinMaxKey) + + jsonExt.DecodeKeyed("$undefined", jdecUndefined) + jsonExt.EncodeType(Undefined, jencUndefined) + + jsonExt.Extend(&funcExt) +} + +func fbytes(format string, args ...interface{}) []byte { + var buf bytes.Buffer + fmt.Fprintf(&buf, format, args...) + return buf.Bytes() +} + +func jdecBinary(data []byte) (interface{}, error) { + var v struct { + Binary []byte `json:"$binary"` + Type string `json:"$type"` + Func struct { + Binary []byte `json:"$binary"` + Type int64 `json:"$type"` + } `json:"$binaryFunc"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + + var binData []byte + var binKind int64 + if v.Type == "" && v.Binary == nil { + binData = v.Func.Binary + binKind = v.Func.Type + } else if v.Type == "" { + return v.Binary, nil + } else { + binData = v.Binary + binKind, err = strconv.ParseInt(v.Type, 0, 64) + if err != nil { + binKind = -1 + } + } + + if binKind == 0 { + return binData, nil + } + if binKind < 0 || binKind > 255 { + return nil, fmt.Errorf("invalid type in binary object: %s", data) + } + + return Binary{Kind: byte(binKind), Data: binData}, nil +} + +func jencBinarySlice(v interface{}) ([]byte, error) { + in := v.([]byte) + out := make([]byte, base64.StdEncoding.EncodedLen(len(in))) + base64.StdEncoding.Encode(out, in) + return fbytes(`{"$binary":"%s","$type":"0x0"}`, out), nil +} + +func jencBinaryType(v interface{}) ([]byte, error) { + in := v.(Binary) + out := make([]byte, base64.StdEncoding.EncodedLen(len(in.Data))) + base64.StdEncoding.Encode(out, in.Data) + return fbytes(`{"$binary":"%s","$type":"0x%x"}`, out, in.Kind), nil +} + +const jdateFormat = "2006-01-02T15:04:05.999Z" + +func jdecDate(data []byte) (interface{}, error) { + var v struct { + S string `json:"$date"` + Func struct { + S string + } `json:"$dateFunc"` + } + _ = jdec(data, &v) + if v.S == "" { + v.S = v.Func.S + } + if v.S != "" { + for _, format := range []string{jdateFormat, "2006-01-02"} { + t, err := time.Parse(format, v.S) + if err == nil { + return t, nil + } + } + return nil, fmt.Errorf("cannot parse date: %q", v.S) + } + + var vn struct { + Date struct { + N int64 `json:"$numberLong,string"` + } `json:"$date"` + Func struct { + S int64 + } `json:"$dateFunc"` + } + err := jdec(data, &vn) + if err != nil { + return nil, fmt.Errorf("cannot parse date: %q", data) + } + n := vn.Date.N + if n == 0 { + n = vn.Func.S + } + return time.Unix(n/1000, n%1000*1e6).UTC(), nil +} + +func jencDate(v interface{}) ([]byte, error) { + t := v.(time.Time) + return fbytes(`{"$date":%q}`, t.Format(jdateFormat)), nil +} + +func jdecTimestamp(data []byte) (interface{}, error) { + var v struct { + Func struct { + T int32 `json:"t"` + I int32 `json:"i"` + } `json:"$timestamp"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + return MongoTimestamp(uint64(v.Func.T)<<32 | uint64(uint32(v.Func.I))), nil +} + +func jencTimestamp(v interface{}) ([]byte, error) { + ts := uint64(v.(MongoTimestamp)) + return fbytes(`{"$timestamp":{"t":%d,"i":%d}}`, ts>>32, uint32(ts)), nil +} + +func jdecRegEx(data []byte) (interface{}, error) { + var v struct { + Regex string `json:"$regex"` + Options string `json:"$options"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + return RegEx{v.Regex, v.Options}, nil +} + +func jencRegEx(v interface{}) ([]byte, error) { + re := v.(RegEx) + type regex struct { + Regex string `json:"$regex"` + Options string `json:"$options"` + } + return json.Marshal(regex{re.Pattern, re.Options}) +} + +func jdecObjectId(data []byte) (interface{}, error) { + var v struct { + Id string `json:"$oid"` + Func struct { + Id string + } `json:"$oidFunc"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if v.Id == "" { + v.Id = v.Func.Id + } + return ObjectIdHex(v.Id), nil +} + +func jencObjectId(v interface{}) ([]byte, error) { + return fbytes(`{"$oid":"%s"}`, v.(ObjectId).Hex()), nil +} + +func jdecDBRef(data []byte) (interface{}, error) { + // TODO Support unmarshaling $ref and $id into the input value. + var v struct { + Obj map[string]interface{} `json:"$dbrefFunc"` + } + // TODO Fix this. Must not be required. + v.Obj = make(map[string]interface{}) + err := jdec(data, &v) + if err != nil { + return nil, err + } + return v.Obj, nil +} + +func jdecNumberLong(data []byte) (interface{}, error) { + var v struct { + N int64 `json:"$numberLong,string"` + Func struct { + N int64 `json:",string"` + } `json:"$numberLongFunc"` + } + var vn struct { + N int64 `json:"$numberLong"` + Func struct { + N int64 + } `json:"$numberLongFunc"` + } + err := jdec(data, &v) + if err != nil { + err = jdec(data, &vn) + v.N = vn.N + v.Func.N = vn.Func.N + } + if err != nil { + return nil, err + } + if v.N != 0 { + return v.N, nil + } + return v.Func.N, nil +} + +func jencNumberLong(v interface{}) ([]byte, error) { + n := v.(int64) + f := `{"$numberLong":"%d"}` + if n <= 1<<53 { + f = `{"$numberLong":%d}` + } + return fbytes(f, n), nil +} + +func jencInt(v interface{}) ([]byte, error) { + n := v.(int) + f := `{"$numberLong":"%d"}` + if int64(n) <= 1<<53 { + f = `%d` + } + return fbytes(f, n), nil +} + +func jdecMinKey(data []byte) (interface{}, error) { + var v struct { + N int64 `json:"$minKey"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if v.N != 1 { + return nil, fmt.Errorf("invalid $minKey object: %s", data) + } + return MinKey, nil +} + +func jdecMaxKey(data []byte) (interface{}, error) { + var v struct { + N int64 `json:"$maxKey"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if v.N != 1 { + return nil, fmt.Errorf("invalid $maxKey object: %s", data) + } + return MaxKey, nil +} + +func jencMinMaxKey(v interface{}) ([]byte, error) { + switch v.(orderKey) { + case MinKey: + return []byte(`{"$minKey":1}`), nil + case MaxKey: + return []byte(`{"$maxKey":1}`), nil + } + panic(fmt.Sprintf("invalid $minKey/$maxKey value: %d", v)) +} + +func jdecUndefined(data []byte) (interface{}, error) { + var v struct { + B bool `json:"$undefined"` + } + err := jdec(data, &v) + if err != nil { + return nil, err + } + if !v.B { + return nil, fmt.Errorf("invalid $undefined object: %s", data) + } + return Undefined, nil +} + +func jencUndefined(v interface{}) ([]byte, error) { + return []byte(`{"$undefined":true}`), nil +} diff --git a/vendor/gopkg.in/mgo.v2/cluster.go b/vendor/gopkg.in/mgo.v2/cluster.go index e28af5b45..c3bf8b013 100644 --- a/vendor/gopkg.in/mgo.v2/cluster.go +++ b/vendor/gopkg.in/mgo.v2/cluster.go @@ -588,7 +588,10 @@ func (cluster *mongoCluster) AcquireSocket(mode Mode, slaveOk bool, syncTimeout mastersLen := cluster.masters.Len() slavesLen := cluster.servers.Len() - mastersLen debugf("Cluster has %d known masters and %d known slaves.", mastersLen, slavesLen) - if !(slaveOk && mode == Secondary) && mastersLen > 0 || slaveOk && slavesLen > 0 { + if mastersLen > 0 && !(slaveOk && mode == Secondary) || slavesLen > 0 && slaveOk { + break + } + if mastersLen > 0 && mode == Secondary && cluster.masters.HasMongos() { break } if started.IsZero() { diff --git a/vendor/gopkg.in/mgo.v2/gridfs.go b/vendor/gopkg.in/mgo.v2/gridfs.go index 2ac4ff576..421472095 100644 --- a/vendor/gopkg.in/mgo.v2/gridfs.go +++ b/vendor/gopkg.in/mgo.v2/gridfs.go @@ -359,7 +359,7 @@ func (file *GridFile) assertMode(mode gfsFileMode) { // SetChunkSize sets size of saved chunks. Once the file is written to, it // will be split in blocks of that size and each block saved into an -// independent chunk document. The default chunk size is 256kb. +// independent chunk document. The default chunk size is 255kb. // // It is a runtime error to call this function once the file has started // being written to. diff --git a/vendor/gopkg.in/mgo.v2/internal/json/LICENSE b/vendor/gopkg.in/mgo.v2/internal/json/LICENSE new file mode 100644 index 000000000..744875676 --- /dev/null +++ b/vendor/gopkg.in/mgo.v2/internal/json/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gopkg.in/mgo.v2/internal/json/decode.go b/vendor/gopkg.in/mgo.v2/internal/json/decode.go new file mode 100644 index 000000000..ce7c7d249 --- /dev/null +++ b/vendor/gopkg.in/mgo.v2/internal/json/decode.go @@ -0,0 +1,1685 @@ +// Copyright 2010 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. + +// Represents JSON data structure using native Go types: booleans, floats, +// strings, arrays, and maps. + +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "errors" + "fmt" + "reflect" + "runtime" + "strconv" + "unicode" + "unicode/utf16" + "unicode/utf8" +) + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. +// +// Unmarshal uses the inverse of the encodings that +// Marshal uses, allocating maps, slices, and pointers as necessary, +// with the following additional rules: +// +// To unmarshal JSON into a pointer, Unmarshal first handles the case of +// the JSON being the JSON literal null. In that case, Unmarshal sets +// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into +// the value pointed at by the pointer. If the pointer is nil, Unmarshal +// allocates a new value for it to point to. +// +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by Marshal (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. +// Unmarshal will only set exported fields of the struct. +// +// To unmarshal JSON into an interface value, +// Unmarshal stores one of these in the interface value: +// +// bool, for JSON booleans +// float64, for JSON numbers +// string, for JSON strings +// []interface{}, for JSON arrays +// map[string]interface{}, for JSON objects +// nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a map, Unmarshal first establishes a map to +// use, If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal +// reuses the existing map, keeping existing entries. Unmarshal then stores key- +// value pairs from the JSON object into the map. The map's key type must +// either be a string or implement encoding.TextUnmarshaler. +// +// If a JSON value is not appropriate for a given target type, +// or if a JSON number overflows the target type, Unmarshal +// skips that field and completes the unmarshaling as best it can. +// If no more serious errors are encountered, Unmarshal returns +// an UnmarshalTypeError describing the earliest such error. +// +// The JSON null value unmarshals into an interface, map, pointer, or slice +// by setting that Go value to nil. Because null is often used in JSON to mean +// ``not present,'' unmarshaling a JSON null into any other Go type has no effect +// on the value and produces no error. +// +// When unmarshaling quoted strings, invalid UTF-8 or +// invalid UTF-16 surrogate pairs are not treated as an error. +// Instead, they are replaced by the Unicode replacement +// character U+FFFD. +// +func Unmarshal(data []byte, v interface{}) error { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + var d decodeState + err := checkValid(data, &d.scan) + if err != nil { + return err + } + + d.init(data) + return d.unmarshal(v) +} + +// Unmarshaler is the interface implemented by types +// that can unmarshal a JSON description of themselves. +// The input can be assumed to be a valid encoding of +// a JSON value. UnmarshalJSON must copy the JSON data +// if it wishes to retain the data after returning. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes +} + +func (e *UnmarshalTypeError) Error() string { + return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() +} + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// (No longer used; kept for compatibility.) +type UnmarshalFieldError struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() +} + +// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + if e.Type.Kind() != reflect.Ptr { + return "json: Unmarshal(non-pointer " + e.Type.String() + ")" + } + return "json: Unmarshal(nil " + e.Type.String() + ")" +} + +func (d *decodeState) unmarshal(v interface{}) (err error) { + defer func() { + if r := recover(); r != nil { + if _, ok := r.(runtime.Error); ok { + panic(r) + } + err = r.(error) + } + }() + + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return &InvalidUnmarshalError{reflect.TypeOf(v)} + } + + d.scan.reset() + // We decode rv not rv.Elem because the Unmarshaler interface + // test must be applied at the top level of the value. + d.value(rv) + return d.savedError +} + +// A Number represents a JSON number literal. +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +// isValidNumber reports whether s is a valid JSON number literal. +func isValidNumber(s string) bool { + // This function implements the JSON numbers grammar. + // See https://tools.ietf.org/html/rfc7159#section-6 + // and http://json.org/number.gif + + if s == "" { + return false + } + + // Optional - + if s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + + // Digits + switch { + default: + return false + + case s[0] == '0': + s = s[1:] + + case '1' <= s[0] && s[0] <= '9': + s = s[1:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // . followed by 1 or more digits. + if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { + s = s[2:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // e or E followed by an optional - or + and + // 1 or more digits. + if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { + s = s[1:] + if s[0] == '+' || s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // Make sure we are at the end. + return s == "" +} + +// decodeState represents the state while decoding a JSON value. +type decodeState struct { + data []byte + off int // read offset in data + scan scanner + nextscan scanner // for calls to nextValue + savedError error + useNumber bool + ext Extension +} + +// errPhase is used for errors that should not happen unless +// there is a bug in the JSON decoder or something is editing +// the data slice while the decoder executes. +var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?") + +func (d *decodeState) init(data []byte) *decodeState { + d.data = data + d.off = 0 + d.savedError = nil + return d +} + +// error aborts the decoding by panicking with err. +func (d *decodeState) error(err error) { + panic(err) +} + +// saveError saves the first err it is called with, +// for reporting at the end of the unmarshal. +func (d *decodeState) saveError(err error) { + if d.savedError == nil { + d.savedError = err + } +} + +// next cuts off and returns the next full JSON value in d.data[d.off:]. +// The next value is known to be an object or array, not a literal. +func (d *decodeState) next() []byte { + c := d.data[d.off] + item, rest, err := nextValue(d.data[d.off:], &d.nextscan) + if err != nil { + d.error(err) + } + d.off = len(d.data) - len(rest) + + // Our scanner has seen the opening brace/bracket + // and thinks we're still in the middle of the object. + // invent a closing brace/bracket to get it out. + if c == '{' { + d.scan.step(&d.scan, '}') + } else if c == '[' { + d.scan.step(&d.scan, ']') + } else { + // Was inside a function name. Get out of it. + d.scan.step(&d.scan, '(') + d.scan.step(&d.scan, ')') + } + + return item +} + +// scanWhile processes bytes in d.data[d.off:] until it +// receives a scan code not equal to op. +// It updates d.off and returns the new scan code. +func (d *decodeState) scanWhile(op int) int { + var newOp int + for { + if d.off >= len(d.data) { + newOp = d.scan.eof() + d.off = len(d.data) + 1 // mark processed EOF with len+1 + } else { + c := d.data[d.off] + d.off++ + newOp = d.scan.step(&d.scan, c) + } + if newOp != op { + break + } + } + return newOp +} + +// value decodes a JSON value from d.data[d.off:] into the value. +// it updates d.off to point past the decoded value. +func (d *decodeState) value(v reflect.Value) { + if !v.IsValid() { + _, rest, err := nextValue(d.data[d.off:], &d.nextscan) + if err != nil { + d.error(err) + } + d.off = len(d.data) - len(rest) + + // d.scan thinks we're still at the beginning of the item. + // Feed in an empty string - the shortest, simplest value - + // so that it knows we got to the end of the value. + if d.scan.redo { + // rewind. + d.scan.redo = false + d.scan.step = stateBeginValue + } + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + + n := len(d.scan.parseState) + if n > 0 && d.scan.parseState[n-1] == parseObjectKey { + // d.scan thinks we just read an object key; finish the object + d.scan.step(&d.scan, ':') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '}') + } + + return + } + + switch op := d.scanWhile(scanSkipSpace); op { + default: + d.error(errPhase) + + case scanBeginArray: + d.array(v) + + case scanBeginObject: + d.object(v) + + case scanBeginLiteral: + d.literal(v) + + case scanBeginName: + d.name(v) + } +} + +type unquotedValue struct{} + +// valueQuoted is like value but decodes a +// quoted string literal or literal null into an interface value. +// If it finds anything other than a quoted string literal or null, +// valueQuoted returns unquotedValue{}. +func (d *decodeState) valueQuoted() interface{} { + switch op := d.scanWhile(scanSkipSpace); op { + default: + d.error(errPhase) + + case scanBeginArray: + d.array(reflect.Value{}) + + case scanBeginObject: + d.object(reflect.Value{}) + + case scanBeginName: + switch v := d.nameInterface().(type) { + case nil, string: + return v + } + + case scanBeginLiteral: + switch v := d.literalInterface().(type) { + case nil, string: + return v + } + } + return unquotedValue{} +} + +// indirect walks down v allocating pointers as needed, +// until it gets to a non-pointer. +// if it encounters an Unmarshaler, indirect stops and returns that. +// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. +func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // If v is a named type and is addressable, + // start with its address, so that if the type has pointer methods, + // we find them. + if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + v = v.Addr() + } + for { + // Load value from interface, but only if the result will be + // usefully addressable. + if v.Kind() == reflect.Interface && !v.IsNil() { + e := v.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + v = e + continue + } + } + + if v.Kind() != reflect.Ptr { + break + } + + if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { + break + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + if v.Type().NumMethod() > 0 { + if u, ok := v.Interface().(Unmarshaler); ok { + return u, nil, v + } + if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { + return nil, u, v + } + } + v = v.Elem() + } + return nil, nil, v +} + +// array consumes an array from d.data[d.off-1:], decoding into the value v. +// the first byte of the array ('[') has been read already. +func (d *decodeState) array(v reflect.Value) { + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) + d.off-- + d.next() + return + } + + v = pv + + // Check type of target. + switch v.Kind() { + case reflect.Interface: + if v.NumMethod() == 0 { + // Decoding into nil interface? Switch to non-reflect code. + v.Set(reflect.ValueOf(d.arrayInterface())) + return + } + // Otherwise it's invalid. + fallthrough + default: + d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) + d.off-- + d.next() + return + case reflect.Array: + case reflect.Slice: + break + } + + i := 0 + for { + // Look ahead for ] - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + // Get element of array, growing if necessary. + if v.Kind() == reflect.Slice { + // Grow slice if necessary + if i >= v.Cap() { + newcap := v.Cap() + v.Cap()/2 + if newcap < 4 { + newcap = 4 + } + newv := reflect.MakeSlice(v.Type(), v.Len(), newcap) + reflect.Copy(newv, v) + v.Set(newv) + } + if i >= v.Len() { + v.SetLen(i + 1) + } + } + + if i < v.Len() { + // Decode into element. + d.value(v.Index(i)) + } else { + // Ran out of fixed array: skip. + d.value(reflect.Value{}) + } + i++ + + // Next token must be , or ]. + op = d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + if op != scanArrayValue { + d.error(errPhase) + } + } + + if i < v.Len() { + if v.Kind() == reflect.Array { + // Array. Zero the rest. + z := reflect.Zero(v.Type().Elem()) + for ; i < v.Len(); i++ { + v.Index(i).Set(z) + } + } else { + v.SetLen(i) + } + } + if i == 0 && v.Kind() == reflect.Slice { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } +} + +var nullLiteral = []byte("null") +var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem() + +// object consumes an object from d.data[d.off-1:], decoding into the value v. +// the first byte ('{') of the object has been read already. +func (d *decodeState) object(v reflect.Value) { + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if d.storeKeyed(pv) { + return + } + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + v = pv + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + v.Set(reflect.ValueOf(d.objectInterface())) + return + } + + // Check type of target: + // struct or + // map[string]T or map[encoding.TextUnmarshaler]T + switch v.Kind() { + case reflect.Map: + // Map key must either have string kind or be an encoding.TextUnmarshaler. + t := v.Type() + if t.Key().Kind() != reflect.String && + !reflect.PtrTo(t.Key()).Implements(textUnmarshalerType) { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + + default: + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + + var mapElem reflect.Value + + empty := true + for { + // Read opening " of string key or closing }. + op := d.scanWhile(scanSkipSpace) + if op == scanEndObject { + if !empty && !d.ext.trailingCommas { + d.syntaxError("beginning of object key string") + } + break + } + empty = false + if op == scanBeginName { + if !d.ext.unquotedKeys { + d.syntaxError("beginning of object key string") + } + } else if op != scanBeginLiteral { + d.error(errPhase) + } + unquotedKey := op == scanBeginName + + // Read key. + start := d.off - 1 + op = d.scanWhile(scanContinue) + item := d.data[start : d.off-1] + var key []byte + if unquotedKey { + key = item + // TODO Fix code below to quote item when necessary. + } else { + var ok bool + key, ok = unquoteBytes(item) + if !ok { + d.error(errPhase) + } + } + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.Set(reflect.Zero(elemType)) + } + subv = mapElem + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, key) { + f = ff + break + } + if f == nil && ff.equalFold(ff.nameBytes, key) { + f = ff + } + } + if f != nil { + subv = v + destring = f.quoted + for _, i := range f.index { + if subv.Kind() == reflect.Ptr { + if subv.IsNil() { + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + subv = subv.Field(i) + } + } + } + + // Read : before value. + if op == scanSkipSpace { + op = d.scanWhile(scanSkipSpace) + } + if op != scanObjectKey { + d.error(errPhase) + } + + // Read value. + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + d.literalStore(nullLiteral, subv, false) + case string: + d.literalStore([]byte(qv), subv, true) + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + d.value(subv) + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kt := v.Type().Key() + var kv reflect.Value + switch { + case kt.Kind() == reflect.String: + kv = reflect.ValueOf(key).Convert(v.Type().Key()) + case reflect.PtrTo(kt).Implements(textUnmarshalerType): + kv = reflect.New(v.Type().Key()) + d.literalStore(item, kv, true) + kv = kv.Elem() + default: + panic("json: Unexpected key type") // should never occur + } + v.SetMapIndex(kv, subv) + } + + // Next token must be , or }. + op = d.scanWhile(scanSkipSpace) + if op == scanEndObject { + break + } + if op != scanObjectValue { + d.error(errPhase) + } + } +} + +// isNull returns whether there's a null literal at the provided offset. +func (d *decodeState) isNull(off int) bool { + if off+4 >= len(d.data) || d.data[off] != 'n' || d.data[off+1] != 'u' || d.data[off+2] != 'l' || d.data[off+3] != 'l' { + return false + } + d.nextscan.reset() + for i, c := range d.data[off:] { + if i > 4 { + return false + } + switch d.nextscan.step(&d.nextscan, c) { + case scanContinue, scanBeginName: + continue + } + break + } + return true +} + +// name consumes a const or function from d.data[d.off-1:], decoding into the value v. +// the first byte of the function name has been read already. +func (d *decodeState) name(v reflect.Value) { + if d.isNull(d.off-1) { + d.literal(v) + return + } + + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if d.storeKeyed(pv) { + return + } + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over function in input + return + } + v = pv + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + out := d.nameInterface() + if out == nil { + v.Set(reflect.Zero(v.Type())) + } else { + v.Set(reflect.ValueOf(out)) + } + return + } + + nameStart := d.off - 1 + + op := d.scanWhile(scanContinue) + + name := d.data[nameStart : d.off-1] + if op != scanParam { + // Back up so the byte just read is consumed next. + d.off-- + d.scan.undo(op) + if l, ok := d.convertLiteral(name); ok { + d.storeValue(v, l) + return + } + d.error(&SyntaxError{fmt.Sprintf("json: unknown constant %q", name), int64(d.off)}) + } + + funcName := string(name) + funcData := d.ext.funcs[funcName] + if funcData.key == "" { + d.error(fmt.Errorf("json: unknown function %q", funcName)) + } + + // Check type of target: + // struct or + // map[string]T or map[encoding.TextUnmarshaler]T + switch v.Kind() { + case reflect.Map: + // Map key must either have string kind or be an encoding.TextUnmarshaler. + t := v.Type() + if t.Key().Kind() != reflect.String && + !reflect.PtrTo(t.Key()).Implements(textUnmarshalerType) { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + + default: + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + + // TODO Fix case of func field as map. + //topv := v + + // Figure out field corresponding to function. + key := []byte(funcData.key) + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + v = reflect.New(elemType).Elem() + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, key) { + f = ff + break + } + if f == nil && ff.equalFold(ff.nameBytes, key) { + f = ff + } + } + if f != nil { + for _, i := range f.index { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = v.Field(i) + } + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + } + } + + // Check for unmarshaler on func field itself. + u, ut, pv = d.indirect(v, false) + if u != nil { + d.off = nameStart + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + + var mapElem reflect.Value + + // Parse function arguments. + for i := 0; ; i++ { + // closing ) - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + if i >= len(funcData.args) { + d.error(fmt.Errorf("json: too many arguments for function %s", funcName)) + } + key := []byte(funcData.args[i]) + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.Set(reflect.Zero(elemType)) + } + subv = mapElem + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, key) { + f = ff + break + } + if f == nil && ff.equalFold(ff.nameBytes, key) { + f = ff + } + } + if f != nil { + subv = v + destring = f.quoted + for _, i := range f.index { + if subv.Kind() == reflect.Ptr { + if subv.IsNil() { + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + subv = subv.Field(i) + } + } + } + + // Read value. + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + d.literalStore(nullLiteral, subv, false) + case string: + d.literalStore([]byte(qv), subv, true) + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + d.value(subv) + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kt := v.Type().Key() + var kv reflect.Value + switch { + case kt.Kind() == reflect.String: + kv = reflect.ValueOf(key).Convert(v.Type().Key()) + case reflect.PtrTo(kt).Implements(textUnmarshalerType): + kv = reflect.New(v.Type().Key()) + d.literalStore(key, kv, true) + kv = kv.Elem() + default: + panic("json: Unexpected key type") // should never occur + } + v.SetMapIndex(kv, subv) + } + + // Next token must be , or ). + op = d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + if op != scanParam { + d.error(errPhase) + } + } +} + +// keyed attempts to decode an object or function using a keyed doc extension, +// and returns the value and true on success, or nil and false otherwise. +func (d *decodeState) keyed() (interface{}, bool) { + if len(d.ext.keyed) == 0 { + return nil, false + } + + unquote := false + + // Look-ahead first key to check for a keyed document extension. + d.nextscan.reset() + var start, end int + for i, c := range d.data[d.off-1:] { + switch op := d.nextscan.step(&d.nextscan, c); op { + case scanSkipSpace, scanContinue, scanBeginObject: + continue + case scanBeginLiteral, scanBeginName: + unquote = op == scanBeginLiteral + start = i + continue + } + end = i + break + } + + name := d.data[d.off-1+start : d.off-1+end] + + var key []byte + var ok bool + if unquote { + key, ok = unquoteBytes(name) + if !ok { + d.error(errPhase) + } + } else { + funcData, ok := d.ext.funcs[string(name)] + if !ok { + return nil, false + } + key = []byte(funcData.key) + } + + decode, ok := d.ext.keyed[string(key)] + if !ok { + return nil, false + } + + d.off-- + out, err := decode(d.next()) + if err != nil { + d.error(err) + } + return out, true +} + +func (d *decodeState) storeKeyed(v reflect.Value) bool { + keyed, ok := d.keyed() + if !ok { + return false + } + d.storeValue(v, keyed) + return true +} + +var ( + trueBytes = []byte("true") + falseBytes = []byte("false") + nullBytes = []byte("null") +) + +func (d *decodeState) storeValue(v reflect.Value, from interface{}) { + switch from { + case nil: + d.literalStore(nullBytes, v, false) + return + case true: + d.literalStore(trueBytes, v, false) + return + case false: + d.literalStore(falseBytes, v, false) + return + } + fromv := reflect.ValueOf(from) + for fromv.Kind() == reflect.Ptr && !fromv.IsNil() { + fromv = fromv.Elem() + } + fromt := fromv.Type() + for v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + vt := v.Type() + if fromt.AssignableTo(vt) { + v.Set(fromv) + } else if fromt.ConvertibleTo(vt) { + v.Set(fromv.Convert(vt)) + } else { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + } +} + +func (d *decodeState) convertLiteral(name []byte) (interface{}, bool) { + if len(name) == 0 { + return nil, false + } + switch name[0] { + case 't': + if bytes.Equal(name, trueBytes) { + return true, true + } + case 'f': + if bytes.Equal(name, falseBytes) { + return false, true + } + case 'n': + if bytes.Equal(name, nullBytes) { + return nil, true + } + } + if l, ok := d.ext.consts[string(name)]; ok { + return l, true + } + return nil, false +} + +// literal consumes a literal from d.data[d.off-1:], decoding into the value v. +// The first byte of the literal has been read already +// (that's how the caller knows it's a literal). +func (d *decodeState) literal(v reflect.Value) { + // All bytes inside literal return scanContinue op code. + start := d.off - 1 + op := d.scanWhile(scanContinue) + + // Scan read one byte too far; back up. + d.off-- + d.scan.undo(op) + + d.literalStore(d.data[start:d.off], v, false) +} + +// convertNumber converts the number literal s to a float64 or a Number +// depending on the setting of d.useNumber. +func (d *decodeState) convertNumber(s string) (interface{}, error) { + if d.useNumber { + return Number(s), nil + } + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} + } + return f, nil +} + +var numberType = reflect.TypeOf(Number("")) + +// literalStore decodes a literal stored in item into v. +// +// fromQuoted indicates whether this literal came from unwrapping a +// string from the ",string" struct tag option. this is used only to +// produce more helpful error messages. +func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) { + // Check for unmarshaler. + if len(item) == 0 { + //Empty string given + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return + } + wantptr := item[0] == 'n' // null + u, ut, pv := d.indirect(v, wantptr) + if u != nil { + err := u.UnmarshalJSON(item) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + if item[0] != '"' { + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + } + return + } + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + err := ut.UnmarshalText(s) + if err != nil { + d.error(err) + } + return + } + + v = pv + + switch c := item[0]; c { + case 'n': // null + switch v.Kind() { + case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: + v.Set(reflect.Zero(v.Type())) + // otherwise, ignore null for primitives/string + } + case 't', 'f': // true, false + value := c == 't' + switch v.Kind() { + default: + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) + } + case reflect.Bool: + v.SetBool(value) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(value)) + } else { + d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) + } + } + + case '"': // string + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + switch v.Kind() { + default: + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + case reflect.Slice: + if v.Type().Elem().Kind() != reflect.Uint8 { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + break + } + b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) + n, err := base64.StdEncoding.Decode(b, s) + if err != nil { + d.saveError(err) + break + } + v.SetBytes(b[:n]) + case reflect.String: + v.SetString(string(s)) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(string(s))) + } else { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + } + } + + default: // number + if c != '-' && (c < '0' || c > '9') { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + s := string(item) + switch v.Kind() { + default: + if v.Kind() == reflect.String && v.Type() == numberType { + v.SetString(s) + if !isValidNumber(s) { + d.error(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)) + } + break + } + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) + } + case reflect.Interface: + n, err := d.convertNumber(s) + if err != nil { + d.saveError(err) + break + } + if v.NumMethod() != 0 { + d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) + break + } + v.Set(reflect.ValueOf(n)) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(s, 10, 64) + if err != nil || v.OverflowInt(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetInt(n) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(s, 10, 64) + if err != nil || v.OverflowUint(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetUint(n) + + case reflect.Float32, reflect.Float64: + n, err := strconv.ParseFloat(s, v.Type().Bits()) + if err != nil || v.OverflowFloat(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetFloat(n) + } + } +} + +// The xxxInterface routines build up a value to be stored +// in an empty interface. They are not strictly necessary, +// but they avoid the weight of reflection in this common case. + +// valueInterface is like value but returns interface{} +func (d *decodeState) valueInterface() interface{} { + switch d.scanWhile(scanSkipSpace) { + default: + d.error(errPhase) + panic("unreachable") + case scanBeginArray: + return d.arrayInterface() + case scanBeginObject: + return d.objectInterface() + case scanBeginLiteral: + return d.literalInterface() + case scanBeginName: + return d.nameInterface() + } +} + +func (d *decodeState) syntaxError(expected string) { + msg := fmt.Sprintf("invalid character '%c' looking for %s", d.data[d.off-1], expected) + d.error(&SyntaxError{msg, int64(d.off)}) +} + +// arrayInterface is like array but returns []interface{}. +func (d *decodeState) arrayInterface() []interface{} { + var v = make([]interface{}, 0) + for { + // Look ahead for ] - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndArray { + if len(v) > 0 && !d.ext.trailingCommas { + d.syntaxError("beginning of value") + } + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + v = append(v, d.valueInterface()) + + // Next token must be , or ]. + op = d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + if op != scanArrayValue { + d.error(errPhase) + } + } + return v +} + +// objectInterface is like object but returns map[string]interface{}. +func (d *decodeState) objectInterface() interface{} { + v, ok := d.keyed() + if ok { + return v + } + + m := make(map[string]interface{}) + for { + // Read opening " of string key or closing }. + op := d.scanWhile(scanSkipSpace) + if op == scanEndObject { + if len(m) > 0 && !d.ext.trailingCommas { + d.syntaxError("beginning of object key string") + } + break + } + if op == scanBeginName { + if !d.ext.unquotedKeys { + d.syntaxError("beginning of object key string") + } + } else if op != scanBeginLiteral { + d.error(errPhase) + } + unquotedKey := op == scanBeginName + + // Read string key. + start := d.off - 1 + op = d.scanWhile(scanContinue) + item := d.data[start : d.off-1] + var key string + if unquotedKey { + key = string(item) + } else { + var ok bool + key, ok = unquote(item) + if !ok { + d.error(errPhase) + } + } + + // Read : before value. + if op == scanSkipSpace { + op = d.scanWhile(scanSkipSpace) + } + if op != scanObjectKey { + d.error(errPhase) + } + + // Read value. + m[key] = d.valueInterface() + + // Next token must be , or }. + op = d.scanWhile(scanSkipSpace) + if op == scanEndObject { + break + } + if op != scanObjectValue { + d.error(errPhase) + } + } + return m +} + +// literalInterface is like literal but returns an interface value. +func (d *decodeState) literalInterface() interface{} { + // All bytes inside literal return scanContinue op code. + start := d.off - 1 + op := d.scanWhile(scanContinue) + + // Scan read one byte too far; back up. + d.off-- + d.scan.undo(op) + item := d.data[start:d.off] + + switch c := item[0]; c { + case 'n': // null + return nil + + case 't', 'f': // true, false + return c == 't' + + case '"': // string + s, ok := unquote(item) + if !ok { + d.error(errPhase) + } + return s + + default: // number + if c != '-' && (c < '0' || c > '9') { + d.error(errPhase) + } + n, err := d.convertNumber(string(item)) + if err != nil { + d.saveError(err) + } + return n + } +} + +// nameInterface is like function but returns map[string]interface{}. +func (d *decodeState) nameInterface() interface{} { + v, ok := d.keyed() + if ok { + return v + } + + nameStart := d.off - 1 + + op := d.scanWhile(scanContinue) + + name := d.data[nameStart : d.off-1] + if op != scanParam { + // Back up so the byte just read is consumed next. + d.off-- + d.scan.undo(op) + if l, ok := d.convertLiteral(name); ok { + return l + } + d.error(&SyntaxError{fmt.Sprintf("json: unknown constant %q", name), int64(d.off)}) + } + + funcName := string(name) + funcData := d.ext.funcs[funcName] + if funcData.key == "" { + d.error(fmt.Errorf("json: unknown function %q", funcName)) + } + + m := make(map[string]interface{}) + for i := 0; ; i++ { + // Look ahead for ) - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + if i >= len(funcData.args) { + d.error(fmt.Errorf("json: too many arguments for function %s", funcName)) + } + m[funcData.args[i]] = d.valueInterface() + + // Next token must be , or ). + op = d.scanWhile(scanSkipSpace) + if op == scanEndParams { + break + } + if op != scanParam { + d.error(errPhase) + } + } + return map[string]interface{}{funcData.key: m} +} + +// getu4 decodes \uXXXX from the beginning of s, returning the hex value, +// or it returns -1. +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + r, err := strconv.ParseUint(string(s[2:6]), 16, 64) + if err != nil { + return -1 + } + return rune(r) +} + +// unquote converts a quoted JSON string literal s into an actual string t. +// The rules are different than for Go, so cannot use strconv.Unquote. +func unquote(s []byte) (t string, ok bool) { + s, ok = unquoteBytes(s) + t = string(s) + return +} + +func unquoteBytes(s []byte) (t []byte, ok bool) { + if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { + return + } + s = s[1 : len(s)-1] + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { + return s, true + } + + b := make([]byte, len(s)+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < len(s) { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= len(s) { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} diff --git a/vendor/gopkg.in/mgo.v2/internal/json/encode.go b/vendor/gopkg.in/mgo.v2/internal/json/encode.go new file mode 100644 index 000000000..67a0f0062 --- /dev/null +++ b/vendor/gopkg.in/mgo.v2/internal/json/encode.go @@ -0,0 +1,1256 @@ +// Copyright 2010 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 json implements encoding and decoding of JSON as defined in +// RFC 4627. The mapping between JSON and Go values is described +// in the documentation for the Marshal and Unmarshal functions. +// +// See "JSON and Go" for an introduction to this package: +// https://golang.org/doc/articles/json_and_go.html +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "fmt" + "math" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements the Marshaler interface +// and is not a nil pointer, Marshal calls its MarshalJSON method +// to produce JSON. If no MarshalJSON method is present but the +// value implements encoding.TextMarshaler instead, Marshal calls +// its MarshalText method. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// UnmarshalJSON. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and Number values encode as JSON numbers. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" +// to keep some browsers from misinterpreting JSON output as HTML. +// Ampersand "&" is also escaped to "\u0026" for the same reason. +// This escaping can be disabled using an Encoder with DisableHTMLEscaping. +// +// Array and slice values encode as JSON arrays, except that +// []byte encodes as a base64-encoded string, and a nil slice +// encodes as the null JSON value. +// +// Struct values encode as JSON objects. Each exported struct field +// becomes a member of the object unless +// - the field's tag is "-", or +// - the field is empty and its tag specifies the "omitempty" option. +// The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or string of +// length zero. The object's default key string is the struct field name +// but can be specified in the struct field's tag value. The "json" key in +// the struct field's tag value is the key name, followed by an optional comma +// and options. Examples: +// +// // Field is ignored by this package. +// Field int `json:"-"` +// +// // Field appears in JSON as key "myName". +// Field int `json:"myName"` +// +// // Field appears in JSON as key "myName" and +// // the field is omitted from the object if its value is empty, +// // as defined above. +// Field int `json:"myName,omitempty"` +// +// // Field appears in JSON as key "Field" (the default), but +// // the field is skipped if empty. +// // Note the leading comma. +// Field int `json:",omitempty"` +// +// The "string" option signals that a field is stored as JSON inside a +// JSON-encoded string. It applies only to fields of string, floating point, +// integer, or boolean types. This extra level of encoding is sometimes used +// when communicating with JavaScript programs: +// +// Int64String int64 `json:",string"` +// +// The key name will be used if it's a non-empty string consisting of +// only Unicode letters, digits, dollar signs, percent signs, hyphens, +// underscores and slashes. +// +// Anonymous struct fields are usually marshaled as if their inner exported fields +// were fields in the outer struct, subject to the usual Go visibility rules amended +// as described in the next paragraph. +// An anonymous struct field with a name given in its JSON tag is treated as +// having that name, rather than being anonymous. +// An anonymous struct field of interface type is treated the same as having +// that type as its name, rather than being anonymous. +// +// The Go visibility rules for struct fields are amended for JSON when +// deciding which field to marshal or unmarshal. If there are +// multiple fields at the same level, and that level is the least +// nested (and would therefore be the nesting level selected by the +// usual Go rules), the following extra rules apply: +// +// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, +// even if there are multiple untagged fields that would otherwise conflict. +// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. +// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. +// +// Handling of anonymous struct fields is new in Go 1.1. +// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of +// an anonymous struct field in both current and earlier versions, give the field +// a JSON tag of "-". +// +// Map values encode as JSON objects. The map's key type must either be a string +// or implement encoding.TextMarshaler. The map keys are used as JSON object +// keys, subject to the UTF-8 coercion described for string values above. +// +// Pointer values encode as the value pointed to. +// A nil pointer encodes as the null JSON value. +// +// Interface values encode as the value contained in the interface. +// A nil interface value encodes as the null JSON value. +// +// Channel, complex, and function values cannot be encoded in JSON. +// Attempting to encode such a value causes Marshal to return +// an UnsupportedTypeError. +// +// JSON cannot represent cyclic data structures and Marshal does not +// handle them. Passing cyclic structures to Marshal will result in +// an infinite recursion. +// +func Marshal(v interface{}) ([]byte, error) { + e := &encodeState{} + err := e.marshal(v, encOpts{escapeHTML: true}) + if err != nil { + return nil, err + } + return e.Bytes(), nil +} + +// MarshalIndent is like Marshal but applies Indent to format the output. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + b, err := Marshal(v) + if err != nil { + return nil, err + } + var buf bytes.Buffer + err = Indent(&buf, b, prefix, indent) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML