From 652cc90f98aa3d9963dc5d2c51b38cd842eae6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Carr=C3=A9?= Date: Mon, 23 Jul 2018 15:33:58 +0200 Subject: [PATCH] Update weaveworks/common to latest version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` $ gvt delete github.com/weaveworks/common $ gvt fetch --revision 4d96fd8dcf2c7b417912c6219b310112cb4a4626 github.com/weaveworks/common 2018/07/23 15:31:11 Fetching: github.com/weaveworks/common 2018/07/23 15:31:14 · Skipping (existing): github.com/golang/protobuf/ptypes/any 2018/07/23 15:31:14 · Fetching recursive dependency: github.com/pkg/errors 2018/07/23 15:31:16 · Skipping (existing): github.com/aws/aws-sdk-go/aws 2018/07/23 15:31:16 · Fetching recursive dependency: github.com/sirupsen/logrus 2018/07/23 15:31:18 ·· Skipping (existing): golang.org/x/sys/unix 2018/07/23 15:31:18 ·· Skipping (existing): golang.org/x/crypto/ssh/terminal 2018/07/23 15:31:18 · Skipping (existing): google.golang.org/grpc/status 2018/07/23 15:31:18 · Skipping (existing): github.com/gorilla/mux 2018/07/23 15:31:18 · Fetching recursive dependency: github.com/opentracing-contrib/go-stdlib/nethttp 2018/07/23 15:31:20 ·· Skipping (existing): github.com/opentracing/opentracing-go/ext 2018/07/23 15:31:20 ·· Skipping (existing): github.com/opentracing/opentracing-go/log 2018/07/23 15:31:20 ·· Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:31:20 · Skipping (existing): github.com/prometheus/client_golang/prometheus 2018/07/23 15:31:20 · Skipping (existing): google.golang.org/grpc 2018/07/23 15:31:20 · Skipping (existing): github.com/pmezard/go-difflib/difflib 2018/07/23 15:31:20 · Fetching recursive dependency: github.com/go-kit/kit/log 2018/07/23 15:31:23 ·· Fetching recursive dependency: github.com/go-logfmt/logfmt 2018/07/23 15:31:25 ··· Fetching recursive dependency: github.com/kr/logfmt 2018/07/23 15:31:27 ·· Fetching recursive dependency: github.com/go-stack/stack 2018/07/23 15:31:29 · Fetching recursive dependency: google.golang.org/genproto/googleapis/rpc/status 2018/07/23 15:31:37 ·· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:31:37 ·· Skipping (existing): github.com/golang/protobuf/ptypes/any 2018/07/23 15:31:37 · Skipping (existing): github.com/opentracing/opentracing-go/log 2018/07/23 15:31:37 · Fetching recursive dependency: github.com/sercand/kuberesolver 2018/07/23 15:31:39 ·· Skipping (existing): google.golang.org/grpc/grpclog 2018/07/23 15:31:39 ·· Skipping (existing): google.golang.org/grpc/resolver 2018/07/23 15:31:39 ·· Skipping (existing): golang.org/x/net/context 2018/07/23 15:31:39 · Skipping (existing): google.golang.org/grpc/metadata 2018/07/23 15:31:39 · Skipping (existing): github.com/opentracing/opentracing-go/ext 2018/07/23 15:31:39 · Skipping (existing): github.com/armon/go-socks5 2018/07/23 15:31:39 · Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:31:39 · Skipping (existing): github.com/davecgh/go-spew/spew 2018/07/23 15:31:39 · Skipping (existing): github.com/golang/protobuf/ptypes 2018/07/23 15:31:39 · Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:31:39 · Fetching recursive dependency: github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc 2018/07/23 15:31:41 ·· Skipping (existing): github.com/opentracing/opentracing-go/log 2018/07/23 15:31:41 ·· Skipping (existing): golang.org/x/net/context 2018/07/23 15:31:41 ·· Skipping (existing): google.golang.org/grpc/codes 2018/07/23 15:31:41 ·· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:31:41 ·· Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:31:41 ·· Skipping (existing): github.com/opentracing/opentracing-go/ext 2018/07/23 15:31:41 ·· Skipping (existing): google.golang.org/grpc 2018/07/23 15:31:41 ·· Skipping (existing): google.golang.org/grpc/metadata 2018/07/23 15:31:41 ·· Skipping (existing): google.golang.org/grpc/status 2018/07/23 15:31:41 · Fetching recursive dependency: github.com/uber/jaeger-client-go/config 2018/07/23 15:31:44 ·· Fetching recursive dependency: github.com/uber/jaeger-client-go/internal/throttler/remote 2018/07/23 15:31:44 ··· Fetching recursive dependency: github.com/uber/jaeger-client-go/utils 2018/07/23 15:31:44 ···· Fetching recursive dependency: github.com/uber/jaeger-client-go/thrift 2018/07/23 15:31:44 ···· Fetching recursive dependency: github.com/uber/jaeger-client-go/thrift-gen/agent 2018/07/23 15:31:44 ····· Fetching recursive dependency: github.com/uber/jaeger-client-go/thrift-gen/jaeger 2018/07/23 15:31:44 ····· Fetching recursive dependency: github.com/uber/jaeger-client-go/thrift-gen/zipkincore 2018/07/23 15:31:44 ··· Fetching recursive dependency: github.com/uber/jaeger-client-go 2018/07/23 15:31:44 ···· Fetching recursive dependency: github.com/crossdock/crossdock-go 2018/07/23 15:31:46 ····· Skipping (existing): github.com/davecgh/go-spew/spew 2018/07/23 15:31:46 ····· Skipping (existing): golang.org/x/net/context/ctxhttp 2018/07/23 15:31:46 ····· Skipping (existing): golang.org/x/net/context 2018/07/23 15:31:46 ····· Skipping (existing): github.com/pmezard/go-difflib/difflib 2018/07/23 15:31:46 ···· Skipping (existing): github.com/opentracing/opentracing-go/log 2018/07/23 15:31:46 ···· Fetching recursive dependency: go.uber.org/zap/zapcore 2018/07/23 15:31:49 ····· Fetching recursive dependency: go.uber.org/atomic 2018/07/23 15:31:51 ····· Fetching recursive dependency: go.uber.org/zap/internal/bufferpool 2018/07/23 15:31:51 ······ Fetching recursive dependency: go.uber.org/zap/buffer 2018/07/23 15:31:51 ····· Fetching recursive dependency: go.uber.org/multierr 2018/07/23 15:31:54 ····· Fetching recursive dependency: go.uber.org/zap/internal/exit 2018/07/23 15:31:54 ····· Fetching recursive dependency: go.uber.org/zap/internal/color 2018/07/23 15:31:54 ···· Fetching recursive dependency: go.uber.org/zap 2018/07/23 15:31:54 ···· Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:31:54 ···· Skipping (existing): github.com/opentracing/opentracing-go/ext 2018/07/23 15:31:54 ···· Fetching recursive dependency: github.com/uber/jaeger-lib/metrics 2018/07/23 15:31:56 ····· Fetching recursive dependency: github.com/uber-go/tally 2018/07/23 15:31:58 ······ Fetching recursive dependency: github.com/m3db/prometheus_client_golang/prometheus/promhttp 2018/07/23 15:32:00 ······· Skipping (existing): github.com/prometheus/client_golang/prometheus 2018/07/23 15:32:00 ······· Skipping (existing): github.com/prometheus/common/expfmt 2018/07/23 15:32:00 ······· Skipping (existing): github.com/prometheus/client_model/go 2018/07/23 15:32:00 ······ Fetching recursive dependency: gopkg.in/validator.v2 2018/07/23 15:32:06 ······ Fetching recursive dependency: github.com/cactus/go-statsd-client/statsd 2018/07/23 15:32:08 ······ Skipping (existing): gopkg.in/yaml.v2 2018/07/23 15:32:08 ······ Fetching recursive dependency: github.com/m3db/prometheus_client_golang/prometheus 2018/07/23 15:32:08 ······· Skipping (existing): github.com/prometheus/procfs 2018/07/23 15:32:08 ······· Skipping (existing): github.com/prometheus/client_model/go 2018/07/23 15:32:08 ······· Skipping (existing): github.com/prometheus/common/expfmt 2018/07/23 15:32:08 ······· Skipping (existing): golang.org/x/net/context 2018/07/23 15:32:08 ······· Skipping (existing): github.com/beorn7/perks/quantile 2018/07/23 15:32:08 ······· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:32:08 ······· Skipping (existing): github.com/prometheus/common/model 2018/07/23 15:32:08 ······· Skipping (existing): github.com/prometheus/client_golang/prometheus 2018/07/23 15:32:08 ······ Fetching recursive dependency: github.com/apache/thrift/lib/go/thrift 2018/07/23 15:32:13 ····· Skipping (existing): github.com/stretchr/testify/assert 2018/07/23 15:32:13 ····· Fetching recursive dependency: github.com/go-kit/kit/metrics/influx 2018/07/23 15:32:13 ······ Fetching recursive dependency: github.com/influxdata/influxdb/client/v2 2018/07/23 15:32:17 ······· Fetching recursive dependency: github.com/influxdata/influxdb/models 2018/07/23 15:32:17 ········ Fetching recursive dependency: github.com/influxdata/influxdb/pkg/escape 2018/07/23 15:32:17 ······ Fetching recursive dependency: github.com/go-kit/kit/metrics 2018/07/23 15:32:17 ······· Fetching recursive dependency: github.com/performancecopilot/speed 2018/07/23 15:32:19 ······· Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/aws 2018/07/23 15:32:28 ········ Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/internal/sdk 2018/07/23 15:32:28 ········ Skipping (existing): github.com/go-ini/ini 2018/07/23 15:32:28 ········ Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/service/sts 2018/07/23 15:32:28 ········· Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/private/protocol/query 2018/07/23 15:32:28 ·········· Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/private/protocol 2018/07/23 15:32:28 ········· Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/internal/awsutil 2018/07/23 15:32:28 ·········· Skipping (existing): github.com/jmespath/go-jmespath 2018/07/23 15:32:28 ······· Fetching recursive dependency: github.com/aws/aws-sdk-go-v2/service/cloudwatch 2018/07/23 15:32:29 ······· Skipping (existing): github.com/aws/aws-sdk-go/aws 2018/07/23 15:32:29 ······· Skipping (existing): github.com/prometheus/client_golang/prometheus 2018/07/23 15:32:29 ······· Skipping (existing): github.com/aws/aws-sdk-go/service/cloudwatch 2018/07/23 15:32:29 ······· Skipping (existing): github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface 2018/07/23 15:32:29 ······· Fetching recursive dependency: golang.org/x/sync/errgroup 2018/07/23 15:32:31 ········ Skipping (existing): golang.org/x/net/context 2018/07/23 15:32:31 ······· Fetching recursive dependency: github.com/go-kit/kit/util/conn 2018/07/23 15:32:31 ······· Fetching recursive dependency: github.com/VividCortex/gohistogram 2018/07/23 15:32:33 ····· Skipping (existing): github.com/prometheus/client_golang/prometheus 2018/07/23 15:32:33 ····· Fetching recursive dependency: github.com/codahale/hdrhistogram 2018/07/23 15:32:35 ·· Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:32:35 · Fetching recursive dependency: github.com/mwitkow/go-grpc-middleware 2018/07/23 15:32:37 ·· Fetching recursive dependency: github.com/grpc-ecosystem/go-grpc-middleware/logging 2018/07/23 15:32:39 ··· Fetching recursive dependency: github.com/grpc-ecosystem/go-grpc-middleware 2018/07/23 15:32:39 ···· Fetching recursive dependency: github.com/golang/protobuf/jsonpb 2018/07/23 15:32:42 ····· Skipping (existing): github.com/golang/protobuf/ptypes/timestamp 2018/07/23 15:32:42 ····· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:32:42 ····· Skipping (existing): github.com/golang/protobuf/ptypes/duration 2018/07/23 15:32:42 ····· Skipping (existing): github.com/golang/protobuf/ptypes/any 2018/07/23 15:32:42 ····· Skipping (existing): github.com/golang/protobuf/ptypes/struct 2018/07/23 15:32:42 ····· Skipping (existing): github.com/golang/protobuf/ptypes/wrappers 2018/07/23 15:32:42 ···· Skipping (existing): google.golang.org/grpc/metadata 2018/07/23 15:32:42 ···· Fetching recursive dependency: github.com/stretchr/testify/suite 2018/07/23 15:32:45 ····· Skipping (existing): github.com/stretchr/testify/assert 2018/07/23 15:32:45 ····· Fetching recursive dependency: github.com/stretchr/testify/require 2018/07/23 15:32:45 ······ Skipping (existing): github.com/stretchr/testify/assert 2018/07/23 15:32:45 ···· Skipping (existing): google.golang.org/grpc/peer 2018/07/23 15:32:45 ···· Skipping (existing): golang.org/x/net/context 2018/07/23 15:32:45 ···· Skipping (existing): golang.org/x/net/trace 2018/07/23 15:32:45 ···· Fetching recursive dependency: github.com/gogo/protobuf/gogoproto 2018/07/23 15:32:48 ····· Fetching recursive dependency: github.com/gogo/protobuf/protoc-gen-gogo/descriptor 2018/07/23 15:32:48 ······ Skipping (existing): github.com/gogo/protobuf/proto 2018/07/23 15:32:48 ····· Skipping (existing): github.com/gogo/protobuf/proto 2018/07/23 15:32:48 ···· Skipping (existing): google.golang.org/grpc/credentials 2018/07/23 15:32:48 ···· Skipping (existing): google.golang.org/grpc 2018/07/23 15:32:48 ···· Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:32:48 ···· Skipping (existing): google.golang.org/grpc/codes 2018/07/23 15:32:48 ···· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:32:48 ···· Skipping (existing): google.golang.org/grpc/grpclog 2018/07/23 15:32:48 ···· Skipping (existing): github.com/opentracing/opentracing-go/ext 2018/07/23 15:32:48 ···· Skipping (existing): github.com/opentracing/opentracing-go/log 2018/07/23 15:32:48 ··· Skipping (existing): golang.org/x/net/context 2018/07/23 15:32:48 ··· Skipping (existing): google.golang.org/grpc 2018/07/23 15:32:48 ··· Skipping (existing): google.golang.org/grpc/grpclog 2018/07/23 15:32:48 ··· Skipping (existing): google.golang.org/grpc/codes 2018/07/23 15:32:48 ··· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:32:48 ·· Skipping (existing): github.com/opentracing/opentracing-go 2018/07/23 15:32:48 ·· Skipping (existing): google.golang.org/grpc 2018/07/23 15:32:48 ·· Skipping (existing): golang.org/x/net/context 2018/07/23 15:32:48 ·· Skipping (existing): google.golang.org/grpc/codes 2018/07/23 15:32:48 ·· Skipping (existing): google.golang.org/grpc/grpclog 2018/07/23 15:32:48 ·· Skipping (existing): github.com/opentracing/opentracing-go/log 2018/07/23 15:32:48 ·· Skipping (existing): google.golang.org/grpc/metadata 2018/07/23 15:32:48 ·· Skipping (existing): google.golang.org/grpc/peer 2018/07/23 15:32:48 ·· Skipping (existing): google.golang.org/grpc/credentials 2018/07/23 15:32:48 ·· Skipping (existing): github.com/golang/protobuf/proto 2018/07/23 15:32:48 ·· Skipping (existing): golang.org/x/net/trace 2018/07/23 15:32:48 ·· Skipping (existing): github.com/opentracing/opentracing-go/ext 2018/07/23 15:32:48 · Fetching recursive dependency: github.com/weaveworks/promrus 2018/07/23 15:32:53 ·· Skipping (existing): gopkg.in/yaml.v2 2018/07/23 15:32:53 ·· Skipping (existing): golang.org/x/net/context/ctxhttp 2018/07/23 15:32:53 ·· Fetching recursive dependency: github.com/stretchr/objx 2018/07/23 15:32:55 ·· Fetching recursive dependency: gopkg.in/alecthomas/kingpin.v2 2018/07/23 15:32:58 ··· Fetching recursive dependency: github.com/alecthomas/units 2018/07/23 15:33:00 ··· Fetching recursive dependency: github.com/alecthomas/template 2018/07/23 15:33:02 ·· Fetching recursive dependency: github.com/julienschmidt/httprouter 2018/07/23 15:33:05 ·· Skipping (existing): golang.org/x/net/context 2018/07/23 15:33:05 · Skipping (existing): github.com/aws/aws-sdk-go/aws/credentials 2018/07/23 15:33:05 · Skipping (existing): github.com/golang/protobuf/ptypes/empty 2018/07/23 15:33:05 · Skipping (existing): golang.org/x/net/context 2018/07/23 15:33:05 · Skipping (existing): golang.org/x/tools/cover 2018/07/23 15:33:05 · Skipping (existing): github.com/mgutz/ansi ``` --- .../VividCortex/gohistogram/LICENSE | 19 + .../VividCortex/gohistogram/histogram.go | 23 + .../gohistogram/numerichistogram.go | 160 + .../gohistogram/weightedhistogram.go | 190 + vendor/github.com/alecthomas/template/LICENSE | 27 + vendor/github.com/alecthomas/template/doc.go | 406 ++ vendor/github.com/alecthomas/template/exec.go | 845 ++++ .../github.com/alecthomas/template/funcs.go | 598 +++ .../github.com/alecthomas/template/helper.go | 108 + .../alecthomas/template/parse/lex.go | 556 +++ .../alecthomas/template/parse/node.go | 834 ++++ .../alecthomas/template/parse/parse.go | 700 ++++ .../alecthomas/template/template.go | 218 + vendor/github.com/alecthomas/units/COPYING | 19 + vendor/github.com/alecthomas/units/bytes.go | 83 + vendor/github.com/alecthomas/units/doc.go | 13 + vendor/github.com/alecthomas/units/si.go | 26 + vendor/github.com/alecthomas/units/util.go | 138 + .../apache/thrift/lib/go/thrift/LICENSE | 239 ++ .../lib/go/thrift/application_exception.go | 164 + .../thrift/lib/go/thrift/binary_protocol.go | 515 +++ .../lib/go/thrift/buffered_transport.go | 92 + .../apache/thrift/lib/go/thrift/client.go | 85 + .../thrift/lib/go/thrift/compact_protocol.go | 816 ++++ .../apache/thrift/lib/go/thrift/context.go | 24 + .../thrift/lib/go/thrift/debug_protocol.go | 270 ++ .../thrift/lib/go/thrift/deserializer.go | 58 + .../apache/thrift/lib/go/thrift/exception.go | 44 + .../apache/thrift/lib/go/thrift/field.go | 79 + .../thrift/lib/go/thrift/framed_transport.go | 173 + .../thrift/lib/go/thrift/http_client.go | 242 ++ .../thrift/lib/go/thrift/http_transport.go | 63 + .../lib/go/thrift/iostream_transport.go | 214 + .../thrift/lib/go/thrift/json_protocol.go | 584 +++ .../thrift/lib/go/thrift/memory_buffer.go | 80 + .../thrift/lib/go/thrift/messagetype.go | 31 + .../lib/go/thrift/multiplexed_protocol.go | 170 + .../apache/thrift/lib/go/thrift/numeric.go | 164 + .../apache/thrift/lib/go/thrift/pointerize.go | 50 + .../thrift/lib/go/thrift/processor_factory.go | 70 + .../apache/thrift/lib/go/thrift/protocol.go | 179 + .../lib/go/thrift/protocol_exception.go | 77 + .../thrift/lib/go/thrift/protocol_factory.go | 25 + .../thrift/lib/go/thrift/rich_transport.go | 68 + .../apache/thrift/lib/go/thrift/serializer.go | 79 + .../apache/thrift/lib/go/thrift/server.go | 35 + .../thrift/lib/go/thrift/server_socket.go | 134 + .../thrift/lib/go/thrift/server_transport.go | 34 + .../lib/go/thrift/simple_json_protocol.go | 1338 +++++++ .../thrift/lib/go/thrift/simple_server.go | 227 ++ .../apache/thrift/lib/go/thrift/socket.go | 166 + .../thrift/lib/go/thrift/ssl_server_socket.go | 112 + .../apache/thrift/lib/go/thrift/ssl_socket.go | 176 + .../apache/thrift/lib/go/thrift/transport.go | 70 + .../lib/go/thrift/transport_exception.go | 90 + .../thrift/lib/go/thrift/transport_factory.go | 39 + .../apache/thrift/lib/go/thrift/type.go | 69 + .../thrift/lib/go/thrift/zlib_transport.go | 132 + .../aws/aws-sdk-go-v2/aws/LICENSE.txt | 202 + .../aws/aws-sdk-go-v2/aws/arn/arn.go | 86 + .../aws/aws-sdk-go-v2/aws/awserr/error.go | 145 + .../aws/aws-sdk-go-v2/aws/awserr/types.go | 194 + .../aws/aws-sdk-go-v2/aws/chain_provider.go | 75 + .../aws/aws-sdk-go-v2/aws/client.go | 85 + .../aws/aws-sdk-go-v2/aws/client_logger.go | 105 + .../aws/aws-sdk-go-v2/aws/config.go | 98 + .../aws/connection_reset_error.go | 19 + .../aws/connection_reset_error_other.go | 11 + .../aws/aws-sdk-go-v2/aws/context.go | 71 + .../aws/aws-sdk-go-v2/aws/context_1_6.go | 41 + .../aws/aws-sdk-go-v2/aws/context_1_7.go | 9 + .../aws/aws-sdk-go-v2/aws/convert_types.go | 387 ++ .../aws/aws-sdk-go-v2/aws/credentials.go | 138 + .../aws/aws-sdk-go-v2/aws/default_retryer.go | 136 + .../aws-sdk-go-v2/aws/defaults/defaults.go | 92 + .../aws-sdk-go-v2/aws/defaults/handlers.go | 229 ++ .../aws/defaults/param_validator.go | 19 + .../aws/defaults/user_agent_handlers.go | 36 + .../github.com/aws/aws-sdk-go-v2/aws/doc.go | 56 + .../aws/aws-sdk-go-v2/aws/ec2metadata/api.go | 162 + .../aws-sdk-go-v2/aws/ec2metadata/service.go | 110 + .../aws/ec2rolecreds/provider.go | 155 + .../aws/endpointcreds/provider.go | 167 + .../aws/aws-sdk-go-v2/aws/endpoints.go | 52 + .../aws/aws-sdk-go-v2/aws/endpoints/decode.go | 143 + .../aws-sdk-go-v2/aws/endpoints/defaults.go | 3175 +++++++++++++++ .../aws/aws-sdk-go-v2/aws/endpoints/doc.go | 69 + .../aws-sdk-go-v2/aws/endpoints/endpoints.go | 344 ++ .../aws-sdk-go-v2/aws/endpoints/v3model.go | 313 ++ .../aws/endpoints/v3model_codegen.go | 330 ++ .../aws/aws-sdk-go-v2/aws/errors.go | 17 + .../aws/aws-sdk-go-v2/aws/external/config.go | 132 + .../aws-sdk-go-v2/aws/external/env_config.go | 236 ++ .../aws-sdk-go-v2/aws/external/http_client.go | 42 + .../aws/aws-sdk-go-v2/aws/external/local.go | 49 + .../aws-sdk-go-v2/aws/external/provider.go | 325 ++ .../aws/aws-sdk-go-v2/aws/external/resolve.go | 216 + .../aws/external/shared_config.go | 430 ++ .../aws/aws-sdk-go-v2/aws/handlers.go | 256 ++ .../aws/aws-sdk-go-v2/aws/http_request.go | 24 + .../aws/aws-sdk-go-v2/aws/jsonvalue.go | 12 + .../aws/aws-sdk-go-v2/aws/logger.go | 97 + .../aws/aws-sdk-go-v2/aws/offset_reader.go | 58 + .../aws-sdk-go-v2/aws/plugincreds/doc_1_7.go | 5 + .../aws-sdk-go-v2/aws/plugincreds/provider.go | 190 + .../aws/aws-sdk-go-v2/aws/request.go | 587 +++ .../aws/aws-sdk-go-v2/aws/request_1_7.go | 39 + .../aws/aws-sdk-go-v2/aws/request_1_8.go | 33 + .../aws/aws-sdk-go-v2/aws/request_context.go | 12 + .../aws-sdk-go-v2/aws/request_context_1_6.go | 12 + .../aws-sdk-go-v2/aws/request_pagination.go | 187 + .../aws/aws-sdk-go-v2/aws/response.go | 8 + .../aws/aws-sdk-go-v2/aws/retryer.go | 160 + .../aws/aws-sdk-go-v2/aws/signer/v2/v2.go | 178 + .../aws/signer/v4/header_rules.go | 82 + .../aws-sdk-go-v2/aws/signer/v4/options.go | 7 + .../aws-sdk-go-v2/aws/signer/v4/uri_path.go | 24 + .../aws/aws-sdk-go-v2/aws/signer/v4/v4.go | 755 ++++ .../aws/aws-sdk-go-v2/aws/static_provider.go | 52 + .../aws-sdk-go-v2/aws/stscreds/provider.go | 264 ++ .../aws-sdk-go-v2/aws/timeout_read_closer.go | 94 + .../github.com/aws/aws-sdk-go-v2/aws/types.go | 118 + .../github.com/aws/aws-sdk-go-v2/aws/url.go | 12 + .../aws/aws-sdk-go-v2/aws/url_1_7.go | 29 + .../aws/aws-sdk-go-v2/aws/validation.go | 234 ++ .../aws/aws-sdk-go-v2/aws/version.go | 8 + .../aws/aws-sdk-go-v2/aws/waiter.go | 284 ++ .../internal/awsutil/LICENSE.txt | 202 + .../aws-sdk-go-v2/internal/awsutil/copy.go | 112 + .../aws-sdk-go-v2/internal/awsutil/equal.go | 33 + .../internal/awsutil/path_value.go | 225 ++ .../internal/awsutil/prettify.go | 113 + .../internal/awsutil/string_value.go | 89 + .../aws-sdk-go-v2/internal/sdk/LICENSE.txt | 202 + .../aws-sdk-go-v2/internal/sdk/interfaces.go | 9 + .../aws/aws-sdk-go-v2/internal/sdk/time.go | 44 + .../private/protocol/LICENSE.txt | 202 + .../private/protocol/ec2query/build.go | 35 + .../private/protocol/ec2query/unmarshal.go | 61 + .../aws-sdk-go-v2/private/protocol/encode.go | 95 + .../aws-sdk-go-v2/private/protocol/fields.go | 197 + .../private/protocol/header_encoder.go | 116 + .../private/protocol/idempotency.go | 75 + .../private/protocol/json/encode.go | 290 ++ .../private/protocol/json/escape.go | 198 + .../private/protocol/json/jsonutil/build.go | 293 ++ .../protocol/json/jsonutil/unmarshal.go | 242 ++ .../private/protocol/jsonrpc/jsonrpc.go | 109 + .../private/protocol/jsonvalue.go | 76 + .../private/protocol/metadata.go | 24 + .../private/protocol/path_replace.go | 136 + .../private/protocol/query/build.go | 36 + .../protocol/query/queryutil/queryutil.go | 261 ++ .../private/protocol/query/unmarshal.go | 33 + .../private/protocol/query/unmarshal_error.go | 66 + .../private/protocol/query_encoder.go | 105 + .../private/protocol/rest/build.go | 339 ++ .../private/protocol/rest/encode.go | 144 + .../private/protocol/rest/payload.go | 45 + .../private/protocol/rest/unmarshal.go | 251 ++ .../private/protocol/restjson/encode.go | 165 + .../private/protocol/restjson/restjson.go | 112 + .../private/protocol/restxml/encode.go | 162 + .../private/protocol/restxml/restxml.go | 90 + .../aws-sdk-go-v2/private/protocol/target.go | 38 + .../private/protocol/unmarshal.go | 21 + .../aws-sdk-go-v2/private/protocol/value.go | 30 + .../private/protocol/xml/encode.go | 415 ++ .../private/protocol/xml/xmlutil/build.go | 302 ++ .../private/protocol/xml/xmlutil/unmarshal.go | 278 ++ .../protocol/xml/xmlutil/xml_to_struct.go | 147 + .../service/cloudwatch/LICENSE.txt | 202 + .../aws-sdk-go-v2/service/cloudwatch/api.go | 3517 +++++++++++++++++ .../cloudwatch/cloudwatchiface/interface.go | 102 + .../aws-sdk-go-v2/service/cloudwatch/doc.go | 42 + .../service/cloudwatch/errors.go | 66 + .../service/cloudwatch/service.go | 80 + .../service/cloudwatch/waiters.go | 55 + .../aws/aws-sdk-go-v2/service/sts/LICENSE.txt | 202 + .../aws/aws-sdk-go-v2/service/sts/api.go | 1832 +++++++++ .../service/sts/customizations.go | 12 + .../aws/aws-sdk-go-v2/service/sts/doc.go | 72 + .../aws/aws-sdk-go-v2/service/sts/errors.go | 73 + .../aws/aws-sdk-go-v2/service/sts/service.go | 80 + .../service/sts/stsiface/interface.go | 80 + .../cactus/go-statsd-client/statsd/LICENSE.md | 19 + .../go-statsd-client/statsd/buffer_pool.go | 31 + .../cactus/go-statsd-client/statsd/client.go | 327 ++ .../statsd/client_buffered.go | 48 + .../go-statsd-client/statsd/client_noop.go | 111 + .../cactus/go-statsd-client/statsd/doc.go | 29 + .../cactus/go-statsd-client/statsd/sender.go | 69 + .../statsd/sender_buffered.go | 175 + .../statsd/statsdtest/recorder.go | 79 + .../statsd/statsdtest/stat.go | 139 + .../go-statsd-client/statsd/validator.go | 26 + .../github.com/codahale/hdrhistogram/LICENSE | 21 + .../github.com/codahale/hdrhistogram/hdr.go | 564 +++ .../codahale/hdrhistogram/window.go | 45 + .../github.com/crossdock/crossdock-go/LICENSE | 21 + .../crossdock-go/assert/assertion_forward.go | 387 ++ .../crossdock-go/assert/assertions.go | 1072 +++++ .../crossdock/crossdock-go/assert/doc.go | 68 + .../crossdock/crossdock-go/assert/errors.go | 33 + .../crossdock-go/assert/forward_assertions.go | 39 + .../crossdock-go/assert/http_assertions.go | 129 + .../github.com/crossdock/crossdock-go/call.go | 65 + .../crossdock/crossdock-go/client.go | 91 + .../crossdock/crossdock-go/combinations.go | 76 + .../github.com/crossdock/crossdock-go/doc.go | 37 + .../crossdock/crossdock-go/entry.go | 62 + .../crossdock/crossdock-go/require/doc.go | 51 + .../require/forward_requirements.go | 39 + .../crossdock/crossdock-go/require/require.go | 1338 +++++++ .../crossdock-go/require/require_forward.go | 388 ++ .../crossdock-go/require/requirements.go | 32 + .../github.com/crossdock/crossdock-go/run.go | 80 + vendor/github.com/crossdock/crossdock-go/t.go | 145 + .../crossdock/crossdock-go/testify.go | 640 +++ .../github.com/crossdock/crossdock-go/wait.go | 53 + vendor/github.com/go-kit/kit/log/LICENSE | 22 + .../kit/log/deprecated_levels/levels.go | 127 + vendor/github.com/go-kit/kit/log/doc.go | 116 + .../github.com/go-kit/kit/log/json_logger.go | 89 + vendor/github.com/go-kit/kit/log/level/doc.go | 22 + .../github.com/go-kit/kit/log/level/level.go | 205 + vendor/github.com/go-kit/kit/log/log.go | 135 + .../go-kit/kit/log/logfmt_logger.go | 62 + .../github.com/go-kit/kit/log/nop_logger.go | 8 + vendor/github.com/go-kit/kit/log/stdlib.go | 116 + vendor/github.com/go-kit/kit/log/sync.go | 116 + .../go-kit/kit/log/syslog/syslog.go | 143 + .../go-kit/kit/log/term/colorlogger.go | 144 + .../go-kit/kit/log/term/colorwriter_others.go | 12 + .../kit/log/term/colorwriter_windows.go | 190 + vendor/github.com/go-kit/kit/log/term/term.go | 22 + .../go-kit/kit/log/term/terminal_appengine.go | 15 + .../go-kit/kit/log/term/terminal_darwin.go | 10 + .../go-kit/kit/log/term/terminal_freebsd.go | 7 + .../go-kit/kit/log/term/terminal_linux.go | 12 + .../kit/log/term/terminal_notwindows.go | 25 + .../go-kit/kit/log/term/terminal_openbsd.go | 5 + .../go-kit/kit/log/term/terminal_windows.go | 102 + vendor/github.com/go-kit/kit/log/value.go | 102 + vendor/github.com/go-kit/kit/metrics/LICENSE | 22 + .../kit/metrics/cloudwatch/cloudwatch.go | 343 ++ .../kit/metrics/cloudwatch2/cloudwatch2.go | 241 ++ .../go-kit/kit/metrics/discard/discard.go | 40 + vendor/github.com/go-kit/kit/metrics/doc.go | 97 + .../go-kit/kit/metrics/dogstatsd/dogstatsd.go | 389 ++ .../go-kit/kit/metrics/expvar/expvar.go | 94 + .../go-kit/kit/metrics/generic/generic.go | 247 ++ .../go-kit/kit/metrics/graphite/graphite.go | 203 + .../go-kit/kit/metrics/influx/influx.go | 267 ++ .../kit/metrics/influxstatsd/influxstatsd.go | 389 ++ .../kit/metrics/internal/convert/convert.go | 135 + .../kit/metrics/internal/lv/labelvalues.go | 14 + .../go-kit/kit/metrics/internal/lv/space.go | 145 + .../kit/metrics/internal/ratemap/ratemap.go | 40 + .../github.com/go-kit/kit/metrics/metrics.go | 25 + .../go-kit/kit/metrics/multi/multi.go | 86 + .../github.com/go-kit/kit/metrics/pcp/pcp.go | 125 + .../kit/metrics/prometheus/prometheus.go | 165 + .../go-kit/kit/metrics/provider/discard.go | 24 + .../go-kit/kit/metrics/provider/dogstatsd.go | 43 + .../go-kit/kit/metrics/provider/expvar.go | 31 + .../go-kit/kit/metrics/provider/graphite.go | 41 + .../go-kit/kit/metrics/provider/influx.go | 40 + .../go-kit/kit/metrics/provider/prometheus.go | 63 + .../go-kit/kit/metrics/provider/provider.go | 42 + .../go-kit/kit/metrics/provider/statsd.go | 43 + .../go-kit/kit/metrics/statsd/statsd.go | 239 ++ .../go-kit/kit/metrics/teststat/buffers.go | 65 + .../go-kit/kit/metrics/teststat/populate.go | 72 + .../go-kit/kit/metrics/teststat/teststat.go | 119 + vendor/github.com/go-kit/kit/metrics/timer.go | 36 + .../github.com/go-kit/kit/util/conn/LICENSE | 22 + vendor/github.com/go-kit/kit/util/conn/doc.go | 2 + .../go-kit/kit/util/conn/manager.go | 152 + vendor/github.com/go-logfmt/logfmt/LICENSE | 22 + vendor/github.com/go-logfmt/logfmt/decode.go | 237 ++ vendor/github.com/go-logfmt/logfmt/doc.go | 6 + vendor/github.com/go-logfmt/logfmt/encode.go | 321 ++ vendor/github.com/go-logfmt/logfmt/fuzz.go | 126 + .../github.com/go-logfmt/logfmt/jsonstring.go | 277 ++ vendor/github.com/go-stack/stack/LICENSE.md | 21 + vendor/github.com/go-stack/stack/stack.go | 324 ++ .../gogo/protobuf/gogoproto/LICENSE | 36 + .../github.com/gogo/protobuf/gogoproto/doc.go | 169 + .../gogo/protobuf/gogoproto/gogo.pb.go | 817 ++++ .../gogo/protobuf/gogoproto/helper.go | 358 ++ .../protoc-gen-gogo/descriptor/LICENSE | 36 + .../protoc-gen-gogo/descriptor/descriptor.go | 118 + .../descriptor/descriptor.pb.go | 2806 +++++++++++++ .../descriptor/descriptor_gostring.gen.go | 744 ++++ .../protoc-gen-gogo/descriptor/helper.go | 390 ++ .../github.com/golang/protobuf/jsonpb/LICENSE | 28 + .../golang/protobuf/jsonpb/jsonpb.go | 1265 ++++++ .../jsonpb_test_proto/more_test_objects.pb.go | 368 ++ .../jsonpb_test_proto/test_objects.pb.go | 1349 +++++++ .../grpc-ecosystem/go-grpc-middleware/LICENSE | 201 + .../go-grpc-middleware/auth/auth.go | 67 + .../go-grpc-middleware/auth/doc.go | 20 + .../go-grpc-middleware/auth/metadata.go | 38 + .../go-grpc-middleware/chain.go | 183 + .../grpc-ecosystem/go-grpc-middleware/doc.go | 69 + .../go-grpc-middleware/logging/common.go | 35 + .../go-grpc-middleware/logging/doc.go | 35 + .../logging/logrus/client_interceptors.go | 65 + .../logging/logrus/context.go | 19 + .../logging/logrus/ctxlogrus/context.go | 65 + .../logging/logrus/ctxlogrus/doc.go | 14 + .../logging/logrus/ctxlogrus/noop.go | 16 + .../go-grpc-middleware/logging/logrus/doc.go | 67 + .../logging/logrus/grpclogger.go | 15 + .../logging/logrus/options.go | 185 + .../logging/logrus/payload_interceptors.go | 144 + .../logging/logrus/server_interceptors.go | 129 + .../logging/zap/client_interceptors.go | 64 + .../go-grpc-middleware/logging/zap/context.go | 20 + .../logging/zap/ctxzap/context.go | 64 + .../logging/zap/ctxzap/doc.go | 14 + .../go-grpc-middleware/logging/zap/doc.go | 74 + .../logging/zap/grpclogger.go | 46 + .../go-grpc-middleware/logging/zap/options.go | 184 + .../logging/zap/payload_interceptors.go | 149 + .../logging/zap/server_interceptors.go | 96 + .../go-grpc-middleware/recovery/doc.go | 15 + .../recovery/interceptors.go | 48 + .../go-grpc-middleware/recovery/options.go | 32 + .../go-grpc-middleware/retry/backoff.go | 26 + .../go-grpc-middleware/retry/doc.go | 25 + .../go-grpc-middleware/retry/options.go | 120 + .../go-grpc-middleware/retry/retry.go | 296 ++ .../testing/gogotestproto/fields.pb.go | 163 + .../testing/interceptor_suite.go | 111 + .../testing/mutex_readerwriter.go | 31 + .../go-grpc-middleware/testing/pingservice.go | 71 + .../testproto/test.manual_extractfields.pb.go | 8 + .../testproto/test.manual_validator.pb.go | 12 + .../testing/testproto/test.pb.go | 394 ++ .../opentracing/client_interceptors.go | 142 + .../tracing/opentracing/doc.go | 22 + .../tracing/opentracing/id_extract.go | 50 + .../tracing/opentracing/metadata.go | 56 + .../tracing/opentracing/options.go | 55 + .../opentracing/server_interceptors.go | 86 + .../util/backoffutils/backoff.go | 23 + .../go-grpc-middleware/util/metautils/doc.go | 19 + .../util/metautils/nicemd.go | 126 + .../util/metautils/single_key.go | 22 + .../go-grpc-middleware/validator/doc.go | 45 + .../go-grpc-middleware/validator/validator.go | 57 + .../go-grpc-middleware/wrappers.go | 29 + .../grpc-opentracing/go/otgrpc/LICENSE | 27 + .../grpc-opentracing/go/otgrpc/client.go | 239 ++ .../grpc-opentracing/go/otgrpc/errors.go | 69 + .../grpc-opentracing/go/otgrpc/options.go | 76 + .../grpc-opentracing/go/otgrpc/package.go | 5 + .../grpc-opentracing/go/otgrpc/server.go | 141 + .../grpc-opentracing/go/otgrpc/shared.go | 42 + .../go/otgrpc/test/otgrpc_testing/test.pb.go | 357 ++ .../influxdata/influxdb/client/v2/LICENSE | 20 + .../influxdata/influxdb/client/v2/client.go | 662 ++++ .../influxdata/influxdb/client/v2/udp.go | 112 + .../influxdata/influxdb/models/LICENSE | 20 + .../influxdata/influxdb/models/consistency.go | 48 + .../influxdata/influxdb/models/inline_fnv.go | 32 + .../influxdb/models/inline_strconv_parse.go | 44 + .../influxdata/influxdb/models/points.go | 2455 ++++++++++++ .../influxdata/influxdb/models/rows.go | 62 + .../influxdata/influxdb/models/statistic.go | 42 + .../influxdata/influxdb/models/time.go | 74 + .../influxdb/models/uint_support.go | 7 + .../influxdata/influxdb/pkg/escape/LICENSE | 20 + .../influxdata/influxdb/pkg/escape/bytes.go | 115 + .../influxdata/influxdb/pkg/escape/strings.go | 21 + .../julienschmidt/httprouter/LICENSE | 24 + .../julienschmidt/httprouter/params_go17.go | 38 + .../julienschmidt/httprouter/params_legacy.go | 16 + .../julienschmidt/httprouter/path.go | 123 + .../julienschmidt/httprouter/router.go | 399 ++ .../julienschmidt/httprouter/tree.go | 656 +++ vendor/github.com/kr/logfmt/decode.go | 184 + vendor/github.com/kr/logfmt/scanner.go | 149 + vendor/github.com/kr/logfmt/unquote.go | 149 + .../prometheus/LICENSE | 201 + .../prometheus/collector.go | 75 + .../prometheus/counter.go | 277 ++ .../prometheus/desc.go | 188 + .../prometheus/doc.go | 191 + .../prometheus/expvar_collector.go | 119 + .../prometheus/fnv.go | 29 + .../prometheus/gauge.go | 286 ++ .../prometheus/go_collector.go | 284 ++ .../prometheus/graphite/bridge.go | 280 ++ .../prometheus/histogram.go | 505 +++ .../prometheus/http.go | 512 +++ .../prometheus/labels.go | 57 + .../prometheus/metric.go | 144 + .../prometheus/observer.go | 52 + .../prometheus/process_collector.go | 139 + .../prometheus/promauto/auto.go | 223 ++ .../prometheus/promhttp/delegator.go | 199 + .../prometheus/promhttp/delegator_1_8.go | 181 + .../prometheus/promhttp/delegator_pre_1_8.go | 44 + .../prometheus/promhttp/http.go | 311 ++ .../prometheus/promhttp/instrument_client.go | 97 + .../promhttp/instrument_client_1_8.go | 144 + .../prometheus/promhttp/instrument_server.go | 447 +++ .../prometheus/push/deprecated.go | 172 + .../prometheus/push/push.go | 236 ++ .../prometheus/registry.go | 807 ++++ .../prometheus/summary.go | 609 +++ .../prometheus/timer.go | 51 + .../prometheus/untyped.go | 42 + .../prometheus/value.go | 158 + .../prometheus/vec.go | 472 +++ .../mwitkow/go-grpc-middleware/LICENSE | 201 + .../mwitkow/go-grpc-middleware/auth/auth.go | 67 + .../mwitkow/go-grpc-middleware/auth/doc.go | 20 + .../go-grpc-middleware/auth/metadata.go | 38 + .../mwitkow/go-grpc-middleware/chain.go | 183 + .../mwitkow/go-grpc-middleware/doc.go | 69 + .../go-grpc-middleware/logging/common.go | 35 + .../mwitkow/go-grpc-middleware/logging/doc.go | 35 + .../logging/logrus/client_interceptors.go | 65 + .../logging/logrus/context.go | 19 + .../logging/logrus/ctxlogrus/context.go | 65 + .../logging/logrus/ctxlogrus/doc.go | 14 + .../logging/logrus/ctxlogrus/noop.go | 16 + .../go-grpc-middleware/logging/logrus/doc.go | 67 + .../logging/logrus/grpclogger.go | 15 + .../logging/logrus/options.go | 185 + .../logging/logrus/payload_interceptors.go | 144 + .../logging/logrus/server_interceptors.go | 129 + .../logging/zap/client_interceptors.go | 64 + .../go-grpc-middleware/logging/zap/context.go | 20 + .../logging/zap/ctxzap/context.go | 64 + .../logging/zap/ctxzap/doc.go | 14 + .../go-grpc-middleware/logging/zap/doc.go | 74 + .../logging/zap/grpclogger.go | 46 + .../go-grpc-middleware/logging/zap/options.go | 184 + .../logging/zap/payload_interceptors.go | 149 + .../logging/zap/server_interceptors.go | 96 + .../go-grpc-middleware/recovery/doc.go | 15 + .../recovery/interceptors.go | 48 + .../go-grpc-middleware/recovery/options.go | 32 + .../go-grpc-middleware/retry/backoff.go | 26 + .../mwitkow/go-grpc-middleware/retry/doc.go | 25 + .../go-grpc-middleware/retry/options.go | 120 + .../mwitkow/go-grpc-middleware/retry/retry.go | 296 ++ .../testing/gogotestproto/fields.pb.go | 163 + .../testing/interceptor_suite.go | 111 + .../testing/mutex_readerwriter.go | 31 + .../go-grpc-middleware/testing/pingservice.go | 71 + .../testproto/test.manual_extractfields.pb.go | 8 + .../testproto/test.manual_validator.pb.go | 12 + .../testing/testproto/test.pb.go | 394 ++ .../opentracing/client_interceptors.go | 142 + .../tracing/opentracing/doc.go | 22 + .../tracing/opentracing/id_extract.go | 50 + .../tracing/opentracing/metadata.go | 56 + .../tracing/opentracing/options.go | 55 + .../opentracing/server_interceptors.go | 86 + .../util/backoffutils/backoff.go | 23 + .../go-grpc-middleware/util/metautils/doc.go | 19 + .../util/metautils/nicemd.go | 126 + .../util/metautils/single_key.go | 22 + .../go-grpc-middleware/validator/doc.go | 45 + .../go-grpc-middleware/validator/validator.go | 57 + .../mwitkow/go-grpc-middleware/wrappers.go | 29 + .../go-stdlib/nethttp/LICENSE | 27 + .../go-stdlib/nethttp/client.go | 301 ++ .../go-stdlib/nethttp/doc.go | 3 + .../go-stdlib/nethttp/server.go | 119 + .../performancecopilot/speed/LICENSE | 21 + .../speed/bytewriter/bytewriter.go | 155 + .../speed/bytewriter/memorymappedwriter.go | 79 + .../speed/bytewriter/writer.go | 50 + .../performancecopilot/speed/client.go | 697 ++++ .../performancecopilot/speed/config.go | 56 + .../speed/countunit_string.go | 17 + .../speed/examples/acme/main.go | 199 + .../speed/examples/basic_histogram/main.go | 38 + .../speed/examples/download/main.go | 83 + .../speed/examples/http_counter/server.go | 50 + .../speed/examples/instance_string/main.go | 46 + .../speed/examples/runtime/main.go | 142 + .../speed/examples/simple/main.go | 37 + .../examples/simple_string_metric/main.go | 43 + .../speed/examples/singleton_counter/main.go | 44 + .../speed/examples/singleton_string/main.go | 39 + .../performancecopilot/speed/instance.go | 31 + .../speed/instance_domain.go | 124 + .../performancecopilot/speed/metrics.go | 1577 ++++++++ .../speed/metricsemantics_string.go | 27 + .../speed/metrictype_string.go | 16 + .../speed/mmvdump/cmd/mmvdump/main.go | 35 + .../speed/mmvdump/mmvdump.go | 345 ++ .../performancecopilot/speed/mmvdump/pcp.go | 395 ++ .../speed/mmvdump/semantics_string.go | 16 + .../speed/mmvdump/toctype_string.go | 17 + .../speed/mmvdump/type_string.go | 27 + .../speed/mmvdump/writer.go | 274 ++ .../speed/mmvflag_string.go | 27 + .../performancecopilot/speed/registry.go | 333 ++ .../speed/spaceunit_string.go | 46 + .../performancecopilot/speed/speed.go | 57 + .../speed/timeunit_string.go | 42 + .../github.com/codahale/hdrhistogram/hdr.go | 564 +++ .../codahale/hdrhistogram/window.go | 45 + .../vendor/github.com/edsrzf/mmap-go/mmap.go | 116 + .../github.com/edsrzf/mmap-go/mmap_unix.go | 67 + .../github.com/edsrzf/mmap-go/mmap_windows.go | 125 + .../github.com/edsrzf/mmap-go/msync_netbsd.go | 8 + .../github.com/edsrzf/mmap-go/msync_unix.go | 14 + .../vendor/github.com/pkg/errors/errors.go | 269 ++ .../vendor/github.com/pkg/errors/stack.go | 178 + vendor/github.com/pkg/errors/LICENSE | 23 + vendor/github.com/pkg/errors/errors.go | 269 ++ vendor/github.com/pkg/errors/stack.go | 147 + .../github.com/sercand/kuberesolver/LICENSE | 202 + .../sercand/kuberesolver/builder.go | 255 ++ .../sercand/kuberesolver/kubernetes.go | 137 + .../github.com/sercand/kuberesolver/models.go | 50 + .../github.com/sercand/kuberesolver/stream.go | 105 + .../github.com/sercand/kuberesolver/util.go | 35 + vendor/github.com/sirupsen/logrus/LICENSE | 21 + vendor/github.com/sirupsen/logrus/alt_exit.go | 64 + vendor/github.com/sirupsen/logrus/doc.go | 26 + vendor/github.com/sirupsen/logrus/entry.go | 300 ++ vendor/github.com/sirupsen/logrus/exported.go | 201 + .../github.com/sirupsen/logrus/formatter.go | 51 + vendor/github.com/sirupsen/logrus/hooks.go | 34 + .../sirupsen/logrus/hooks/syslog/syslog.go | 55 + .../sirupsen/logrus/hooks/test/test.go | 92 + .../sirupsen/logrus/json_formatter.go | 89 + vendor/github.com/sirupsen/logrus/logger.go | 337 ++ vendor/github.com/sirupsen/logrus/logrus.go | 143 + .../sirupsen/logrus/terminal_bsd.go | 10 + .../logrus/terminal_check_appengine.go | 11 + .../logrus/terminal_check_notappengine.go | 19 + .../sirupsen/logrus/terminal_linux.go | 14 + .../sirupsen/logrus/text_formatter.go | 195 + vendor/github.com/sirupsen/logrus/writer.go | 62 + vendor/github.com/stretchr/objx/LICENSE | 22 + vendor/github.com/stretchr/objx/accessors.go | 119 + .../github.com/stretchr/objx/conversions.go | 218 + vendor/github.com/stretchr/objx/doc.go | 66 + vendor/github.com/stretchr/objx/map.go | 228 ++ vendor/github.com/stretchr/objx/mutations.go | 77 + vendor/github.com/stretchr/objx/security.go | 12 + vendor/github.com/stretchr/objx/tests.go | 17 + .../github.com/stretchr/objx/type_specific.go | 317 ++ .../stretchr/objx/type_specific_codegen.go | 2251 +++++++++++ vendor/github.com/stretchr/objx/value.go | 159 + .../github.com/davecgh/go-spew/spew/bypass.go | 152 + .../davecgh/go-spew/spew/bypasssafe.go | 38 + .../github.com/davecgh/go-spew/spew/common.go | 341 ++ .../github.com/davecgh/go-spew/spew/config.go | 306 ++ .../github.com/davecgh/go-spew/spew/doc.go | 211 + .../github.com/davecgh/go-spew/spew/dump.go | 509 +++ .../github.com/davecgh/go-spew/spew/format.go | 419 ++ .../github.com/davecgh/go-spew/spew/spew.go | 148 + .../pmezard/go-difflib/difflib/difflib.go | 772 ++++ .../testify/assert/assertion_format.go | 484 +++ .../testify/assert/assertion_forward.go | 956 +++++ .../stretchr/testify/assert/assertions.go | 1394 +++++++ .../github.com/stretchr/testify/assert/doc.go | 45 + .../stretchr/testify/assert/errors.go | 10 + .../testify/assert/forward_assertions.go | 16 + .../testify/assert/http_assertions.go | 143 + .../stretchr/testify/require/doc.go | 28 + .../testify/require/forward_requirements.go | 16 + .../stretchr/testify/require/require.go | 1227 ++++++ .../testify/require/require_forward.go | 957 +++++ .../stretchr/testify/require/requirements.go | 29 + .../stretchr/testify/require/LICENSE | 22 + .../stretchr/testify/require/doc.go | 28 + .../testify/require/forward_requirements.go | 16 + .../stretchr/testify/require/require.go | 1227 ++++++ .../testify/require/require_forward.go | 957 +++++ .../stretchr/testify/require/requirements.go | 29 + .../github.com/stretchr/testify/suite/LICENSE | 22 + .../github.com/stretchr/testify/suite/doc.go | 65 + .../stretchr/testify/suite/interfaces.go | 46 + .../stretchr/testify/suite/suite.go | 136 + vendor/github.com/uber-go/tally/LICENSE | 21 + .../github.com/uber-go/tally/example/main.go | 119 + vendor/github.com/uber-go/tally/histogram.go | 318 ++ .../uber-go/tally/instrument/call.go | 67 + .../uber-go/tally/instrument/types.go | 31 + vendor/github.com/uber-go/tally/key_gen.go | 111 + vendor/github.com/uber-go/tally/m3/config.go | 65 + .../buffered_read_transport.go | 79 + .../m3/customtransports/m3_calc_transport.go | 86 + .../uber-go/tally/m3/example/local_server.go | 110 + .../uber-go/tally/m3/example/m3_main.go | 163 + .../github.com/uber-go/tally/m3/reporter.go | 620 +++ .../uber-go/tally/m3/resource_pool.go | 224 ++ .../github.com/uber-go/tally/m3/sanitize.go | 44 + .../uber-go/tally/m3/thrift/constants.go | 38 + .../github.com/uber-go/tally/m3/thrift/m3.go | 265 ++ .../uber-go/tally/m3/thrift/ttypes.go | 1149 ++++++ .../tally/m3/thriftudp/multitransport.go | 120 + .../uber-go/tally/m3/thriftudp/transport.go | 152 + .../uber-go/tally/multi/reporter.go | 272 ++ vendor/github.com/uber-go/tally/pool.go | 63 + .../uber-go/tally/prometheus/config.go | 145 + .../prometheus/example/prometheus_main.go | 90 + .../uber-go/tally/prometheus/reporter.go | 582 +++ .../uber-go/tally/prometheus/sanitize.go | 44 + vendor/github.com/uber-go/tally/reporter.go | 140 + vendor/github.com/uber-go/tally/sanitize.go | 176 + vendor/github.com/uber-go/tally/scope.go | 752 ++++ vendor/github.com/uber-go/tally/stats.go | 475 +++ .../tally/statsd/example/statsd_main.go | 86 + .../uber-go/tally/statsd/reporter.go | 156 + vendor/github.com/uber-go/tally/types.go | 152 + .../github.com/uber/jaeger-client-go/LICENSE | 201 + .../uber/jaeger-client-go/baggage_setter.go | 77 + .../uber/jaeger-client-go/config/config.go | 394 ++ .../jaeger-client-go/config/config_env.go | 232 ++ .../uber/jaeger-client-go/config/options.go | 148 + .../uber/jaeger-client-go/constants.go | 88 + .../uber/jaeger-client-go/context.go | 258 ++ .../uber/jaeger-client-go/contrib_observer.go | 56 + .../crossdock/client/client.go | 107 + .../crossdock/client/constants.go | 42 + .../crossdock/client/trace.go | 163 + .../crossdock/common/constants.go | 26 + .../jaeger-client-go/crossdock/common/json.go | 73 + .../crossdock/endtoend/handler.go | 156 + .../jaeger-client-go/crossdock/log/logger.go | 29 + .../uber/jaeger-client-go/crossdock/main.go | 64 + .../crossdock/server/constants.go | 25 + .../crossdock/server/server.go | 150 + .../crossdock/server/trace.go | 99 + .../crossdock/thrift/tracetest/constants.go | 18 + .../thrift/tracetest/tracedservice.go | 747 ++++ .../crossdock/thrift/tracetest/ttypes.go | 1103 ++++++ .../github.com/uber/jaeger-client-go/doc.go | 24 + .../uber/jaeger-client-go/header.go | 64 + .../internal/baggage/remote/options.go | 101 + .../baggage/remote/restriction_manager.go | 157 + .../internal/baggage/restriction_manager.go | 71 + .../jaeger-client-go/internal/spanlog/json.go | 81 + .../internal/throttler/remote/options.go | 99 + .../internal/throttler/remote/throttler.go | 216 + .../internal/throttler/throttler.go | 32 + .../uber/jaeger-client-go/interop.go | 55 + .../uber/jaeger-client-go/jaeger_tag.go | 84 + .../jaeger-client-go/jaeger_thrift_span.go | 179 + .../uber/jaeger-client-go/log/logger.go | 90 + .../uber/jaeger-client-go/log/zap/field.go | 60 + .../uber/jaeger-client-go/log/zap/logger.go | 39 + .../uber/jaeger-client-go/logger.go | 53 + .../uber/jaeger-client-go/metrics.go | 107 + .../uber/jaeger-client-go/observer.go | 88 + .../uber/jaeger-client-go/process.go | 29 + .../uber/jaeger-client-go/propagation.go | 300 ++ .../uber/jaeger-client-go/reference.go | 23 + .../uber/jaeger-client-go/reporter.go | 289 ++ .../uber/jaeger-client-go/reporter_options.go | 69 + .../uber/jaeger-client-go/rpcmetrics/doc.go | 16 + .../jaeger-client-go/rpcmetrics/endpoints.go | 63 + .../jaeger-client-go/rpcmetrics/metrics.go | 124 + .../jaeger-client-go/rpcmetrics/normalizer.go | 101 + .../jaeger-client-go/rpcmetrics/observer.go | 171 + .../uber/jaeger-client-go/sampler.go | 556 +++ .../uber/jaeger-client-go/sampler_options.go | 81 + .../github.com/uber/jaeger-client-go/span.go | 249 ++ .../jaeger-client-go/testutils/mock_agent.go | 189 + .../testutils/sampling_manager.go | 53 + .../testutils/udp_transport.go | 106 + .../thrift-gen/agent/agent.go | 411 ++ .../thrift-gen/agent/constants.go | 23 + .../thrift-gen/agent/ttypes.go | 21 + .../baggage/baggagerestrictionmanager.go | 435 ++ .../thrift-gen/baggage/constants.go | 18 + .../thrift-gen/baggage/ttypes.go | 154 + .../thrift-gen/jaeger/agent.go | 242 ++ .../thrift-gen/jaeger/constants.go | 18 + .../thrift-gen/jaeger/ttypes.go | 1838 +++++++++ .../thrift-gen/sampling/constants.go | 18 + .../thrift-gen/sampling/samplingmanager.go | 410 ++ .../thrift-gen/sampling/ttypes.go | 873 ++++ .../thrift-gen/zipkincore/constants.go | 32 + .../thrift-gen/zipkincore/ttypes.go | 1247 ++++++ .../thrift-gen/zipkincore/zipkincollector.go | 446 +++ .../thrift/application_exception.go | 142 + .../thrift/binary_protocol.go | 514 +++ .../thrift/compact_protocol.go | 815 ++++ .../uber/jaeger-client-go/thrift/exception.go | 44 + .../jaeger-client-go/thrift/memory_buffer.go | 79 + .../jaeger-client-go/thrift/messagetype.go | 31 + .../uber/jaeger-client-go/thrift/numeric.go | 164 + .../uber/jaeger-client-go/thrift/processor.go | 30 + .../uber/jaeger-client-go/thrift/protocol.go | 175 + .../thrift/protocol_exception.go | 78 + .../thrift/protocol_factory.go | 25 + .../jaeger-client-go/thrift/rich_transport.go | 69 + .../jaeger-client-go/thrift/serializer.go | 75 + .../thrift/simple_json_protocol.go | 1337 +++++++ .../uber/jaeger-client-go/thrift/transport.go | 68 + .../thrift/transport_exception.go | 90 + .../thrift/transport_factory.go | 39 + .../uber/jaeger-client-go/thrift/type.go | 69 + .../uber/jaeger-client-go/tracer.go | 431 ++ .../uber/jaeger-client-go/tracer_options.go | 159 + .../uber/jaeger-client-go/transport.go | 38 + .../uber/jaeger-client-go/transport/doc.go | 23 + .../uber/jaeger-client-go/transport/http.go | 155 + .../jaeger-client-go/transport/zipkin/doc.go | 17 + .../jaeger-client-go/transport/zipkin/http.go | 166 + .../uber/jaeger-client-go/transport_udp.go | 131 + .../uber/jaeger-client-go/utils/http_json.go | 54 + .../uber/jaeger-client-go/utils/localip.go | 84 + .../uber/jaeger-client-go/utils/rand.go | 46 + .../jaeger-client-go/utils/rate_limiter.go | 77 + .../uber/jaeger-client-go/utils/udp_client.go | 98 + .../uber/jaeger-client-go/utils/utils.go | 87 + .../uber/jaeger-client-go/zipkin.go | 76 + .../uber/jaeger-client-go/zipkin/doc.go | 16 + .../jaeger-client-go/zipkin/propagation.go | 95 + .../jaeger-client-go/zipkin_thrift_span.go | 322 ++ .../uber/jaeger-lib/metrics/LICENSE | 201 + .../uber/jaeger-lib/metrics/adapters/cache.go | 69 + .../jaeger-lib/metrics/adapters/factory.go | 123 + .../jaeger-lib/metrics/adapters/tagless.go | 61 + .../uber/jaeger-lib/metrics/counter.go | 28 + .../uber/jaeger-lib/metrics/expvar/factory.go | 49 + .../uber/jaeger-lib/metrics/factory.go | 35 + .../uber/jaeger-lib/metrics/gauge.go | 28 + .../metrics/go-kit/expvar/factory.go | 58 + .../uber/jaeger-lib/metrics/go-kit/factory.go | 161 + .../metrics/go-kit/influx/factory.go | 49 + .../uber/jaeger-lib/metrics/go-kit/metrics.go | 66 + .../metrics/go-kit/prometheus/factory.go | 93 + .../uber/jaeger-lib/metrics/local.go | 337 ++ .../uber/jaeger-lib/metrics/metrics.go | 85 + .../uber/jaeger-lib/metrics/multi/multi.go | 107 + .../jaeger-lib/metrics/prometheus/cache.go | 86 + .../jaeger-lib/metrics/prometheus/factory.go | 246 ++ .../uber/jaeger-lib/metrics/stopwatch.go | 43 + .../uber/jaeger-lib/metrics/tally/factory.go | 63 + .../uber/jaeger-lib/metrics/tally/metrics.go | 66 + .../jaeger-lib/metrics/testutils/testutils.go | 55 + .../uber/jaeger-lib/metrics/timer.go | 33 + .../weaveworks/common/backoff/backoff.go | 2 +- .../weaveworks/common/http/client/client.go | 51 +- .../weaveworks/common/httpgrpc/httpgrpc.go | 2 +- .../weaveworks/common/httpgrpc/httpgrpc.pb.go | 47 +- .../common/httpgrpc/server/server.go | 21 +- .../common/instrument/instrument.go | 192 +- .../weaveworks/common/logging/dedupe.go | 137 + .../weaveworks/common/logging/global.go | 58 + .../weaveworks/common/logging/gokit.go | 66 + .../weaveworks/common/logging/interface.go | 24 + .../weaveworks/common/logging/level.go | 64 + .../weaveworks/common/logging/logging.go | 168 +- .../weaveworks/common/logging/logrus.go | 74 + .../weaveworks/common/logging/noop.go | 23 + .../weaveworks/common/middleware/grpc_auth.go | 33 + .../common/middleware/grpc_instrumentation.go | 23 +- .../common/middleware/grpc_logging.go | 38 +- .../common/middleware/instrument.go | 31 + .../weaveworks/common/middleware/logging.go | 75 +- .../common/middleware/path_rewrite.go | 2 +- .../weaveworks/common/middleware/response.go | 84 + .../weaveworks/common/sanitize/sanitize.go | 2 +- .../common/server/fake_server.pb.go | 8 +- .../weaveworks/common/server/server.go | 73 +- .../weaveworks/common/signals/signals.go | 13 +- .../weaveworks/common/tracing/tracing.go | 41 + .../github.com/weaveworks/common/user/grpc.go | 6 +- .../github.com/weaveworks/common/user/http.go | 21 +- .../weaveworks/common/user/logging.go | 15 +- vendor/github.com/weaveworks/promrus/LICENSE | 201 + .../github.com/weaveworks/promrus/promrus.go | 61 + .../beorn7/perks/histogram/histogram.go | 108 + .../beorn7/perks/quantile/stream.go | 292 ++ .../github.com/beorn7/perks/topk/topk.go | 90 + .../github.com/davecgh/go-spew/spew/bypass.go | 152 + .../davecgh/go-spew/spew/bypasssafe.go | 38 + .../github.com/davecgh/go-spew/spew/common.go | 341 ++ .../github.com/davecgh/go-spew/spew/config.go | 306 ++ .../github.com/davecgh/go-spew/spew/doc.go | 211 + .../github.com/davecgh/go-spew/spew/dump.go | 509 +++ .../github.com/davecgh/go-spew/spew/format.go | 419 ++ .../github.com/davecgh/go-spew/spew/spew.go | 148 + .../golang/protobuf/descriptor/descriptor.go | 93 + .../golang/protobuf/jsonpb/jsonpb.go | 1083 +++++ .../jsonpb_test_proto/more_test_objects.pb.go | 266 ++ .../jsonpb_test_proto/test_objects.pb.go | 852 ++++ .../github.com/golang/protobuf/proto/clone.go | 229 ++ .../golang/protobuf/proto/decode.go | 970 +++++ .../golang/protobuf/proto/encode.go | 1362 +++++++ .../github.com/golang/protobuf/proto/equal.go | 300 ++ .../golang/protobuf/proto/extensions.go | 587 +++ .../github.com/golang/protobuf/proto/lib.go | 897 +++++ .../golang/protobuf/proto/message_set.go | 311 ++ .../golang/protobuf/proto/pointer_reflect.go | 484 +++ .../golang/protobuf/proto/pointer_unsafe.go | 270 ++ .../golang/protobuf/proto/properties.go | 872 ++++ .../protobuf/proto/proto3_proto/proto3.pb.go | 347 ++ .../github.com/golang/protobuf/proto/text.go | 854 ++++ .../golang/protobuf/proto/text_parser.go | 895 +++++ .../protoc-gen-go/descriptor/descriptor.pb.go | 2215 +++++++++++ .../golang/protobuf/protoc-gen-go/doc.go | 51 + .../protoc-gen-go/generator/generator.go | 2866 ++++++++++++++ .../protobuf/protoc-gen-go/grpc/grpc.go | 463 +++ .../protobuf/protoc-gen-go/link_grpc.go | 34 + .../golang/protobuf/protoc-gen-go/main.go | 98 + .../protoc-gen-go/plugin/plugin.pb.go | 293 ++ .../github.com/golang/protobuf/ptypes/any.go | 139 + .../golang/protobuf/ptypes/any/any.pb.go | 178 + .../github.com/golang/protobuf/ptypes/doc.go | 35 + .../golang/protobuf/ptypes/duration.go | 102 + .../protobuf/ptypes/duration/duration.pb.go | 144 + .../golang/protobuf/ptypes/empty/empty.pb.go | 66 + .../protobuf/ptypes/struct/struct.pb.go | 380 ++ .../golang/protobuf/ptypes/timestamp.go | 134 + .../protobuf/ptypes/timestamp/timestamp.pb.go | 160 + .../protobuf/ptypes/wrappers/wrappers.pb.go | 260 ++ .../golang_protobuf_extensions/ext/moved.go | 2 + .../pbtest/deleted.go | 2 + .../pbutil/decode.go | 75 + .../golang_protobuf_extensions/pbutil/doc.go | 16 + .../pbutil/encode.go | 46 + .../pmezard/go-difflib/difflib/difflib.go | 772 ++++ .../client_golang/api/prometheus/api.go | 345 ++ .../client_golang/examples/random/main.go | 103 + .../client_golang/examples/simple/main.go | 30 + .../client_golang/prometheus/collector.go | 75 + .../client_golang/prometheus/counter.go | 172 + .../client_golang/prometheus/desc.go | 205 + .../client_golang/prometheus/doc.go | 181 + .../prometheus/expvar_collector.go | 119 + .../client_golang/prometheus/fnv.go | 29 + .../client_golang/prometheus/gauge.go | 140 + .../client_golang/prometheus/go_collector.go | 263 ++ .../client_golang/prometheus/histogram.go | 444 +++ .../client_golang/prometheus/http.go | 490 +++ .../client_golang/prometheus/metric.go | 166 + .../prometheus/process_collector.go | 142 + .../client_golang/prometheus/promhttp/http.go | 201 + .../client_golang/prometheus/push/push.go | 172 + .../client_golang/prometheus/registry.go | 806 ++++ .../client_golang/prometheus/summary.go | 534 +++ .../client_golang/prometheus/untyped.go | 138 + .../client_golang/prometheus/value.go | 234 ++ .../client_golang/prometheus/vec.go | 404 ++ .../prometheus/client_model/cpp/metrics.pb.cc | 3380 ++++++++++++++++ .../prometheus/client_model/cpp/metrics.pb.h | 2072 ++++++++++ .../prometheus/client_model/go/metrics.pb.go | 364 ++ .../prometheus/common/config/config.go | 47 + .../prometheus/common/config/http_config.go | 279 ++ .../prometheus/common/expfmt/decode.go | 429 ++ .../prometheus/common/expfmt/encode.go | 88 + .../prometheus/common/expfmt/expfmt.go | 38 + .../prometheus/common/expfmt/fuzz.go | 36 + .../prometheus/common/expfmt/text_create.go | 303 ++ .../prometheus/common/expfmt/text_parse.go | 757 ++++ .../bitbucket.org/ww/goautoneg/autoneg.go | 162 + .../common/log/eventlog_formatter.go | 89 + .../github.com/prometheus/common/log/log.go | 359 ++ .../prometheus/common/log/syslog_formatter.go | 126 + .../prometheus/common/model/alert.go | 136 + .../prometheus/common/model/fingerprinting.go | 105 + .../github.com/prometheus/common/model/fnv.go | 42 + .../prometheus/common/model/labels.go | 210 + .../prometheus/common/model/labelset.go | 169 + .../prometheus/common/model/metric.go | 103 + .../prometheus/common/model/model.go | 16 + .../prometheus/common/model/signature.go | 144 + .../prometheus/common/model/silence.go | 106 + .../prometheus/common/model/time.go | 261 ++ .../prometheus/common/model/value.go | 416 ++ .../prometheus/common/promlog/flag/flag.go | 33 + .../prometheus/common/promlog/log.go | 63 + .../prometheus/common/route/route.go | 100 + .../prometheus/common/version/info.go | 89 + .../prometheus/procfs/bcache/bcache.go | 84 + .../prometheus/procfs/bcache/get.go | 330 ++ .../github.com/prometheus/procfs/buddyinfo.go | 95 + .../github.com/prometheus/procfs/doc.go | 45 + .../vendor/github.com/prometheus/procfs/fs.go | 46 + .../github.com/prometheus/procfs/ipvs.go | 246 ++ .../github.com/prometheus/procfs/mdstat.go | 138 + .../prometheus/procfs/mountstats.go | 556 +++ .../github.com/prometheus/procfs/proc.go | 224 ++ .../github.com/prometheus/procfs/proc_io.go | 55 + .../prometheus/procfs/proc_limits.go | 137 + .../github.com/prometheus/procfs/proc_stat.go | 175 + .../github.com/prometheus/procfs/stat.go | 219 + .../github.com/prometheus/procfs/sysfs/doc.go | 16 + .../github.com/prometheus/procfs/sysfs/fs.go | 108 + .../github.com/prometheus/procfs/xfrm.go | 187 + .../github.com/prometheus/procfs/xfs/parse.go | 359 ++ .../github.com/prometheus/procfs/xfs/xfs.go | 163 + .../github.com/sirupsen/logrus/alt_exit.go | 64 + .../vendor/github.com/sirupsen/logrus/doc.go | 26 + .../github.com/sirupsen/logrus/entry.go | 276 ++ .../github.com/sirupsen/logrus/exported.go | 193 + .../github.com/sirupsen/logrus/formatter.go | 45 + .../github.com/sirupsen/logrus/hooks.go | 34 + .../sirupsen/logrus/hooks/syslog/syslog.go | 55 + .../sirupsen/logrus/hooks/test/test.go | 95 + .../sirupsen/logrus/json_formatter.go | 79 + .../github.com/sirupsen/logrus/logger.go | 317 ++ .../github.com/sirupsen/logrus/logrus.go | 143 + .../sirupsen/logrus/terminal_bsd.go | 10 + .../sirupsen/logrus/terminal_linux.go | 14 + .../sirupsen/logrus/text_formatter.go | 191 + .../github.com/sirupsen/logrus/writer.go | 62 + .../testify/assert/assertion_forward.go | 387 ++ .../stretchr/testify/assert/assertions.go | 1052 +++++ .../github.com/stretchr/testify/assert/doc.go | 45 + .../stretchr/testify/assert/errors.go | 10 + .../testify/assert/forward_assertions.go | 16 + .../testify/assert/http_assertions.go | 106 + .../vendor/github.com/stretchr/testify/doc.go | 22 + .../github.com/stretchr/testify/http/doc.go | 2 + .../testify/http/test_response_writer.go | 49 + .../testify/http/test_round_tripper.go | 17 + .../github.com/stretchr/testify/mock/doc.go | 44 + .../github.com/stretchr/testify/mock/mock.go | 763 ++++ .../stretchr/testify/require/doc.go | 28 + .../testify/require/forward_requirements.go | 16 + .../stretchr/testify/require/require.go | 464 +++ .../testify/require/require_forward.go | 388 ++ .../stretchr/testify/require/requirements.go | 9 + .../github.com/stretchr/testify/suite/doc.go | 65 + .../stretchr/testify/suite/interfaces.go | 34 + .../stretchr/testify/suite/suite.go | 115 + .../vendor/golang.org/x/crypto/acme/acme.go | 1054 +++++ .../x/crypto/acme/autocert/autocert.go | 821 ++++ .../x/crypto/acme/autocert/cache.go | 130 + .../x/crypto/acme/autocert/listener.go | 160 + .../x/crypto/acme/autocert/renewal.go | 124 + .../vendor/golang.org/x/crypto/acme/jws.go | 153 + .../vendor/golang.org/x/crypto/acme/types.go | 329 ++ .../golang.org/x/crypto/bcrypt/base64.go | 35 + .../golang.org/x/crypto/bcrypt/bcrypt.go | 295 ++ .../golang.org/x/crypto/blake2b/blake2b.go | 207 + .../x/crypto/blake2b/blake2bAVX2_amd64.go | 43 + .../x/crypto/blake2b/blake2bAVX2_amd64.s | 762 ++++ .../x/crypto/blake2b/blake2b_amd64.go | 25 + .../x/crypto/blake2b/blake2b_amd64.s | 290 ++ .../x/crypto/blake2b/blake2b_generic.go | 179 + .../x/crypto/blake2b/blake2b_ref.go | 11 + .../golang.org/x/crypto/blake2b/blake2x.go | 177 + .../golang.org/x/crypto/blake2b/register.go | 32 + .../golang.org/x/crypto/blake2s/blake2s.go | 187 + .../x/crypto/blake2s/blake2s_386.go | 35 + .../golang.org/x/crypto/blake2s/blake2s_386.s | 460 +++ .../x/crypto/blake2s/blake2s_amd64.go | 40 + .../x/crypto/blake2s/blake2s_amd64.s | 463 +++ .../x/crypto/blake2s/blake2s_generic.go | 174 + .../x/crypto/blake2s/blake2s_ref.go | 17 + .../golang.org/x/crypto/blake2s/blake2x.go | 178 + .../golang.org/x/crypto/blake2s/register.go | 21 + .../golang.org/x/crypto/blowfish/block.go | 159 + .../golang.org/x/crypto/blowfish/cipher.go | 91 + .../golang.org/x/crypto/blowfish/const.go | 199 + .../vendor/golang.org/x/crypto/bn256/bn256.go | 404 ++ .../golang.org/x/crypto/bn256/constants.go | 44 + .../vendor/golang.org/x/crypto/bn256/curve.go | 278 ++ .../vendor/golang.org/x/crypto/bn256/gfp12.go | 200 + .../vendor/golang.org/x/crypto/bn256/gfp2.go | 219 + .../vendor/golang.org/x/crypto/bn256/gfp6.go | 296 ++ .../golang.org/x/crypto/bn256/optate.go | 395 ++ .../vendor/golang.org/x/crypto/bn256/twist.go | 249 ++ .../vendor/golang.org/x/crypto/cast5/cast5.go | 526 +++ .../chacha20poly1305/chacha20poly1305.go | 83 + .../chacha20poly1305_amd64.go | 127 + .../chacha20poly1305/chacha20poly1305_amd64.s | 2714 +++++++++++++ .../chacha20poly1305_generic.go | 70 + .../chacha20poly1305_noasm.go | 15 + .../internal/chacha20/chacha_generic.go | 198 + .../golang.org/x/crypto/cryptobyte/asn1.go | 732 ++++ .../x/crypto/cryptobyte/asn1/asn1.go | 46 + .../golang.org/x/crypto/cryptobyte/builder.go | 309 ++ .../golang.org/x/crypto/cryptobyte/string.go | 167 + .../x/crypto/curve25519/const_amd64.h | 8 + .../x/crypto/curve25519/const_amd64.s | 20 + .../x/crypto/curve25519/cswap_amd64.s | 65 + .../x/crypto/curve25519/curve25519.go | 834 ++++ .../golang.org/x/crypto/curve25519/doc.go | 23 + .../x/crypto/curve25519/freeze_amd64.s | 73 + .../x/crypto/curve25519/ladderstep_amd64.s | 1377 +++++++ .../x/crypto/curve25519/mont25519_amd64.go | 240 ++ .../x/crypto/curve25519/mul_amd64.s | 169 + .../x/crypto/curve25519/square_amd64.s | 132 + .../golang.org/x/crypto/ed25519/ed25519.go | 181 + .../ed25519/internal/edwards25519/const.go | 1422 +++++++ .../internal/edwards25519/edwards25519.go | 1771 +++++++++ .../vendor/golang.org/x/crypto/hkdf/hkdf.go | 75 + .../vendor/golang.org/x/crypto/md4/md4.go | 118 + .../golang.org/x/crypto/md4/md4block.go | 89 + .../golang.org/x/crypto/nacl/auth/auth.go | 58 + .../golang.org/x/crypto/nacl/box/box.go | 103 + .../x/crypto/nacl/secretbox/secretbox.go | 166 + .../vendor/golang.org/x/crypto/ocsp/ocsp.go | 778 ++++ .../x/crypto/openpgp/armor/armor.go | 219 + .../x/crypto/openpgp/armor/encode.go | 160 + .../x/crypto/openpgp/canonical_text.go | 59 + .../x/crypto/openpgp/clearsign/clearsign.go | 376 ++ .../x/crypto/openpgp/elgamal/elgamal.go | 122 + .../x/crypto/openpgp/errors/errors.go | 72 + .../golang.org/x/crypto/openpgp/keys.go | 637 +++ .../x/crypto/openpgp/packet/compressed.go | 123 + .../x/crypto/openpgp/packet/config.go | 91 + .../x/crypto/openpgp/packet/encrypted_key.go | 199 + .../x/crypto/openpgp/packet/literal.go | 89 + .../x/crypto/openpgp/packet/ocfb.go | 143 + .../openpgp/packet/one_pass_signature.go | 73 + .../x/crypto/openpgp/packet/opaque.go | 162 + .../x/crypto/openpgp/packet/packet.go | 537 +++ .../x/crypto/openpgp/packet/private_key.go | 380 ++ .../x/crypto/openpgp/packet/public_key.go | 748 ++++ .../x/crypto/openpgp/packet/public_key_v3.go | 279 ++ .../x/crypto/openpgp/packet/reader.go | 76 + .../x/crypto/openpgp/packet/signature.go | 731 ++++ .../x/crypto/openpgp/packet/signature_v3.go | 146 + .../openpgp/packet/symmetric_key_encrypted.go | 155 + .../openpgp/packet/symmetrically_encrypted.go | 290 ++ .../x/crypto/openpgp/packet/userattribute.go | 91 + .../x/crypto/openpgp/packet/userid.go | 160 + .../golang.org/x/crypto/openpgp/read.go | 442 +++ .../golang.org/x/crypto/openpgp/s2k/s2k.go | 273 ++ .../golang.org/x/crypto/openpgp/write.go | 378 ++ .../x/crypto/otr/libotr_test_helper.c | 197 + .../vendor/golang.org/x/crypto/otr/otr.go | 1415 +++++++ .../vendor/golang.org/x/crypto/otr/smp.go | 572 +++ .../golang.org/x/crypto/pbkdf2/pbkdf2.go | 77 + .../golang.org/x/crypto/pkcs12/bmp-string.go | 50 + .../golang.org/x/crypto/pkcs12/crypto.go | 131 + .../golang.org/x/crypto/pkcs12/errors.go | 23 + .../x/crypto/pkcs12/internal/rc2/rc2.go | 274 ++ .../vendor/golang.org/x/crypto/pkcs12/mac.go | 45 + .../golang.org/x/crypto/pkcs12/pbkdf.go | 170 + .../golang.org/x/crypto/pkcs12/pkcs12.go | 346 ++ .../golang.org/x/crypto/pkcs12/safebags.go | 57 + .../golang.org/x/crypto/poly1305/poly1305.go | 33 + .../golang.org/x/crypto/poly1305/sum_amd64.go | 22 + .../golang.org/x/crypto/poly1305/sum_amd64.s | 125 + .../golang.org/x/crypto/poly1305/sum_arm.go | 22 + .../golang.org/x/crypto/poly1305/sum_arm.s | 427 ++ .../golang.org/x/crypto/poly1305/sum_ref.go | 141 + .../x/crypto/ripemd160/ripemd160.go | 120 + .../x/crypto/ripemd160/ripemd160block.go | 161 + .../x/crypto/salsa20/salsa/hsalsa20.go | 144 + .../x/crypto/salsa20/salsa/salsa2020_amd64.s | 889 +++++ .../x/crypto/salsa20/salsa/salsa208.go | 199 + .../x/crypto/salsa20/salsa/salsa20_amd64.go | 24 + .../x/crypto/salsa20/salsa/salsa20_ref.go | 234 ++ .../golang.org/x/crypto/salsa20/salsa20.go | 54 + .../golang.org/x/crypto/scrypt/scrypt.go | 244 ++ .../vendor/golang.org/x/crypto/sha3/doc.go | 66 + .../vendor/golang.org/x/crypto/sha3/hashes.go | 65 + .../golang.org/x/crypto/sha3/keccakf.go | 412 ++ .../golang.org/x/crypto/sha3/keccakf_amd64.go | 13 + .../golang.org/x/crypto/sha3/keccakf_amd64.s | 390 ++ .../golang.org/x/crypto/sha3/register.go | 18 + .../vendor/golang.org/x/crypto/sha3/sha3.go | 192 + .../vendor/golang.org/x/crypto/sha3/shake.go | 60 + .../vendor/golang.org/x/crypto/sha3/xor.go | 16 + .../golang.org/x/crypto/sha3/xor_generic.go | 28 + .../golang.org/x/crypto/sha3/xor_unaligned.go | 58 + .../golang.org/x/crypto/ssh/agent/client.go | 683 ++++ .../golang.org/x/crypto/ssh/agent/forward.go | 103 + .../golang.org/x/crypto/ssh/agent/keyring.go | 215 + .../golang.org/x/crypto/ssh/agent/server.go | 523 +++ .../vendor/golang.org/x/crypto/ssh/buffer.go | 97 + .../vendor/golang.org/x/crypto/ssh/certs.go | 519 +++ .../vendor/golang.org/x/crypto/ssh/channel.go | 633 +++ .../vendor/golang.org/x/crypto/ssh/cipher.go | 629 +++ .../vendor/golang.org/x/crypto/ssh/client.go | 257 ++ .../golang.org/x/crypto/ssh/client_auth.go | 486 +++ .../vendor/golang.org/x/crypto/ssh/common.go | 373 ++ .../golang.org/x/crypto/ssh/connection.go | 143 + .../vendor/golang.org/x/crypto/ssh/doc.go | 21 + .../golang.org/x/crypto/ssh/handshake.go | 640 +++ .../vendor/golang.org/x/crypto/ssh/kex.go | 540 +++ .../vendor/golang.org/x/crypto/ssh/keys.go | 1031 +++++ .../x/crypto/ssh/knownhosts/knownhosts.go | 546 +++ .../vendor/golang.org/x/crypto/ssh/mac.go | 61 + .../golang.org/x/crypto/ssh/messages.go | 758 ++++ .../vendor/golang.org/x/crypto/ssh/mux.go | 330 ++ .../vendor/golang.org/x/crypto/ssh/server.go | 563 +++ .../vendor/golang.org/x/crypto/ssh/session.go | 647 +++ .../golang.org/x/crypto/ssh/streamlocal.go | 115 + .../vendor/golang.org/x/crypto/ssh/tcpip.go | 465 +++ .../x/crypto/ssh/terminal/terminal.go | 951 +++++ .../golang.org/x/crypto/ssh/terminal/util.go | 123 + .../x/crypto/ssh/terminal/util_bsd.go | 12 + .../x/crypto/ssh/terminal/util_linux.go | 10 + .../x/crypto/ssh/terminal/util_plan9.go | 58 + .../x/crypto/ssh/terminal/util_solaris.go | 128 + .../x/crypto/ssh/terminal/util_windows.go | 102 + .../golang.org/x/crypto/ssh/test/doc.go | 7 + .../golang.org/x/crypto/ssh/transport.go | 375 ++ .../vendor/golang.org/x/crypto/tea/cipher.go | 109 + .../golang.org/x/crypto/twofish/twofish.go | 342 ++ .../vendor/golang.org/x/crypto/xtea/block.go | 66 + .../vendor/golang.org/x/crypto/xtea/cipher.go | 82 + .../vendor/golang.org/x/crypto/xts/xts.go | 137 + .../vendor/golang.org/x/sys/plan9/asm.s | 8 + .../golang.org/x/sys/plan9/asm_plan9_386.s | 30 + .../golang.org/x/sys/plan9/asm_plan9_amd64.s | 30 + .../golang.org/x/sys/plan9/const_plan9.go | 70 + .../golang.org/x/sys/plan9/dir_plan9.go | 212 + .../golang.org/x/sys/plan9/env_plan9.go | 27 + .../golang.org/x/sys/plan9/env_unset.go | 14 + .../golang.org/x/sys/plan9/errors_plan9.go | 50 + .../golang.org/x/sys/plan9/pwd_go15_plan9.go | 21 + .../golang.org/x/sys/plan9/pwd_plan9.go | 23 + .../vendor/golang.org/x/sys/plan9/race.go | 30 + .../vendor/golang.org/x/sys/plan9/race0.go | 25 + .../vendor/golang.org/x/sys/plan9/str.go | 22 + .../vendor/golang.org/x/sys/plan9/syscall.go | 74 + .../golang.org/x/sys/plan9/syscall_plan9.go | 349 ++ .../x/sys/plan9/zsyscall_plan9_386.go | 292 ++ .../x/sys/plan9/zsyscall_plan9_amd64.go | 292 ++ .../golang.org/x/sys/plan9/zsysnum_plan9.go | 49 + .../golang.org/x/sys/unix/asm_darwin_386.s | 29 + .../golang.org/x/sys/unix/asm_darwin_amd64.s | 29 + .../golang.org/x/sys/unix/asm_darwin_arm.s | 30 + .../golang.org/x/sys/unix/asm_darwin_arm64.s | 30 + .../x/sys/unix/asm_dragonfly_amd64.s | 29 + .../golang.org/x/sys/unix/asm_freebsd_386.s | 29 + .../golang.org/x/sys/unix/asm_freebsd_amd64.s | 29 + .../golang.org/x/sys/unix/asm_freebsd_arm.s | 29 + .../golang.org/x/sys/unix/asm_linux_386.s | 35 + .../golang.org/x/sys/unix/asm_linux_amd64.s | 29 + .../golang.org/x/sys/unix/asm_linux_arm.s | 29 + .../golang.org/x/sys/unix/asm_linux_arm64.s | 24 + .../golang.org/x/sys/unix/asm_linux_mips64x.s | 28 + .../golang.org/x/sys/unix/asm_linux_mipsx.s | 31 + .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 28 + .../golang.org/x/sys/unix/asm_linux_s390x.s | 28 + .../golang.org/x/sys/unix/asm_netbsd_386.s | 29 + .../golang.org/x/sys/unix/asm_netbsd_amd64.s | 29 + .../golang.org/x/sys/unix/asm_netbsd_arm.s | 29 + .../golang.org/x/sys/unix/asm_openbsd_386.s | 29 + .../golang.org/x/sys/unix/asm_openbsd_amd64.s | 29 + .../golang.org/x/sys/unix/asm_openbsd_arm.s | 29 + .../golang.org/x/sys/unix/asm_solaris_amd64.s | 17 + .../golang.org/x/sys/unix/bluetooth_linux.go | 35 + .../golang.org/x/sys/unix/cap_freebsd.go | 195 + .../vendor/golang.org/x/sys/unix/constants.go | 13 + .../golang.org/x/sys/unix/dev_darwin.go | 24 + .../golang.org/x/sys/unix/dev_dragonfly.go | 30 + .../golang.org/x/sys/unix/dev_freebsd.go | 30 + .../vendor/golang.org/x/sys/unix/dev_linux.go | 42 + .../golang.org/x/sys/unix/dev_netbsd.go | 29 + .../golang.org/x/sys/unix/dev_openbsd.go | 29 + .../vendor/golang.org/x/sys/unix/dirent.go | 102 + .../golang.org/x/sys/unix/endian_big.go | 9 + .../golang.org/x/sys/unix/endian_little.go | 9 + .../vendor/golang.org/x/sys/unix/env_unix.go | 27 + .../vendor/golang.org/x/sys/unix/env_unset.go | 14 + .../x/sys/unix/errors_freebsd_386.go | 227 ++ .../x/sys/unix/errors_freebsd_amd64.go | 227 ++ .../x/sys/unix/errors_freebsd_arm.go | 226 ++ .../vendor/golang.org/x/sys/unix/file_unix.go | 27 + .../vendor/golang.org/x/sys/unix/flock.go | 22 + .../x/sys/unix/flock_linux_32bit.go | 13 + .../vendor/golang.org/x/sys/unix/gccgo.go | 46 + .../vendor/golang.org/x/sys/unix/gccgo_c.c | 41 + .../x/sys/unix/gccgo_linux_amd64.go | 20 + .../golang.org/x/sys/unix/linux/mkall.go | 379 ++ .../golang.org/x/sys/unix/linux/types.go | 595 +++ .../vendor/golang.org/x/sys/unix/mkpost.go | 88 + .../golang.org/x/sys/unix/openbsd_pledge.go | 38 + .../golang.org/x/sys/unix/pagesize_unix.go | 15 + .../vendor/golang.org/x/sys/unix/race.go | 30 + .../vendor/golang.org/x/sys/unix/race0.go | 25 + .../golang.org/x/sys/unix/sockcmsg_linux.go | 36 + .../golang.org/x/sys/unix/sockcmsg_unix.go | 104 + .../vendor/golang.org/x/sys/unix/str.go | 26 + .../vendor/golang.org/x/sys/unix/syscall.go | 69 + .../golang.org/x/sys/unix/syscall_bsd.go | 635 +++ .../golang.org/x/sys/unix/syscall_darwin.go | 536 +++ .../x/sys/unix/syscall_darwin_386.go | 75 + .../x/sys/unix/syscall_darwin_amd64.go | 75 + .../x/sys/unix/syscall_darwin_arm.go | 69 + .../x/sys/unix/syscall_darwin_arm64.go | 75 + .../x/sys/unix/syscall_dragonfly.go | 415 ++ .../x/sys/unix/syscall_dragonfly_amd64.go | 59 + .../golang.org/x/sys/unix/syscall_freebsd.go | 708 ++++ .../x/sys/unix/syscall_freebsd_386.go | 59 + .../x/sys/unix/syscall_freebsd_amd64.go | 59 + .../x/sys/unix/syscall_freebsd_arm.go | 59 + .../golang.org/x/sys/unix/syscall_linux.go | 1469 +++++++ .../x/sys/unix/syscall_linux_386.go | 397 ++ .../x/sys/unix/syscall_linux_amd64.go | 150 + .../x/sys/unix/syscall_linux_amd64_gc.go | 13 + .../x/sys/unix/syscall_linux_arm.go | 261 ++ .../x/sys/unix/syscall_linux_arm64.go | 188 + .../x/sys/unix/syscall_linux_mips64x.go | 207 + .../x/sys/unix/syscall_linux_mipsx.go | 237 ++ .../x/sys/unix/syscall_linux_ppc64x.go | 133 + .../x/sys/unix/syscall_linux_s390x.go | 326 ++ .../x/sys/unix/syscall_linux_sparc64.go | 149 + .../golang.org/x/sys/unix/syscall_netbsd.go | 472 +++ .../x/sys/unix/syscall_netbsd_386.go | 40 + .../x/sys/unix/syscall_netbsd_amd64.go | 40 + .../x/sys/unix/syscall_netbsd_arm.go | 40 + .../golang.org/x/sys/unix/syscall_no_getwd.go | 11 + .../golang.org/x/sys/unix/syscall_openbsd.go | 282 ++ .../x/sys/unix/syscall_openbsd_386.go | 40 + .../x/sys/unix/syscall_openbsd_amd64.go | 40 + .../x/sys/unix/syscall_openbsd_arm.go | 40 + .../golang.org/x/sys/unix/syscall_solaris.go | 719 ++++ .../x/sys/unix/syscall_solaris_amd64.go | 35 + .../golang.org/x/sys/unix/syscall_unix.go | 293 ++ .../golang.org/x/sys/unix/syscall_unix_gc.go | 15 + .../golang.org/x/sys/unix/types_darwin.go | 254 ++ .../golang.org/x/sys/unix/types_dragonfly.go | 249 ++ .../golang.org/x/sys/unix/types_freebsd.go | 372 ++ .../golang.org/x/sys/unix/types_netbsd.go | 239 ++ .../golang.org/x/sys/unix/types_openbsd.go | 251 ++ .../golang.org/x/sys/unix/types_solaris.go | 265 ++ .../x/sys/unix/zerrors_darwin_386.go | 1673 ++++++++ .../x/sys/unix/zerrors_darwin_amd64.go | 1673 ++++++++ .../x/sys/unix/zerrors_darwin_arm.go | 1673 ++++++++ .../x/sys/unix/zerrors_darwin_arm64.go | 1673 ++++++++ .../x/sys/unix/zerrors_dragonfly_amd64.go | 1568 ++++++++ .../x/sys/unix/zerrors_freebsd_386.go | 1706 ++++++++ .../x/sys/unix/zerrors_freebsd_amd64.go | 1707 ++++++++ .../x/sys/unix/zerrors_freebsd_arm.go | 1715 ++++++++ .../x/sys/unix/zerrors_linux_386.go | 2231 +++++++++++ .../x/sys/unix/zerrors_linux_amd64.go | 2232 +++++++++++ .../x/sys/unix/zerrors_linux_arm.go | 2236 +++++++++++ .../x/sys/unix/zerrors_linux_arm64.go | 2222 +++++++++++ .../x/sys/unix/zerrors_linux_mips.go | 2241 +++++++++++ .../x/sys/unix/zerrors_linux_mips64.go | 2241 +++++++++++ .../x/sys/unix/zerrors_linux_mips64le.go | 2241 +++++++++++ .../x/sys/unix/zerrors_linux_mipsle.go | 2241 +++++++++++ .../x/sys/unix/zerrors_linux_ppc64.go | 2294 +++++++++++ .../x/sys/unix/zerrors_linux_ppc64le.go | 2294 +++++++++++ .../x/sys/unix/zerrors_linux_s390x.go | 2293 +++++++++++ .../x/sys/unix/zerrors_linux_sparc64.go | 2142 ++++++++++ .../x/sys/unix/zerrors_netbsd_386.go | 1712 ++++++++ .../x/sys/unix/zerrors_netbsd_amd64.go | 1702 ++++++++ .../x/sys/unix/zerrors_netbsd_arm.go | 1691 ++++++++ .../x/sys/unix/zerrors_openbsd_386.go | 1584 ++++++++ .../x/sys/unix/zerrors_openbsd_amd64.go | 1583 ++++++++ .../x/sys/unix/zerrors_openbsd_arm.go | 1586 ++++++++ .../x/sys/unix/zerrors_solaris_amd64.go | 1489 +++++++ .../x/sys/unix/zsyscall_darwin_386.go | 1609 ++++++++ .../x/sys/unix/zsyscall_darwin_amd64.go | 1609 ++++++++ .../x/sys/unix/zsyscall_darwin_arm.go | 1609 ++++++++ .../x/sys/unix/zsyscall_darwin_arm64.go | 1609 ++++++++ .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1440 +++++++ .../x/sys/unix/zsyscall_freebsd_386.go | 1877 +++++++++ .../x/sys/unix/zsyscall_freebsd_amd64.go | 1877 +++++++++ .../x/sys/unix/zsyscall_freebsd_arm.go | 1877 +++++++++ .../x/sys/unix/zsyscall_linux_386.go | 1953 +++++++++ .../x/sys/unix/zsyscall_linux_amd64.go | 2146 ++++++++++ .../x/sys/unix/zsyscall_linux_arm.go | 2055 ++++++++++ .../x/sys/unix/zsyscall_linux_arm64.go | 2029 ++++++++++ .../x/sys/unix/zsyscall_linux_mips.go | 2111 ++++++++++ .../x/sys/unix/zsyscall_linux_mips64.go | 2105 ++++++++++ .../x/sys/unix/zsyscall_linux_mips64le.go | 2105 ++++++++++ .../x/sys/unix/zsyscall_linux_mipsle.go | 2111 ++++++++++ .../x/sys/unix/zsyscall_linux_ppc64.go | 2157 ++++++++++ .../x/sys/unix/zsyscall_linux_ppc64le.go | 2157 ++++++++++ .../x/sys/unix/zsyscall_linux_s390x.go | 1937 +++++++++ .../x/sys/unix/zsyscall_linux_sparc64.go | 1833 +++++++++ .../x/sys/unix/zsyscall_netbsd_386.go | 1346 +++++++ .../x/sys/unix/zsyscall_netbsd_amd64.go | 1346 +++++++ .../x/sys/unix/zsyscall_netbsd_arm.go | 1346 +++++++ .../x/sys/unix/zsyscall_openbsd_386.go | 1404 +++++++ .../x/sys/unix/zsyscall_openbsd_amd64.go | 1404 +++++++ .../x/sys/unix/zsyscall_openbsd_arm.go | 1404 +++++++ .../x/sys/unix/zsyscall_solaris_amd64.go | 1630 ++++++++ .../golang.org/x/sys/unix/zsysctl_openbsd.go | 270 ++ .../x/sys/unix/zsysnum_darwin_386.go | 398 ++ .../x/sys/unix/zsysnum_darwin_amd64.go | 398 ++ .../x/sys/unix/zsysnum_darwin_arm.go | 426 ++ .../x/sys/unix/zsysnum_darwin_arm64.go | 426 ++ .../x/sys/unix/zsysnum_dragonfly_amd64.go | 315 ++ .../x/sys/unix/zsysnum_freebsd_386.go | 353 ++ .../x/sys/unix/zsysnum_freebsd_amd64.go | 353 ++ .../x/sys/unix/zsysnum_freebsd_arm.go | 353 ++ .../x/sys/unix/zsysnum_linux_386.go | 390 ++ .../x/sys/unix/zsysnum_linux_amd64.go | 342 ++ .../x/sys/unix/zsysnum_linux_arm.go | 362 ++ .../x/sys/unix/zsysnum_linux_arm64.go | 286 ++ .../x/sys/unix/zsysnum_linux_mips.go | 375 ++ .../x/sys/unix/zsysnum_linux_mips64.go | 335 ++ .../x/sys/unix/zsysnum_linux_mips64le.go | 335 ++ .../x/sys/unix/zsysnum_linux_mipsle.go | 375 ++ .../x/sys/unix/zsysnum_linux_ppc64.go | 370 ++ .../x/sys/unix/zsysnum_linux_ppc64le.go | 370 ++ .../x/sys/unix/zsysnum_linux_s390x.go | 333 ++ .../x/sys/unix/zsysnum_linux_sparc64.go | 348 ++ .../x/sys/unix/zsysnum_netbsd_386.go | 274 ++ .../x/sys/unix/zsysnum_netbsd_amd64.go | 274 ++ .../x/sys/unix/zsysnum_netbsd_arm.go | 274 ++ .../x/sys/unix/zsysnum_openbsd_386.go | 207 + .../x/sys/unix/zsysnum_openbsd_amd64.go | 207 + .../x/sys/unix/zsysnum_openbsd_arm.go | 213 + .../x/sys/unix/zsysnum_solaris_amd64.go | 13 + .../x/sys/unix/ztypes_darwin_386.go | 462 +++ .../x/sys/unix/ztypes_darwin_amd64.go | 472 +++ .../x/sys/unix/ztypes_darwin_arm.go | 463 +++ .../x/sys/unix/ztypes_darwin_arm64.go | 471 +++ .../x/sys/unix/ztypes_dragonfly_amd64.go | 448 +++ .../x/sys/unix/ztypes_freebsd_386.go | 521 +++ .../x/sys/unix/ztypes_freebsd_amd64.go | 524 +++ .../x/sys/unix/ztypes_freebsd_arm.go | 524 +++ .../golang.org/x/sys/unix/ztypes_linux_386.go | 793 ++++ .../x/sys/unix/ztypes_linux_amd64.go | 811 ++++ .../golang.org/x/sys/unix/ztypes_linux_arm.go | 782 ++++ .../x/sys/unix/ztypes_linux_arm64.go | 790 ++++ .../x/sys/unix/ztypes_linux_mips.go | 787 ++++ .../x/sys/unix/ztypes_linux_mips64.go | 792 ++++ .../x/sys/unix/ztypes_linux_mips64le.go | 792 ++++ .../x/sys/unix/ztypes_linux_mipsle.go | 787 ++++ .../x/sys/unix/ztypes_linux_ppc64.go | 800 ++++ .../x/sys/unix/ztypes_linux_ppc64le.go | 800 ++++ .../x/sys/unix/ztypes_linux_s390x.go | 817 ++++ .../x/sys/unix/ztypes_linux_sparc64.go | 666 ++++ .../x/sys/unix/ztypes_netbsd_386.go | 401 ++ .../x/sys/unix/ztypes_netbsd_amd64.go | 408 ++ .../x/sys/unix/ztypes_netbsd_arm.go | 406 ++ .../x/sys/unix/ztypes_openbsd_386.go | 446 +++ .../x/sys/unix/ztypes_openbsd_amd64.go | 453 +++ .../x/sys/unix/ztypes_openbsd_arm.go | 439 ++ .../x/sys/unix/ztypes_solaris_amd64.go | 440 +++ .../x/sys/windows/asm_windows_386.s | 13 + .../x/sys/windows/asm_windows_amd64.s | 13 + .../golang.org/x/sys/windows/dll_windows.go | 377 ++ .../golang.org/x/sys/windows/env_unset.go | 15 + .../golang.org/x/sys/windows/env_windows.go | 25 + .../golang.org/x/sys/windows/eventlog.go | 20 + .../golang.org/x/sys/windows/exec_windows.go | 97 + .../x/sys/windows/memory_windows.go | 26 + .../golang.org/x/sys/windows/mksyscall.go | 7 + .../vendor/golang.org/x/sys/windows/race.go | 30 + .../vendor/golang.org/x/sys/windows/race0.go | 25 + .../golang.org/x/sys/windows/registry/key.go | 200 + .../x/sys/windows/registry/mksyscall.go | 7 + .../x/sys/windows/registry/syscall.go | 32 + .../x/sys/windows/registry/value.go | 384 ++ .../sys/windows/registry/zsyscall_windows.go | 120 + .../x/sys/windows/security_windows.go | 435 ++ .../golang.org/x/sys/windows/service.go | 164 + .../vendor/golang.org/x/sys/windows/str.go | 22 + .../golang.org/x/sys/windows/svc/debug/log.go | 56 + .../x/sys/windows/svc/debug/service.go | 45 + .../golang.org/x/sys/windows/svc/event.go | 48 + .../x/sys/windows/svc/eventlog/install.go | 80 + .../x/sys/windows/svc/eventlog/log.go | 70 + .../x/sys/windows/svc/example/beep.go | 22 + .../x/sys/windows/svc/example/install.go | 92 + .../x/sys/windows/svc/example/main.go | 76 + .../x/sys/windows/svc/example/manage.go | 62 + .../x/sys/windows/svc/example/service.go | 82 + .../golang.org/x/sys/windows/svc/go12.c | 24 + .../golang.org/x/sys/windows/svc/go12.go | 11 + .../golang.org/x/sys/windows/svc/go13.go | 31 + .../x/sys/windows/svc/mgr/config.go | 139 + .../golang.org/x/sys/windows/svc/mgr/mgr.go | 162 + .../x/sys/windows/svc/mgr/service.go | 72 + .../golang.org/x/sys/windows/svc/security.go | 62 + .../golang.org/x/sys/windows/svc/service.go | 363 ++ .../golang.org/x/sys/windows/svc/sys_386.s | 68 + .../golang.org/x/sys/windows/svc/sys_amd64.s | 42 + .../golang.org/x/sys/windows/syscall.go | 71 + .../x/sys/windows/syscall_windows.go | 1009 +++++ .../golang.org/x/sys/windows/types_windows.go | 1282 ++++++ .../x/sys/windows/types_windows_386.go | 22 + .../x/sys/windows/types_windows_amd64.go | 22 + .../x/sys/windows/zsyscall_windows.go | 2428 ++++++++++++ vendor/go.uber.org/atomic/LICENSE.txt | 19 + vendor/go.uber.org/atomic/atomic.go | 351 ++ vendor/go.uber.org/atomic/string.go | 49 + vendor/go.uber.org/multierr/LICENSE.txt | 19 + vendor/go.uber.org/multierr/error.go | 401 ++ vendor/go.uber.org/zap/LICENSE.txt | 19 + vendor/go.uber.org/zap/array.go | 320 ++ vendor/go.uber.org/zap/benchmarks/doc.go | 23 + vendor/go.uber.org/zap/buffer/buffer.go | 115 + vendor/go.uber.org/zap/buffer/pool.go | 49 + vendor/go.uber.org/zap/config.go | 243 ++ vendor/go.uber.org/zap/doc.go | 113 + vendor/go.uber.org/zap/encoder.go | 75 + vendor/go.uber.org/zap/error.go | 80 + vendor/go.uber.org/zap/field.go | 310 ++ vendor/go.uber.org/zap/flag.go | 39 + vendor/go.uber.org/zap/global.go | 169 + vendor/go.uber.org/zap/http_handler.go | 81 + .../zap/internal/bufferpool/bufferpool.go | 31 + .../go.uber.org/zap/internal/color/color.go | 44 + vendor/go.uber.org/zap/internal/exit/exit.go | 64 + .../go.uber.org/zap/internal/readme/readme.go | 209 + vendor/go.uber.org/zap/internal/ztest/doc.go | 24 + .../go.uber.org/zap/internal/ztest/timeout.go | 59 + .../go.uber.org/zap/internal/ztest/writer.go | 96 + vendor/go.uber.org/zap/level.go | 132 + vendor/go.uber.org/zap/logger.go | 305 ++ vendor/go.uber.org/zap/options.go | 109 + vendor/go.uber.org/zap/sink.go | 161 + vendor/go.uber.org/zap/stacktrace.go | 126 + vendor/go.uber.org/zap/sugar.go | 304 ++ vendor/go.uber.org/zap/time.go | 27 + vendor/go.uber.org/zap/writer.go | 99 + .../zap/zapcore/console_encoder.go | 147 + vendor/go.uber.org/zap/zapcore/core.go | 113 + vendor/go.uber.org/zap/zapcore/doc.go | 24 + vendor/go.uber.org/zap/zapcore/encoder.go | 348 ++ vendor/go.uber.org/zap/zapcore/entry.go | 257 ++ vendor/go.uber.org/zap/zapcore/error.go | 120 + vendor/go.uber.org/zap/zapcore/field.go | 201 + vendor/go.uber.org/zap/zapcore/hook.go | 68 + .../go.uber.org/zap/zapcore/json_encoder.go | 502 +++ vendor/go.uber.org/zap/zapcore/level.go | 175 + .../go.uber.org/zap/zapcore/level_strings.go | 46 + vendor/go.uber.org/zap/zapcore/marshaler.go | 53 + .../go.uber.org/zap/zapcore/memory_encoder.go | 179 + vendor/go.uber.org/zap/zapcore/sampler.go | 134 + vendor/go.uber.org/zap/zapcore/tee.go | 81 + .../go.uber.org/zap/zapcore/write_syncer.go | 123 + vendor/go.uber.org/zap/zapgrpc/zapgrpc.go | 100 + vendor/go.uber.org/zap/zaptest/doc.go | 22 + vendor/go.uber.org/zap/zaptest/logger.go | 124 + .../zap/zaptest/observer/logged_entry.go | 39 + .../zap/zaptest/observer/observer.go | 167 + vendor/go.uber.org/zap/zaptest/testingt.go | 47 + vendor/go.uber.org/zap/zaptest/timeout.go | 45 + vendor/go.uber.org/zap/zaptest/writer.go | 44 + vendor/golang.org/x/sync/errgroup/LICENSE | 27 + vendor/golang.org/x/sync/errgroup/errgroup.go | 67 + .../googleapis/rpc/status/status.pb.go | 63 +- vendor/gopkg.in/alecthomas/kingpin.v2/COPYING | 19 + .../gopkg.in/alecthomas/kingpin.v2/actions.go | 42 + vendor/gopkg.in/alecthomas/kingpin.v2/app.go | 688 ++++ vendor/gopkg.in/alecthomas/kingpin.v2/args.go | 184 + vendor/gopkg.in/alecthomas/kingpin.v2/cmd.go | 274 ++ .../kingpin.v2/cmd/genvalues/main.go | 134 + .../alecthomas/kingpin.v2/completions.go | 33 + vendor/gopkg.in/alecthomas/kingpin.v2/doc.go | 68 + .../gopkg.in/alecthomas/kingpin.v2/envar.go | 45 + .../gopkg.in/alecthomas/kingpin.v2/flags.go | 308 ++ .../gopkg.in/alecthomas/kingpin.v2/global.go | 94 + .../alecthomas/kingpin.v2/guesswidth.go | 9 + .../alecthomas/kingpin.v2/guesswidth_unix.go | 38 + .../gopkg.in/alecthomas/kingpin.v2/model.go | 227 ++ .../gopkg.in/alecthomas/kingpin.v2/parser.go | 396 ++ .../gopkg.in/alecthomas/kingpin.v2/parsers.go | 212 + .../alecthomas/kingpin.v2/templates.go | 262 ++ .../gopkg.in/alecthomas/kingpin.v2/usage.go | 211 + .../gopkg.in/alecthomas/kingpin.v2/values.go | 470 +++ .../alecthomas/kingpin.v2/values_generated.go | 821 ++++ vendor/gopkg.in/validator.v2/LICENSE | 201 + vendor/gopkg.in/validator.v2/builtins.go | 271 ++ vendor/gopkg.in/validator.v2/doc.go | 265 ++ vendor/gopkg.in/validator.v2/validator.go | 369 ++ vendor/manifest | 421 +- 1466 files changed, 394515 insertions(+), 359 deletions(-) create mode 100644 vendor/github.com/VividCortex/gohistogram/LICENSE create mode 100644 vendor/github.com/VividCortex/gohistogram/histogram.go create mode 100644 vendor/github.com/VividCortex/gohistogram/numerichistogram.go create mode 100644 vendor/github.com/VividCortex/gohistogram/weightedhistogram.go create mode 100644 vendor/github.com/alecthomas/template/LICENSE create mode 100644 vendor/github.com/alecthomas/template/doc.go create mode 100644 vendor/github.com/alecthomas/template/exec.go create mode 100644 vendor/github.com/alecthomas/template/funcs.go create mode 100644 vendor/github.com/alecthomas/template/helper.go create mode 100644 vendor/github.com/alecthomas/template/parse/lex.go create mode 100644 vendor/github.com/alecthomas/template/parse/node.go create mode 100644 vendor/github.com/alecthomas/template/parse/parse.go create mode 100644 vendor/github.com/alecthomas/template/template.go create mode 100644 vendor/github.com/alecthomas/units/COPYING create mode 100644 vendor/github.com/alecthomas/units/bytes.go create mode 100644 vendor/github.com/alecthomas/units/doc.go create mode 100644 vendor/github.com/alecthomas/units/si.go create mode 100644 vendor/github.com/alecthomas/units/util.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/LICENSE create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/application_exception.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/binary_protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/buffered_transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/client.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/context.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/debug_protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/deserializer.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/exception.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/field.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/framed_transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/http_client.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/http_transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/iostream_transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/json_protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/memory_buffer.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/messagetype.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/multiplexed_protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/numeric.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/pointerize.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/processor_factory.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/protocol_exception.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/protocol_factory.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/rich_transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/serializer.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/server.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/server_socket.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/server_transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/simple_json_protocol.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/simple_server.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/socket.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/ssl_server_socket.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/ssl_socket.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/transport.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/transport_exception.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/transport_factory.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/type.go create mode 100644 vendor/github.com/apache/thrift/lib/go/thrift/zlib_transport.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/error.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/chain_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/client.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/client_logger.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/config.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error_other.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/context.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/convert_types.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/default_retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/handlers.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/param_validator.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/user_agent_handlers.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/ec2rolecreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpointcreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/decode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/defaults.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/endpoints.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model_codegen.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/config.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/env_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/http_client.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/local.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/resolve.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/external/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/handlers.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/http_request.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/logger.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/offset_reader.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/doc_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_8.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request_context.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request_context_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request_pagination.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/response.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v2/v2.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/header_rules.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/uri_path.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/static_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/stscreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/timeout_read_closer.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/url.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/url_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/validation.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/version.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/waiter.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/copy.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/equal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/path_value.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/prettify.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/string_value.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/encode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/fields.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/header_encoder.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/idempotency.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/encode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/escape.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonrpc/jsonrpc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/metadata.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/path_replace.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/queryutil/queryutil.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query_encoder.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/encode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/encode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/restjson.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/encode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/restxml.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/target.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/value.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/encode.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/xml_to_struct.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/cloudwatchiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/waiters.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/customizations.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/stsiface/interface.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/LICENSE.md create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/buffer_pool.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/client.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/client_buffered.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/client_noop.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/doc.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/sender.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/sender_buffered.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/recorder.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/stat.go create mode 100644 vendor/github.com/cactus/go-statsd-client/statsd/validator.go create mode 100644 vendor/github.com/codahale/hdrhistogram/LICENSE create mode 100644 vendor/github.com/codahale/hdrhistogram/hdr.go create mode 100644 vendor/github.com/codahale/hdrhistogram/window.go create mode 100644 vendor/github.com/crossdock/crossdock-go/LICENSE create mode 100644 vendor/github.com/crossdock/crossdock-go/assert/assertion_forward.go create mode 100644 vendor/github.com/crossdock/crossdock-go/assert/assertions.go create mode 100644 vendor/github.com/crossdock/crossdock-go/assert/doc.go create mode 100644 vendor/github.com/crossdock/crossdock-go/assert/errors.go create mode 100644 vendor/github.com/crossdock/crossdock-go/assert/forward_assertions.go create mode 100644 vendor/github.com/crossdock/crossdock-go/assert/http_assertions.go create mode 100644 vendor/github.com/crossdock/crossdock-go/call.go create mode 100644 vendor/github.com/crossdock/crossdock-go/client.go create mode 100644 vendor/github.com/crossdock/crossdock-go/combinations.go create mode 100644 vendor/github.com/crossdock/crossdock-go/doc.go create mode 100644 vendor/github.com/crossdock/crossdock-go/entry.go create mode 100644 vendor/github.com/crossdock/crossdock-go/require/doc.go create mode 100644 vendor/github.com/crossdock/crossdock-go/require/forward_requirements.go create mode 100644 vendor/github.com/crossdock/crossdock-go/require/require.go create mode 100644 vendor/github.com/crossdock/crossdock-go/require/require_forward.go create mode 100644 vendor/github.com/crossdock/crossdock-go/require/requirements.go create mode 100644 vendor/github.com/crossdock/crossdock-go/run.go create mode 100644 vendor/github.com/crossdock/crossdock-go/t.go create mode 100644 vendor/github.com/crossdock/crossdock-go/testify.go create mode 100644 vendor/github.com/crossdock/crossdock-go/wait.go create mode 100644 vendor/github.com/go-kit/kit/log/LICENSE create mode 100644 vendor/github.com/go-kit/kit/log/deprecated_levels/levels.go create mode 100644 vendor/github.com/go-kit/kit/log/doc.go create mode 100644 vendor/github.com/go-kit/kit/log/json_logger.go create mode 100644 vendor/github.com/go-kit/kit/log/level/doc.go create mode 100644 vendor/github.com/go-kit/kit/log/level/level.go create mode 100644 vendor/github.com/go-kit/kit/log/log.go create mode 100644 vendor/github.com/go-kit/kit/log/logfmt_logger.go create mode 100644 vendor/github.com/go-kit/kit/log/nop_logger.go create mode 100644 vendor/github.com/go-kit/kit/log/stdlib.go create mode 100644 vendor/github.com/go-kit/kit/log/sync.go create mode 100644 vendor/github.com/go-kit/kit/log/syslog/syslog.go create mode 100644 vendor/github.com/go-kit/kit/log/term/colorlogger.go create mode 100644 vendor/github.com/go-kit/kit/log/term/colorwriter_others.go create mode 100644 vendor/github.com/go-kit/kit/log/term/colorwriter_windows.go create mode 100644 vendor/github.com/go-kit/kit/log/term/term.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_appengine.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_darwin.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_freebsd.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_linux.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_notwindows.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_openbsd.go create mode 100644 vendor/github.com/go-kit/kit/log/term/terminal_windows.go create mode 100644 vendor/github.com/go-kit/kit/log/value.go create mode 100644 vendor/github.com/go-kit/kit/metrics/LICENSE create mode 100644 vendor/github.com/go-kit/kit/metrics/cloudwatch/cloudwatch.go create mode 100644 vendor/github.com/go-kit/kit/metrics/cloudwatch2/cloudwatch2.go create mode 100644 vendor/github.com/go-kit/kit/metrics/discard/discard.go create mode 100644 vendor/github.com/go-kit/kit/metrics/doc.go create mode 100644 vendor/github.com/go-kit/kit/metrics/dogstatsd/dogstatsd.go create mode 100644 vendor/github.com/go-kit/kit/metrics/expvar/expvar.go create mode 100644 vendor/github.com/go-kit/kit/metrics/generic/generic.go create mode 100644 vendor/github.com/go-kit/kit/metrics/graphite/graphite.go create mode 100644 vendor/github.com/go-kit/kit/metrics/influx/influx.go create mode 100644 vendor/github.com/go-kit/kit/metrics/influxstatsd/influxstatsd.go create mode 100644 vendor/github.com/go-kit/kit/metrics/internal/convert/convert.go create mode 100644 vendor/github.com/go-kit/kit/metrics/internal/lv/labelvalues.go create mode 100644 vendor/github.com/go-kit/kit/metrics/internal/lv/space.go create mode 100644 vendor/github.com/go-kit/kit/metrics/internal/ratemap/ratemap.go create mode 100644 vendor/github.com/go-kit/kit/metrics/metrics.go create mode 100644 vendor/github.com/go-kit/kit/metrics/multi/multi.go create mode 100644 vendor/github.com/go-kit/kit/metrics/pcp/pcp.go create mode 100644 vendor/github.com/go-kit/kit/metrics/prometheus/prometheus.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/discard.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/dogstatsd.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/expvar.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/graphite.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/influx.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/prometheus.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/provider.go create mode 100644 vendor/github.com/go-kit/kit/metrics/provider/statsd.go create mode 100644 vendor/github.com/go-kit/kit/metrics/statsd/statsd.go create mode 100644 vendor/github.com/go-kit/kit/metrics/teststat/buffers.go create mode 100644 vendor/github.com/go-kit/kit/metrics/teststat/populate.go create mode 100644 vendor/github.com/go-kit/kit/metrics/teststat/teststat.go create mode 100644 vendor/github.com/go-kit/kit/metrics/timer.go create mode 100644 vendor/github.com/go-kit/kit/util/conn/LICENSE create mode 100644 vendor/github.com/go-kit/kit/util/conn/doc.go create mode 100644 vendor/github.com/go-kit/kit/util/conn/manager.go create mode 100644 vendor/github.com/go-logfmt/logfmt/LICENSE create mode 100644 vendor/github.com/go-logfmt/logfmt/decode.go create mode 100644 vendor/github.com/go-logfmt/logfmt/doc.go create mode 100644 vendor/github.com/go-logfmt/logfmt/encode.go create mode 100644 vendor/github.com/go-logfmt/logfmt/fuzz.go create mode 100644 vendor/github.com/go-logfmt/logfmt/jsonstring.go create mode 100644 vendor/github.com/go-stack/stack/LICENSE.md create mode 100644 vendor/github.com/go-stack/stack/stack.go create mode 100644 vendor/github.com/gogo/protobuf/gogoproto/LICENSE create mode 100644 vendor/github.com/gogo/protobuf/gogoproto/doc.go create mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go create mode 100644 vendor/github.com/gogo/protobuf/gogoproto/helper.go create mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/LICENSE create mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.go create mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go create mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor_gostring.gen.go create mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/LICENSE create mode 100644 vendor/github.com/golang/protobuf/jsonpb/jsonpb.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.pb.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/common.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/client_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/grpclogger.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/payload_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/server_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/client_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap/context.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/grpclogger.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/payload_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/server_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/backoff.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/gogotestproto/fields.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/interceptor_suite.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/mutex_readerwriter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/pingservice.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/testproto/test.manual_extractfields.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/testproto/test.manual_validator.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/testing/testproto/test.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils/backoff.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/single_key.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/validator.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/LICENSE create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/options.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/package.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/test/otgrpc_testing/test.pb.go create mode 100644 vendor/github.com/influxdata/influxdb/client/v2/LICENSE create mode 100644 vendor/github.com/influxdata/influxdb/client/v2/client.go create mode 100644 vendor/github.com/influxdata/influxdb/client/v2/udp.go create mode 100644 vendor/github.com/influxdata/influxdb/models/LICENSE create mode 100644 vendor/github.com/influxdata/influxdb/models/consistency.go create mode 100644 vendor/github.com/influxdata/influxdb/models/inline_fnv.go create mode 100644 vendor/github.com/influxdata/influxdb/models/inline_strconv_parse.go create mode 100644 vendor/github.com/influxdata/influxdb/models/points.go create mode 100644 vendor/github.com/influxdata/influxdb/models/rows.go create mode 100644 vendor/github.com/influxdata/influxdb/models/statistic.go create mode 100644 vendor/github.com/influxdata/influxdb/models/time.go create mode 100644 vendor/github.com/influxdata/influxdb/models/uint_support.go create mode 100644 vendor/github.com/influxdata/influxdb/pkg/escape/LICENSE create mode 100644 vendor/github.com/influxdata/influxdb/pkg/escape/bytes.go create mode 100644 vendor/github.com/influxdata/influxdb/pkg/escape/strings.go create mode 100644 vendor/github.com/julienschmidt/httprouter/LICENSE create mode 100644 vendor/github.com/julienschmidt/httprouter/params_go17.go create mode 100644 vendor/github.com/julienschmidt/httprouter/params_legacy.go create mode 100644 vendor/github.com/julienschmidt/httprouter/path.go create mode 100644 vendor/github.com/julienschmidt/httprouter/router.go create mode 100644 vendor/github.com/julienschmidt/httprouter/tree.go create mode 100644 vendor/github.com/kr/logfmt/decode.go create mode 100644 vendor/github.com/kr/logfmt/scanner.go create mode 100644 vendor/github.com/kr/logfmt/unquote.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/LICENSE create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/collector.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/counter.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/desc.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/doc.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/expvar_collector.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/fnv.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/gauge.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/go_collector.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/graphite/bridge.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/histogram.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/http.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/labels.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/metric.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/observer.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/process_collector.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promauto/auto.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/delegator.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/delegator_1_8.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/delegator_pre_1_8.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/http.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/instrument_client.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/instrument_client_1_8.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/promhttp/instrument_server.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/push/deprecated.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/push/push.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/registry.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/summary.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/timer.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/untyped.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/value.go create mode 100644 vendor/github.com/m3db/prometheus_client_golang/prometheus/vec.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/LICENSE create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/auth/auth.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/auth/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/auth/metadata.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/chain.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/common.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/client_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/context.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/ctxlogrus/context.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/ctxlogrus/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/ctxlogrus/noop.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/grpclogger.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/options.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/payload_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/logrus/server_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/client_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/context.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/ctxzap/context.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/ctxzap/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/grpclogger.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/options.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/payload_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/logging/zap/server_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/recovery/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/recovery/interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/recovery/options.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/retry/backoff.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/retry/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/retry/options.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/retry/retry.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/gogotestproto/fields.pb.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/interceptor_suite.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/mutex_readerwriter.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/pingservice.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/testproto/test.manual_extractfields.pb.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/testproto/test.manual_validator.pb.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/testing/testproto/test.pb.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/tracing/opentracing/client_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/tracing/opentracing/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/tracing/opentracing/id_extract.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/tracing/opentracing/metadata.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/tracing/opentracing/options.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/tracing/opentracing/server_interceptors.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/util/backoffutils/backoff.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/util/metautils/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/util/metautils/nicemd.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/util/metautils/single_key.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/validator/doc.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/validator/validator.go create mode 100644 vendor/github.com/mwitkow/go-grpc-middleware/wrappers.go create mode 100644 vendor/github.com/opentracing-contrib/go-stdlib/nethttp/LICENSE create mode 100644 vendor/github.com/opentracing-contrib/go-stdlib/nethttp/client.go create mode 100644 vendor/github.com/opentracing-contrib/go-stdlib/nethttp/doc.go create mode 100644 vendor/github.com/opentracing-contrib/go-stdlib/nethttp/server.go create mode 100644 vendor/github.com/performancecopilot/speed/LICENSE create mode 100644 vendor/github.com/performancecopilot/speed/bytewriter/bytewriter.go create mode 100644 vendor/github.com/performancecopilot/speed/bytewriter/memorymappedwriter.go create mode 100644 vendor/github.com/performancecopilot/speed/bytewriter/writer.go create mode 100644 vendor/github.com/performancecopilot/speed/client.go create mode 100644 vendor/github.com/performancecopilot/speed/config.go create mode 100644 vendor/github.com/performancecopilot/speed/countunit_string.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/acme/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/basic_histogram/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/download/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/http_counter/server.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/instance_string/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/runtime/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/simple/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/simple_string_metric/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/singleton_counter/main.go create mode 100644 vendor/github.com/performancecopilot/speed/examples/singleton_string/main.go create mode 100644 vendor/github.com/performancecopilot/speed/instance.go create mode 100644 vendor/github.com/performancecopilot/speed/instance_domain.go create mode 100644 vendor/github.com/performancecopilot/speed/metrics.go create mode 100644 vendor/github.com/performancecopilot/speed/metricsemantics_string.go create mode 100644 vendor/github.com/performancecopilot/speed/metrictype_string.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/cmd/mmvdump/main.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/mmvdump.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/pcp.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/semantics_string.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/toctype_string.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/type_string.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvdump/writer.go create mode 100644 vendor/github.com/performancecopilot/speed/mmvflag_string.go create mode 100644 vendor/github.com/performancecopilot/speed/registry.go create mode 100644 vendor/github.com/performancecopilot/speed/spaceunit_string.go create mode 100644 vendor/github.com/performancecopilot/speed/speed.go create mode 100644 vendor/github.com/performancecopilot/speed/timeunit_string.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/codahale/hdrhistogram/hdr.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/codahale/hdrhistogram/window.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/edsrzf/mmap-go/mmap.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/edsrzf/mmap-go/mmap_unix.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/edsrzf/mmap-go/mmap_windows.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/edsrzf/mmap-go/msync_unix.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/pkg/errors/errors.go create mode 100644 vendor/github.com/performancecopilot/speed/vendor/github.com/pkg/errors/stack.go create mode 100644 vendor/github.com/pkg/errors/LICENSE create mode 100644 vendor/github.com/pkg/errors/errors.go create mode 100644 vendor/github.com/pkg/errors/stack.go create mode 100644 vendor/github.com/sercand/kuberesolver/LICENSE create mode 100644 vendor/github.com/sercand/kuberesolver/builder.go create mode 100644 vendor/github.com/sercand/kuberesolver/kubernetes.go create mode 100644 vendor/github.com/sercand/kuberesolver/models.go create mode 100644 vendor/github.com/sercand/kuberesolver/stream.go create mode 100644 vendor/github.com/sercand/kuberesolver/util.go create mode 100644 vendor/github.com/sirupsen/logrus/LICENSE create mode 100644 vendor/github.com/sirupsen/logrus/alt_exit.go create mode 100644 vendor/github.com/sirupsen/logrus/doc.go create mode 100644 vendor/github.com/sirupsen/logrus/entry.go create mode 100644 vendor/github.com/sirupsen/logrus/exported.go create mode 100644 vendor/github.com/sirupsen/logrus/formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/hooks.go create mode 100644 vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go create mode 100644 vendor/github.com/sirupsen/logrus/hooks/test/test.go create mode 100644 vendor/github.com/sirupsen/logrus/json_formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/logger.go create mode 100644 vendor/github.com/sirupsen/logrus/logrus.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_bsd.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_linux.go create mode 100644 vendor/github.com/sirupsen/logrus/text_formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/writer.go create mode 100644 vendor/github.com/stretchr/objx/LICENSE create mode 100644 vendor/github.com/stretchr/objx/accessors.go create mode 100644 vendor/github.com/stretchr/objx/conversions.go create mode 100644 vendor/github.com/stretchr/objx/doc.go create mode 100644 vendor/github.com/stretchr/objx/map.go create mode 100644 vendor/github.com/stretchr/objx/mutations.go create mode 100644 vendor/github.com/stretchr/objx/security.go create mode 100644 vendor/github.com/stretchr/objx/tests.go create mode 100644 vendor/github.com/stretchr/objx/type_specific.go create mode 100644 vendor/github.com/stretchr/objx/type_specific_codegen.go create mode 100644 vendor/github.com/stretchr/objx/value.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/bypass.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/common.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/config.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/doc.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/dump.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/format.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/davecgh/go-spew/spew/spew.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/pmezard/go-difflib/difflib/difflib.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/assertion_format.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/assertion_forward.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/assertions.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/doc.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/errors.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/forward_assertions.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/assert/http_assertions.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/require/doc.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/require/forward_requirements.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/require/require.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/require/require_forward.go create mode 100644 vendor/github.com/stretchr/objx/vendor/github.com/stretchr/testify/require/requirements.go create mode 100644 vendor/github.com/stretchr/testify/require/LICENSE create mode 100644 vendor/github.com/stretchr/testify/require/doc.go create mode 100644 vendor/github.com/stretchr/testify/require/forward_requirements.go create mode 100644 vendor/github.com/stretchr/testify/require/require.go create mode 100644 vendor/github.com/stretchr/testify/require/require_forward.go create mode 100644 vendor/github.com/stretchr/testify/require/requirements.go create mode 100644 vendor/github.com/stretchr/testify/suite/LICENSE create mode 100644 vendor/github.com/stretchr/testify/suite/doc.go create mode 100644 vendor/github.com/stretchr/testify/suite/interfaces.go create mode 100644 vendor/github.com/stretchr/testify/suite/suite.go create mode 100644 vendor/github.com/uber-go/tally/LICENSE create mode 100644 vendor/github.com/uber-go/tally/example/main.go create mode 100644 vendor/github.com/uber-go/tally/histogram.go create mode 100644 vendor/github.com/uber-go/tally/instrument/call.go create mode 100644 vendor/github.com/uber-go/tally/instrument/types.go create mode 100644 vendor/github.com/uber-go/tally/key_gen.go create mode 100644 vendor/github.com/uber-go/tally/m3/config.go create mode 100644 vendor/github.com/uber-go/tally/m3/customtransports/buffered_read_transport.go create mode 100644 vendor/github.com/uber-go/tally/m3/customtransports/m3_calc_transport.go create mode 100644 vendor/github.com/uber-go/tally/m3/example/local_server.go create mode 100644 vendor/github.com/uber-go/tally/m3/example/m3_main.go create mode 100644 vendor/github.com/uber-go/tally/m3/reporter.go create mode 100644 vendor/github.com/uber-go/tally/m3/resource_pool.go create mode 100644 vendor/github.com/uber-go/tally/m3/sanitize.go create mode 100644 vendor/github.com/uber-go/tally/m3/thrift/constants.go create mode 100644 vendor/github.com/uber-go/tally/m3/thrift/m3.go create mode 100644 vendor/github.com/uber-go/tally/m3/thrift/ttypes.go create mode 100644 vendor/github.com/uber-go/tally/m3/thriftudp/multitransport.go create mode 100644 vendor/github.com/uber-go/tally/m3/thriftudp/transport.go create mode 100644 vendor/github.com/uber-go/tally/multi/reporter.go create mode 100644 vendor/github.com/uber-go/tally/pool.go create mode 100644 vendor/github.com/uber-go/tally/prometheus/config.go create mode 100644 vendor/github.com/uber-go/tally/prometheus/example/prometheus_main.go create mode 100644 vendor/github.com/uber-go/tally/prometheus/reporter.go create mode 100644 vendor/github.com/uber-go/tally/prometheus/sanitize.go create mode 100644 vendor/github.com/uber-go/tally/reporter.go create mode 100644 vendor/github.com/uber-go/tally/sanitize.go create mode 100644 vendor/github.com/uber-go/tally/scope.go create mode 100644 vendor/github.com/uber-go/tally/stats.go create mode 100644 vendor/github.com/uber-go/tally/statsd/example/statsd_main.go create mode 100644 vendor/github.com/uber-go/tally/statsd/reporter.go create mode 100644 vendor/github.com/uber-go/tally/types.go create mode 100644 vendor/github.com/uber/jaeger-client-go/LICENSE create mode 100644 vendor/github.com/uber/jaeger-client-go/baggage_setter.go create mode 100644 vendor/github.com/uber/jaeger-client-go/config/config.go create mode 100644 vendor/github.com/uber/jaeger-client-go/config/config_env.go create mode 100644 vendor/github.com/uber/jaeger-client-go/config/options.go create mode 100644 vendor/github.com/uber/jaeger-client-go/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/context.go create mode 100644 vendor/github.com/uber/jaeger-client-go/contrib_observer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/client/client.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/client/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/client/trace.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/common/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/common/json.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/endtoend/handler.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/log/logger.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/main.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/server/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/server/server.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/server/trace.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/thrift/tracetest/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/thrift/tracetest/tracedservice.go create mode 100644 vendor/github.com/uber/jaeger-client-go/crossdock/thrift/tracetest/ttypes.go create mode 100644 vendor/github.com/uber/jaeger-client-go/doc.go create mode 100644 vendor/github.com/uber/jaeger-client-go/header.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/options.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/restriction_manager.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/baggage/restriction_manager.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/spanlog/json.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/options.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/throttler.go create mode 100644 vendor/github.com/uber/jaeger-client-go/internal/throttler/throttler.go create mode 100644 vendor/github.com/uber/jaeger-client-go/interop.go create mode 100644 vendor/github.com/uber/jaeger-client-go/jaeger_tag.go create mode 100644 vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go create mode 100644 vendor/github.com/uber/jaeger-client-go/log/logger.go create mode 100644 vendor/github.com/uber/jaeger-client-go/log/zap/field.go create mode 100644 vendor/github.com/uber/jaeger-client-go/log/zap/logger.go create mode 100644 vendor/github.com/uber/jaeger-client-go/logger.go create mode 100644 vendor/github.com/uber/jaeger-client-go/metrics.go create mode 100644 vendor/github.com/uber/jaeger-client-go/observer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/process.go create mode 100644 vendor/github.com/uber/jaeger-client-go/propagation.go create mode 100644 vendor/github.com/uber/jaeger-client-go/reference.go create mode 100644 vendor/github.com/uber/jaeger-client-go/reporter.go create mode 100644 vendor/github.com/uber/jaeger-client-go/reporter_options.go create mode 100644 vendor/github.com/uber/jaeger-client-go/rpcmetrics/doc.go create mode 100644 vendor/github.com/uber/jaeger-client-go/rpcmetrics/endpoints.go create mode 100644 vendor/github.com/uber/jaeger-client-go/rpcmetrics/metrics.go create mode 100644 vendor/github.com/uber/jaeger-client-go/rpcmetrics/normalizer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/rpcmetrics/observer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/sampler.go create mode 100644 vendor/github.com/uber/jaeger-client-go/sampler_options.go create mode 100644 vendor/github.com/uber/jaeger-client-go/span.go create mode 100644 vendor/github.com/uber/jaeger-client-go/testutils/mock_agent.go create mode 100644 vendor/github.com/uber/jaeger-client-go/testutils/sampling_manager.go create mode 100644 vendor/github.com/uber/jaeger-client-go/testutils/udp_transport.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/agent.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/ttypes.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/baggagerestrictionmanager.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/ttypes.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/agent.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/ttypes.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/samplingmanager.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/ttypes.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/constants.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/ttypes.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/zipkincollector.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/application_exception.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/binary_protocol.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/compact_protocol.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/exception.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/memory_buffer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/messagetype.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/numeric.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/processor.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/protocol.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/protocol_exception.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/protocol_factory.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/rich_transport.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/serializer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/simple_json_protocol.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/transport.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/transport_exception.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/transport_factory.go create mode 100644 vendor/github.com/uber/jaeger-client-go/thrift/type.go create mode 100644 vendor/github.com/uber/jaeger-client-go/tracer.go create mode 100644 vendor/github.com/uber/jaeger-client-go/tracer_options.go create mode 100644 vendor/github.com/uber/jaeger-client-go/transport.go create mode 100644 vendor/github.com/uber/jaeger-client-go/transport/doc.go create mode 100644 vendor/github.com/uber/jaeger-client-go/transport/http.go create mode 100644 vendor/github.com/uber/jaeger-client-go/transport/zipkin/doc.go create mode 100644 vendor/github.com/uber/jaeger-client-go/transport/zipkin/http.go create mode 100644 vendor/github.com/uber/jaeger-client-go/transport_udp.go create mode 100644 vendor/github.com/uber/jaeger-client-go/utils/http_json.go create mode 100644 vendor/github.com/uber/jaeger-client-go/utils/localip.go create mode 100644 vendor/github.com/uber/jaeger-client-go/utils/rand.go create mode 100644 vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go create mode 100644 vendor/github.com/uber/jaeger-client-go/utils/udp_client.go create mode 100644 vendor/github.com/uber/jaeger-client-go/utils/utils.go create mode 100644 vendor/github.com/uber/jaeger-client-go/zipkin.go create mode 100644 vendor/github.com/uber/jaeger-client-go/zipkin/doc.go create mode 100644 vendor/github.com/uber/jaeger-client-go/zipkin/propagation.go create mode 100644 vendor/github.com/uber/jaeger-client-go/zipkin_thrift_span.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/LICENSE create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/adapters/cache.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/adapters/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/adapters/tagless.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/counter.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/expvar/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/gauge.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/go-kit/expvar/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/go-kit/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/go-kit/influx/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/go-kit/metrics.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/go-kit/prometheus/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/local.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/metrics.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/multi/multi.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/prometheus/cache.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/prometheus/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/stopwatch.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/tally/factory.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/tally/metrics.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/testutils/testutils.go create mode 100644 vendor/github.com/uber/jaeger-lib/metrics/timer.go create mode 100644 vendor/github.com/weaveworks/common/logging/dedupe.go create mode 100644 vendor/github.com/weaveworks/common/logging/global.go create mode 100644 vendor/github.com/weaveworks/common/logging/gokit.go create mode 100644 vendor/github.com/weaveworks/common/logging/interface.go create mode 100644 vendor/github.com/weaveworks/common/logging/level.go create mode 100644 vendor/github.com/weaveworks/common/logging/logrus.go create mode 100644 vendor/github.com/weaveworks/common/logging/noop.go create mode 100644 vendor/github.com/weaveworks/common/middleware/response.go create mode 100644 vendor/github.com/weaveworks/common/tracing/tracing.go create mode 100644 vendor/github.com/weaveworks/promrus/LICENSE create mode 100644 vendor/github.com/weaveworks/promrus/promrus.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/beorn7/perks/histogram/histogram.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/beorn7/perks/quantile/stream.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/beorn7/perks/topk/topk.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/bypass.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/common.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/config.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/dump.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/format.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/davecgh/go-spew/spew/spew.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/descriptor/descriptor.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/clone.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/decode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/encode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/equal.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/extensions.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/lib.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/message_set.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/pointer_reflect.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/properties.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/text.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/proto/text_parser.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/grpc/grpc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/link_grpc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/main.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/any.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/duration.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/timestamp.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/matttproud/golang_protobuf_extensions/ext/moved.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/matttproud/golang_protobuf_extensions/pbtest/deleted.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/pmezard/go-difflib/difflib/difflib.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/api/prometheus/api.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/examples/random/main.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/examples/simple/main.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/collector.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/counter.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/desc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/fnv.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/gauge.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/histogram.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/http.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/metric.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/push/push.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/registry.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/summary.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/untyped.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/value.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_golang/prometheus/vec.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_model/cpp/metrics.pb.cc create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_model/cpp/metrics.pb.h create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/client_model/go/metrics.pb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/config/config.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/config/http_config.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/expfmt/decode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/expfmt/encode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/expfmt/expfmt.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/expfmt/fuzz.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/expfmt/text_create.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/expfmt/text_parse.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/log/eventlog_formatter.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/log/log.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/log/syslog_formatter.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/alert.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/fingerprinting.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/fnv.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/labels.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/labelset.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/metric.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/model.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/signature.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/silence.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/time.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/model/value.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/promlog/flag/flag.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/promlog/log.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/route/route.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/common/version/info.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/bcache/bcache.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/bcache/get.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/buddyinfo.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/fs.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/ipvs.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/mdstat.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/mountstats.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/proc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/proc_io.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/proc_limits.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/proc_stat.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/stat.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/sysfs/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/sysfs/fs.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/xfrm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/xfs/parse.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/prometheus/procfs/xfs/xfs.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/alt_exit.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/entry.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/exported.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/formatter.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/hooks.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/hooks/test/test.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/json_formatter.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/logger.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/logrus.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/terminal_bsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/terminal_linux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/text_formatter.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/sirupsen/logrus/writer.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/assert/assertion_forward.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/assert/assertions.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/assert/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/assert/errors.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/assert/forward_assertions.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/assert/http_assertions.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/http/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/http/test_response_writer.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/http/test_round_tripper.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/mock/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/mock/mock.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/require/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/require/forward_requirements.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/require/require.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/require/require_forward.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/require/requirements.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/suite/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/suite/interfaces.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/github.com/stretchr/testify/suite/suite.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/acme.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/autocert/autocert.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/autocert/cache.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/autocert/listener.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/autocert/renewal.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/jws.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/acme/types.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bcrypt/base64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bcrypt/bcrypt.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2b.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/blake2x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2b/register.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/blake2x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blake2s/register.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blowfish/block.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blowfish/cipher.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/blowfish/const.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/bn256.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/constants.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/curve.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/gfp12.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/gfp2.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/gfp6.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/optate.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/bn256/twist.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/cast5/cast5.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_generic.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/cryptobyte/asn1.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/cryptobyte/builder.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/cryptobyte/string.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/const_amd64.h create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/const_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/curve25519.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/mul_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/curve25519/square_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/hkdf/hkdf.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/md4/md4.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/md4/md4block.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/nacl/auth/auth.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/nacl/box/box.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ocsp/ocsp.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/armor/armor.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/armor/encode.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/canonical_text.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/errors/errors.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/keys.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/compressed.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/config.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/literal.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/opaque.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/packet.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/private_key.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/public_key.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/reader.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/signature.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/packet/userid.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/read.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/openpgp/write.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/otr/libotr_test_helper.c create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/otr/otr.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/otr/smp.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/bmp-string.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/crypto.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/errors.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/mac.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/pbkdf.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/pkcs12.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/pkcs12/safebags.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/poly1305/poly1305.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/poly1305/sum_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/poly1305/sum_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/poly1305/sum_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/poly1305/sum_arm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/poly1305/sum_ref.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ripemd160/ripemd160.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/salsa20/salsa20.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/scrypt/scrypt.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/hashes.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/keccakf.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/register.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/sha3.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/shake.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/xor.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/xor_generic.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/sha3/xor_unaligned.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/agent/client.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/agent/forward.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/agent/keyring.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/agent/server.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/buffer.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/certs.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/channel.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/cipher.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/client.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/client_auth.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/common.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/connection.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/handshake.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/kex.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/keys.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/mac.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/messages.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/mux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/server.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/session.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/streamlocal.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/tcpip.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/terminal.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/util.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/test/doc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/ssh/transport.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/tea/cipher.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/twofish/twofish.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/xtea/block.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/xtea/cipher.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/crypto/xts/xts.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/asm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/asm_plan9_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/const_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/dir_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/env_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/env_unset.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/errors_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/pwd_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/race.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/race0.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/str.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/syscall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/syscall_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_darwin_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_darwin_arm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_freebsd_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_arm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_arm64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_linux_s390x.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_netbsd_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_openbsd_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/bluetooth_linux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/cap_freebsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/constants.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dev_darwin.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dev_dragonfly.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dev_freebsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dev_linux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dev_netbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dev_openbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/dirent.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/endian_big.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/endian_little.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/env_unix.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/env_unset.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/errors_freebsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/file_unix.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/flock.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/flock_linux_32bit.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/gccgo.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/gccgo_c.c create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/linux/mkall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/linux/types.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/mkpost.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/openbsd_pledge.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/pagesize_unix.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/race.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/race0.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/sockcmsg_linux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/sockcmsg_unix.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/str.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_bsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_darwin.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_darwin_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_dragonfly.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_freebsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_netbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_no_getwd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_openbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_solaris.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_unix.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/syscall_unix_gc.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/types_darwin.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/types_dragonfly.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/types_freebsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/types_netbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/types_openbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/types_solaris.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysctl_openbsd.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/asm_windows_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/asm_windows_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/dll_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/env_unset.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/env_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/eventlog.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/exec_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/memory_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/mksyscall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/race.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/race0.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/registry/key.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/registry/mksyscall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/registry/syscall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/registry/value.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/security_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/service.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/str.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/debug/log.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/debug/service.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/event.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/eventlog/install.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/eventlog/log.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/example/beep.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/example/install.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/example/main.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/example/manage.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/example/service.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/go12.c create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/go12.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/go13.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/mgr/config.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/mgr/service.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/security.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/service.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/sys_386.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/svc/sys_amd64.s create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/syscall.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/syscall_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/types_windows.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/types_windows_386.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/types_windows_amd64.go create mode 100644 vendor/github.com/weaveworks/promrus/vendor/golang.org/x/sys/windows/zsyscall_windows.go create mode 100644 vendor/go.uber.org/atomic/LICENSE.txt create mode 100644 vendor/go.uber.org/atomic/atomic.go create mode 100644 vendor/go.uber.org/atomic/string.go create mode 100644 vendor/go.uber.org/multierr/LICENSE.txt create mode 100644 vendor/go.uber.org/multierr/error.go create mode 100644 vendor/go.uber.org/zap/LICENSE.txt create mode 100644 vendor/go.uber.org/zap/array.go create mode 100644 vendor/go.uber.org/zap/benchmarks/doc.go create mode 100644 vendor/go.uber.org/zap/buffer/buffer.go create mode 100644 vendor/go.uber.org/zap/buffer/pool.go create mode 100644 vendor/go.uber.org/zap/config.go create mode 100644 vendor/go.uber.org/zap/doc.go create mode 100644 vendor/go.uber.org/zap/encoder.go create mode 100644 vendor/go.uber.org/zap/error.go create mode 100644 vendor/go.uber.org/zap/field.go create mode 100644 vendor/go.uber.org/zap/flag.go create mode 100644 vendor/go.uber.org/zap/global.go create mode 100644 vendor/go.uber.org/zap/http_handler.go create mode 100644 vendor/go.uber.org/zap/internal/bufferpool/bufferpool.go create mode 100644 vendor/go.uber.org/zap/internal/color/color.go create mode 100644 vendor/go.uber.org/zap/internal/exit/exit.go create mode 100644 vendor/go.uber.org/zap/internal/readme/readme.go create mode 100644 vendor/go.uber.org/zap/internal/ztest/doc.go create mode 100644 vendor/go.uber.org/zap/internal/ztest/timeout.go create mode 100644 vendor/go.uber.org/zap/internal/ztest/writer.go create mode 100644 vendor/go.uber.org/zap/level.go create mode 100644 vendor/go.uber.org/zap/logger.go create mode 100644 vendor/go.uber.org/zap/options.go create mode 100644 vendor/go.uber.org/zap/sink.go create mode 100644 vendor/go.uber.org/zap/stacktrace.go create mode 100644 vendor/go.uber.org/zap/sugar.go create mode 100644 vendor/go.uber.org/zap/time.go create mode 100644 vendor/go.uber.org/zap/writer.go create mode 100644 vendor/go.uber.org/zap/zapcore/console_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/core.go create mode 100644 vendor/go.uber.org/zap/zapcore/doc.go create mode 100644 vendor/go.uber.org/zap/zapcore/encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/entry.go create mode 100644 vendor/go.uber.org/zap/zapcore/error.go create mode 100644 vendor/go.uber.org/zap/zapcore/field.go create mode 100644 vendor/go.uber.org/zap/zapcore/hook.go create mode 100644 vendor/go.uber.org/zap/zapcore/json_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/level.go create mode 100644 vendor/go.uber.org/zap/zapcore/level_strings.go create mode 100644 vendor/go.uber.org/zap/zapcore/marshaler.go create mode 100644 vendor/go.uber.org/zap/zapcore/memory_encoder.go create mode 100644 vendor/go.uber.org/zap/zapcore/sampler.go create mode 100644 vendor/go.uber.org/zap/zapcore/tee.go create mode 100644 vendor/go.uber.org/zap/zapcore/write_syncer.go create mode 100644 vendor/go.uber.org/zap/zapgrpc/zapgrpc.go create mode 100644 vendor/go.uber.org/zap/zaptest/doc.go create mode 100644 vendor/go.uber.org/zap/zaptest/logger.go create mode 100644 vendor/go.uber.org/zap/zaptest/observer/logged_entry.go create mode 100644 vendor/go.uber.org/zap/zaptest/observer/observer.go create mode 100644 vendor/go.uber.org/zap/zaptest/testingt.go create mode 100644 vendor/go.uber.org/zap/zaptest/timeout.go create mode 100644 vendor/go.uber.org/zap/zaptest/writer.go create mode 100644 vendor/golang.org/x/sync/errgroup/LICENSE create mode 100644 vendor/golang.org/x/sync/errgroup/errgroup.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/COPYING create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/actions.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/app.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/args.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/cmd.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/cmd/genvalues/main.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/completions.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/doc.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/envar.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/flags.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/global.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth_unix.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/model.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/parser.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/parsers.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/templates.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/usage.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/values.go create mode 100644 vendor/gopkg.in/alecthomas/kingpin.v2/values_generated.go create mode 100644 vendor/gopkg.in/validator.v2/LICENSE create mode 100644 vendor/gopkg.in/validator.v2/builtins.go create mode 100644 vendor/gopkg.in/validator.v2/doc.go create mode 100644 vendor/gopkg.in/validator.v2/validator.go diff --git a/vendor/github.com/VividCortex/gohistogram/LICENSE b/vendor/github.com/VividCortex/gohistogram/LICENSE new file mode 100644 index 000000000..d23fea365 --- /dev/null +++ b/vendor/github.com/VividCortex/gohistogram/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 VividCortex + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/VividCortex/gohistogram/histogram.go b/vendor/github.com/VividCortex/gohistogram/histogram.go new file mode 100644 index 000000000..ede21fd31 --- /dev/null +++ b/vendor/github.com/VividCortex/gohistogram/histogram.go @@ -0,0 +1,23 @@ +package gohistogram + +// Copyright (c) 2013 VividCortex, Inc. All rights reserved. +// Please see the LICENSE file for applicable license terms. + +// Histogram is the interface that wraps the Add and Quantile methods. +type Histogram interface { + // Add adds a new value, n, to the histogram. Trimming is done + // automatically. + Add(n float64) + + // Quantile returns an approximation. + Quantile(n float64) (q float64) + + // String returns a string reprentation of the histogram, + // which is useful for printing to a terminal. + String() (str string) +} + +type bin struct { + value float64 + count float64 +} diff --git a/vendor/github.com/VividCortex/gohistogram/numerichistogram.go b/vendor/github.com/VividCortex/gohistogram/numerichistogram.go new file mode 100644 index 000000000..20dea740d --- /dev/null +++ b/vendor/github.com/VividCortex/gohistogram/numerichistogram.go @@ -0,0 +1,160 @@ +package gohistogram + +// Copyright (c) 2013 VividCortex, Inc. All rights reserved. +// Please see the LICENSE file for applicable license terms. + +import ( + "fmt" +) + +type NumericHistogram struct { + bins []bin + maxbins int + total uint64 +} + +// NewHistogram returns a new NumericHistogram with a maximum of n bins. +// +// There is no "optimal" bin count, but somewhere between 20 and 80 bins +// should be sufficient. +func NewHistogram(n int) *NumericHistogram { + return &NumericHistogram{ + bins: make([]bin, 0), + maxbins: n, + total: 0, + } +} + +func (h *NumericHistogram) Add(n float64) { + defer h.trim() + h.total++ + for i := range h.bins { + if h.bins[i].value == n { + h.bins[i].count++ + return + } + + if h.bins[i].value > n { + + newbin := bin{value: n, count: 1} + head := append(make([]bin, 0), h.bins[0:i]...) + + head = append(head, newbin) + tail := h.bins[i:] + h.bins = append(head, tail...) + return + } + } + + h.bins = append(h.bins, bin{count: 1, value: n}) +} + +func (h *NumericHistogram) Quantile(q float64) float64 { + count := q * float64(h.total) + for i := range h.bins { + count -= float64(h.bins[i].count) + + if count <= 0 { + return h.bins[i].value + } + } + + return -1 +} + +// CDF returns the value of the cumulative distribution function +// at x +func (h *NumericHistogram) CDF(x float64) float64 { + count := 0.0 + for i := range h.bins { + if h.bins[i].value <= x { + count += float64(h.bins[i].count) + } + } + + return count / float64(h.total) +} + +// Mean returns the sample mean of the distribution +func (h *NumericHistogram) Mean() float64 { + if h.total == 0 { + return 0 + } + + sum := 0.0 + + for i := range h.bins { + sum += h.bins[i].value * h.bins[i].count + } + + return sum / float64(h.total) +} + +// Variance returns the variance of the distribution +func (h *NumericHistogram) Variance() float64 { + if h.total == 0 { + return 0 + } + + sum := 0.0 + mean := h.Mean() + + for i := range h.bins { + sum += (h.bins[i].count * (h.bins[i].value - mean) * (h.bins[i].value - mean)) + } + + return sum / float64(h.total) +} + +func (h *NumericHistogram) Count() float64 { + return float64(h.total) +} + +// trim merges adjacent bins to decrease the bin count to the maximum value +func (h *NumericHistogram) trim() { + for len(h.bins) > h.maxbins { + // Find closest bins in terms of value + minDelta := 1e99 + minDeltaIndex := 0 + for i := range h.bins { + if i == 0 { + continue + } + + if delta := h.bins[i].value - h.bins[i-1].value; delta < minDelta { + minDelta = delta + minDeltaIndex = i + } + } + + // We need to merge bins minDeltaIndex-1 and minDeltaIndex + totalCount := h.bins[minDeltaIndex-1].count + h.bins[minDeltaIndex].count + mergedbin := bin{ + value: (h.bins[minDeltaIndex-1].value* + h.bins[minDeltaIndex-1].count + + h.bins[minDeltaIndex].value* + h.bins[minDeltaIndex].count) / + totalCount, // weighted average + count: totalCount, // summed heights + } + head := append(make([]bin, 0), h.bins[0:minDeltaIndex-1]...) + tail := append([]bin{mergedbin}, h.bins[minDeltaIndex+1:]...) + h.bins = append(head, tail...) + } +} + +// String returns a string reprentation of the histogram, +// which is useful for printing to a terminal. +func (h *NumericHistogram) String() (str string) { + str += fmt.Sprintln("Total:", h.total) + + for i := range h.bins { + var bar string + for j := 0; j < int(float64(h.bins[i].count)/float64(h.total)*200); j++ { + bar += "." + } + str += fmt.Sprintln(h.bins[i].value, "\t", bar) + } + + return +} diff --git a/vendor/github.com/VividCortex/gohistogram/weightedhistogram.go b/vendor/github.com/VividCortex/gohistogram/weightedhistogram.go new file mode 100644 index 000000000..16eed3719 --- /dev/null +++ b/vendor/github.com/VividCortex/gohistogram/weightedhistogram.go @@ -0,0 +1,190 @@ +// Package gohistogram contains implementations of weighted and exponential histograms. +package gohistogram + +// Copyright (c) 2013 VividCortex, Inc. All rights reserved. +// Please see the LICENSE file for applicable license terms. + +import "fmt" + +// A WeightedHistogram implements Histogram. A WeightedHistogram has bins that have values +// which are exponentially weighted moving averages. This allows you keep inserting large +// amounts of data into the histogram and approximate quantiles with recency factored in. +type WeightedHistogram struct { + bins []bin + maxbins int + total float64 + alpha float64 +} + +// NewWeightedHistogram returns a new WeightedHistogram with a maximum of n bins with a decay factor +// of alpha. +// +// There is no "optimal" bin count, but somewhere between 20 and 80 bins should be +// sufficient. +// +// Alpha should be set to 2 / (N+1), where N represents the average age of the moving window. +// For example, a 60-second window with an average age of 30 seconds would yield an +// alpha of 0.064516129. +func NewWeightedHistogram(n int, alpha float64) *WeightedHistogram { + return &WeightedHistogram{ + bins: make([]bin, 0), + maxbins: n, + total: 0, + alpha: alpha, + } +} + +func ewma(existingVal float64, newVal float64, alpha float64) (result float64) { + result = newVal*(1-alpha) + existingVal*alpha + return +} + +func (h *WeightedHistogram) scaleDown(except int) { + for i := range h.bins { + if i != except { + h.bins[i].count = ewma(h.bins[i].count, 0, h.alpha) + } + } +} + +func (h *WeightedHistogram) Add(n float64) { + defer h.trim() + for i := range h.bins { + if h.bins[i].value == n { + h.bins[i].count++ + + defer h.scaleDown(i) + return + } + + if h.bins[i].value > n { + + newbin := bin{value: n, count: 1} + head := append(make([]bin, 0), h.bins[0:i]...) + + head = append(head, newbin) + tail := h.bins[i:] + h.bins = append(head, tail...) + + defer h.scaleDown(i) + return + } + } + + h.bins = append(h.bins, bin{count: 1, value: n}) +} + +func (h *WeightedHistogram) Quantile(q float64) float64 { + count := q * h.total + for i := range h.bins { + count -= float64(h.bins[i].count) + + if count <= 0 { + return h.bins[i].value + } + } + + return -1 +} + +// CDF returns the value of the cumulative distribution function +// at x +func (h *WeightedHistogram) CDF(x float64) float64 { + count := 0.0 + for i := range h.bins { + if h.bins[i].value <= x { + count += float64(h.bins[i].count) + } + } + + return count / h.total +} + +// Mean returns the sample mean of the distribution +func (h *WeightedHistogram) Mean() float64 { + if h.total == 0 { + return 0 + } + + sum := 0.0 + + for i := range h.bins { + sum += h.bins[i].value * h.bins[i].count + } + + return sum / h.total +} + +// Variance returns the variance of the distribution +func (h *WeightedHistogram) Variance() float64 { + if h.total == 0 { + return 0 + } + + sum := 0.0 + mean := h.Mean() + + for i := range h.bins { + sum += (h.bins[i].count * (h.bins[i].value - mean) * (h.bins[i].value - mean)) + } + + return sum / h.total +} + +func (h *WeightedHistogram) Count() float64 { + return h.total +} + +func (h *WeightedHistogram) trim() { + total := 0.0 + for i := range h.bins { + total += h.bins[i].count + } + h.total = total + for len(h.bins) > h.maxbins { + + // Find closest bins in terms of value + minDelta := 1e99 + minDeltaIndex := 0 + for i := range h.bins { + if i == 0 { + continue + } + + if delta := h.bins[i].value - h.bins[i-1].value; delta < minDelta { + minDelta = delta + minDeltaIndex = i + } + } + + // We need to merge bins minDeltaIndex-1 and minDeltaIndex + totalCount := h.bins[minDeltaIndex-1].count + h.bins[minDeltaIndex].count + mergedbin := bin{ + value: (h.bins[minDeltaIndex-1].value* + h.bins[minDeltaIndex-1].count + + h.bins[minDeltaIndex].value* + h.bins[minDeltaIndex].count) / + totalCount, // weighted average + count: totalCount, // summed heights + } + head := append(make([]bin, 0), h.bins[0:minDeltaIndex-1]...) + tail := append([]bin{mergedbin}, h.bins[minDeltaIndex+1:]...) + h.bins = append(head, tail...) + } +} + +// String returns a string reprentation of the histogram, +// which is useful for printing to a terminal. +func (h *WeightedHistogram) String() (str string) { + str += fmt.Sprintln("Total:", h.total) + + for i := range h.bins { + var bar string + for j := 0; j < int(float64(h.bins[i].count)/float64(h.total)*200); j++ { + bar += "." + } + str += fmt.Sprintln(h.bins[i].value, "\t", bar) + } + + return +} diff --git a/vendor/github.com/alecthomas/template/LICENSE b/vendor/github.com/alecthomas/template/LICENSE new file mode 100644 index 000000000..744875676 --- /dev/null +++ b/vendor/github.com/alecthomas/template/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/github.com/alecthomas/template/doc.go b/vendor/github.com/alecthomas/template/doc.go new file mode 100644 index 000000000..223c595c2 --- /dev/null +++ b/vendor/github.com/alecthomas/template/doc.go @@ -0,0 +1,406 @@ +// Copyright 2011 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 template implements data-driven templates for generating textual output. + +To generate HTML output, see package html/template, which has the same interface +as this package but automatically secures HTML output against certain attacks. + +Templates are executed by applying them to a data structure. Annotations in the +template refer to elements of the data structure (typically a field of a struct +or a key in a map) to control execution and derive values to be displayed. +Execution of the template walks the structure and sets the cursor, represented +by a period '.' and called "dot", to the value at the current location in the +structure as execution proceeds. + +The input text for a template is UTF-8-encoded text in any format. +"Actions"--data evaluations or control structures--are delimited by +"{{" and "}}"; all text outside actions is copied to the output unchanged. +Actions may not span newlines, although comments can. + +Once parsed, a template may be executed safely in parallel. + +Here is a trivial example that prints "17 items are made of wool". + + type Inventory struct { + Material string + Count uint + } + sweaters := Inventory{"wool", 17} + tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}") + if err != nil { panic(err) } + err = tmpl.Execute(os.Stdout, sweaters) + if err != nil { panic(err) } + +More intricate examples appear below. + +Actions + +Here is the list of actions. "Arguments" and "pipelines" are evaluations of +data, defined in detail below. + +*/ +// {{/* a comment */}} +// A comment; discarded. May contain newlines. +// Comments do not nest and must start and end at the +// delimiters, as shown here. +/* + + {{pipeline}} + The default textual representation of the value of the pipeline + is copied to the output. + + {{if pipeline}} T1 {{end}} + If the value of the pipeline is empty, no output is generated; + otherwise, T1 is executed. The empty values are false, 0, any + nil pointer or interface value, and any array, slice, map, or + string of length zero. + Dot is unaffected. + + {{if pipeline}} T1 {{else}} T0 {{end}} + If the value of the pipeline is empty, T0 is executed; + otherwise, T1 is executed. Dot is unaffected. + + {{if pipeline}} T1 {{else if pipeline}} T0 {{end}} + To simplify the appearance of if-else chains, the else action + of an if may include another if directly; the effect is exactly + the same as writing + {{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}} + + {{range pipeline}} T1 {{end}} + The value of the pipeline must be an array, slice, map, or channel. + If the value of the pipeline has length zero, nothing is output; + otherwise, dot is set to the successive elements of the array, + slice, or map and T1 is executed. If the value is a map and the + keys are of basic type with a defined order ("comparable"), the + elements will be visited in sorted key order. + + {{range pipeline}} T1 {{else}} T0 {{end}} + The value of the pipeline must be an array, slice, map, or channel. + If the value of the pipeline has length zero, dot is unaffected and + T0 is executed; otherwise, dot is set to the successive elements + of the array, slice, or map and T1 is executed. + + {{template "name"}} + The template with the specified name is executed with nil data. + + {{template "name" pipeline}} + The template with the specified name is executed with dot set + to the value of the pipeline. + + {{with pipeline}} T1 {{end}} + If the value of the pipeline is empty, no output is generated; + otherwise, dot is set to the value of the pipeline and T1 is + executed. + + {{with pipeline}} T1 {{else}} T0 {{end}} + If the value of the pipeline is empty, dot is unaffected and T0 + is executed; otherwise, dot is set to the value of the pipeline + and T1 is executed. + +Arguments + +An argument is a simple value, denoted by one of the following. + + - A boolean, string, character, integer, floating-point, imaginary + or complex constant in Go syntax. These behave like Go's untyped + constants, although raw strings may not span newlines. + - The keyword nil, representing an untyped Go nil. + - The character '.' (period): + . + The result is the value of dot. + - A variable name, which is a (possibly empty) alphanumeric string + preceded by a dollar sign, such as + $piOver2 + or + $ + The result is the value of the variable. + Variables are described below. + - The name of a field of the data, which must be a struct, preceded + by a period, such as + .Field + The result is the value of the field. Field invocations may be + chained: + .Field1.Field2 + Fields can also be evaluated on variables, including chaining: + $x.Field1.Field2 + - The name of a key of the data, which must be a map, preceded + by a period, such as + .Key + The result is the map element value indexed by the key. + Key invocations may be chained and combined with fields to any + depth: + .Field1.Key1.Field2.Key2 + Although the key must be an alphanumeric identifier, unlike with + field names they do not need to start with an upper case letter. + Keys can also be evaluated on variables, including chaining: + $x.key1.key2 + - The name of a niladic method of the data, preceded by a period, + such as + .Method + The result is the value of invoking the method with dot as the + receiver, dot.Method(). Such a method must have one return value (of + any type) or two return values, the second of which is an error. + If it has two and the returned error is non-nil, execution terminates + and an error is returned to the caller as the value of Execute. + Method invocations may be chained and combined with fields and keys + to any depth: + .Field1.Key1.Method1.Field2.Key2.Method2 + Methods can also be evaluated on variables, including chaining: + $x.Method1.Field + - The name of a niladic function, such as + fun + The result is the value of invoking the function, fun(). The return + types and values behave as in methods. Functions and function + names are described below. + - A parenthesized instance of one the above, for grouping. The result + may be accessed by a field or map key invocation. + print (.F1 arg1) (.F2 arg2) + (.StructValuedMethod "arg").Field + +Arguments may evaluate to any type; if they are pointers the implementation +automatically indirects to the base type when required. +If an evaluation yields a function value, such as a function-valued +field of a struct, the function is not invoked automatically, but it +can be used as a truth value for an if action and the like. To invoke +it, use the call function, defined below. + +A pipeline is a possibly chained sequence of "commands". A command is a simple +value (argument) or a function or method call, possibly with multiple arguments: + + Argument + The result is the value of evaluating the argument. + .Method [Argument...] + The method can be alone or the last element of a chain but, + unlike methods in the middle of a chain, it can take arguments. + The result is the value of calling the method with the + arguments: + dot.Method(Argument1, etc.) + functionName [Argument...] + The result is the value of calling the function associated + with the name: + function(Argument1, etc.) + Functions and function names are described below. + +Pipelines + +A pipeline may be "chained" by separating a sequence of commands with pipeline +characters '|'. In a chained pipeline, the result of the each command is +passed as the last argument of the following command. The output of the final +command in the pipeline is the value of the pipeline. + +The output of a command will be either one value or two values, the second of +which has type error. If that second value is present and evaluates to +non-nil, execution terminates and the error is returned to the caller of +Execute. + +Variables + +A pipeline inside an action may initialize a variable to capture the result. +The initialization has syntax + + $variable := pipeline + +where $variable is the name of the variable. An action that declares a +variable produces no output. + +If a "range" action initializes a variable, the variable is set to the +successive elements of the iteration. Also, a "range" may declare two +variables, separated by a comma: + + range $index, $element := pipeline + +in which case $index and $element are set to the successive values of the +array/slice index or map key and element, respectively. Note that if there is +only one variable, it is assigned the element; this is opposite to the +convention in Go range clauses. + +A variable's scope extends to the "end" action of the control structure ("if", +"with", or "range") in which it is declared, or to the end of the template if +there is no such control structure. A template invocation does not inherit +variables from the point of its invocation. + +When execution begins, $ is set to the data argument passed to Execute, that is, +to the starting value of dot. + +Examples + +Here are some example one-line templates demonstrating pipelines and variables. +All produce the quoted word "output": + + {{"\"output\""}} + A string constant. + {{`"output"`}} + A raw string constant. + {{printf "%q" "output"}} + A function call. + {{"output" | printf "%q"}} + A function call whose final argument comes from the previous + command. + {{printf "%q" (print "out" "put")}} + A parenthesized argument. + {{"put" | printf "%s%s" "out" | printf "%q"}} + A more elaborate call. + {{"output" | printf "%s" | printf "%q"}} + A longer chain. + {{with "output"}}{{printf "%q" .}}{{end}} + A with action using dot. + {{with $x := "output" | printf "%q"}}{{$x}}{{end}} + A with action that creates and uses a variable. + {{with $x := "output"}}{{printf "%q" $x}}{{end}} + A with action that uses the variable in another action. + {{with $x := "output"}}{{$x | printf "%q"}}{{end}} + The same, but pipelined. + +Functions + +During execution functions are found in two function maps: first in the +template, then in the global function map. By default, no functions are defined +in the template but the Funcs method can be used to add them. + +Predefined global functions are named as follows. + + and + Returns the boolean AND of its arguments by returning the + first empty argument or the last argument, that is, + "and x y" behaves as "if x then y else x". All the + arguments are evaluated. + call + Returns the result of calling the first argument, which + must be a function, with the remaining arguments as parameters. + Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where + Y is a func-valued field, map entry, or the like. + The first argument must be the result of an evaluation + that yields a value of function type (as distinct from + a predefined function such as print). The function must + return either one or two result values, the second of which + is of type error. If the arguments don't match the function + or the returned error value is non-nil, execution stops. + html + Returns the escaped HTML equivalent of the textual + representation of its arguments. + index + Returns the result of indexing its first argument by the + following arguments. Thus "index x 1 2 3" is, in Go syntax, + x[1][2][3]. Each indexed item must be a map, slice, or array. + js + Returns the escaped JavaScript equivalent of the textual + representation of its arguments. + len + Returns the integer length of its argument. + not + Returns the boolean negation of its single argument. + or + Returns the boolean OR of its arguments by returning the + first non-empty argument or the last argument, that is, + "or x y" behaves as "if x then x else y". All the + arguments are evaluated. + print + An alias for fmt.Sprint + printf + An alias for fmt.Sprintf + println + An alias for fmt.Sprintln + urlquery + Returns the escaped value of the textual representation of + its arguments in a form suitable for embedding in a URL query. + +The boolean functions take any zero value to be false and a non-zero +value to be true. + +There is also a set of binary comparison operators defined as +functions: + + eq + Returns the boolean truth of arg1 == arg2 + ne + Returns the boolean truth of arg1 != arg2 + lt + Returns the boolean truth of arg1 < arg2 + le + Returns the boolean truth of arg1 <= arg2 + gt + Returns the boolean truth of arg1 > arg2 + ge + Returns the boolean truth of arg1 >= arg2 + +For simpler multi-way equality tests, eq (only) accepts two or more +arguments and compares the second and subsequent to the first, +returning in effect + + arg1==arg2 || arg1==arg3 || arg1==arg4 ... + +(Unlike with || in Go, however, eq is a function call and all the +arguments will be evaluated.) + +The comparison functions work on basic types only (or named basic +types, such as "type Celsius float32"). They implement the Go rules +for comparison of values, except that size and exact type are +ignored, so any integer value, signed or unsigned, may be compared +with any other integer value. (The arithmetic value is compared, +not the bit pattern, so all negative integers are less than all +unsigned integers.) However, as usual, one may not compare an int +with a float32 and so on. + +Associated templates + +Each template is named by a string specified when it is created. Also, each +template is associated with zero or more other templates that it may invoke by +name; such associations are transitive and form a name space of templates. + +A template may use a template invocation to instantiate another associated +template; see the explanation of the "template" action above. The name must be +that of a template associated with the template that contains the invocation. + +Nested template definitions + +When parsing a template, another template may be defined and associated with the +template being parsed. Template definitions must appear at the top level of the +template, much like global variables in a Go program. + +The syntax of such definitions is to surround each template declaration with a +"define" and "end" action. + +The define action names the template being created by providing a string +constant. Here is a simple example: + + `{{define "T1"}}ONE{{end}} + {{define "T2"}}TWO{{end}} + {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}} + {{template "T3"}}` + +This defines two templates, T1 and T2, and a third T3 that invokes the other two +when it is executed. Finally it invokes T3. If executed this template will +produce the text + + ONE TWO + +By construction, a template may reside in only one association. If it's +necessary to have a template addressable from multiple associations, the +template definition must be parsed multiple times to create distinct *Template +values, or must be copied with the Clone or AddParseTree method. + +Parse may be called multiple times to assemble the various associated templates; +see the ParseFiles and ParseGlob functions and methods for simple ways to parse +related templates stored in files. + +A template may be executed directly or through ExecuteTemplate, which executes +an associated template identified by name. To invoke our example above, we +might write, + + err := tmpl.Execute(os.Stdout, "no data needed") + if err != nil { + log.Fatalf("execution failed: %s", err) + } + +or to invoke a particular template explicitly by name, + + err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed") + if err != nil { + log.Fatalf("execution failed: %s", err) + } + +*/ +package template diff --git a/vendor/github.com/alecthomas/template/exec.go b/vendor/github.com/alecthomas/template/exec.go new file mode 100644 index 000000000..c3078e5d0 --- /dev/null +++ b/vendor/github.com/alecthomas/template/exec.go @@ -0,0 +1,845 @@ +// Copyright 2011 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 template + +import ( + "bytes" + "fmt" + "io" + "reflect" + "runtime" + "sort" + "strings" + + "github.com/alecthomas/template/parse" +) + +// state represents the state of an execution. It's not part of the +// template so that multiple executions of the same template +// can execute in parallel. +type state struct { + tmpl *Template + wr io.Writer + node parse.Node // current node, for errors + vars []variable // push-down stack of variable values. +} + +// variable holds the dynamic value of a variable such as $, $x etc. +type variable struct { + name string + value reflect.Value +} + +// push pushes a new variable on the stack. +func (s *state) push(name string, value reflect.Value) { + s.vars = append(s.vars, variable{name, value}) +} + +// mark returns the length of the variable stack. +func (s *state) mark() int { + return len(s.vars) +} + +// pop pops the variable stack up to the mark. +func (s *state) pop(mark int) { + s.vars = s.vars[0:mark] +} + +// setVar overwrites the top-nth variable on the stack. Used by range iterations. +func (s *state) setVar(n int, value reflect.Value) { + s.vars[len(s.vars)-n].value = value +} + +// varValue returns the value of the named variable. +func (s *state) varValue(name string) reflect.Value { + for i := s.mark() - 1; i >= 0; i-- { + if s.vars[i].name == name { + return s.vars[i].value + } + } + s.errorf("undefined variable: %s", name) + return zero +} + +var zero reflect.Value + +// at marks the state to be on node n, for error reporting. +func (s *state) at(node parse.Node) { + s.node = node +} + +// doublePercent returns the string with %'s replaced by %%, if necessary, +// so it can be used safely inside a Printf format string. +func doublePercent(str string) string { + if strings.Contains(str, "%") { + str = strings.Replace(str, "%", "%%", -1) + } + return str +} + +// errorf formats the error and terminates processing. +func (s *state) errorf(format string, args ...interface{}) { + name := doublePercent(s.tmpl.Name()) + if s.node == nil { + format = fmt.Sprintf("template: %s: %s", name, format) + } else { + location, context := s.tmpl.ErrorContext(s.node) + format = fmt.Sprintf("template: %s: executing %q at <%s>: %s", location, name, doublePercent(context), format) + } + panic(fmt.Errorf(format, args...)) +} + +// errRecover is the handler that turns panics into returns from the top +// level of Parse. +func errRecover(errp *error) { + e := recover() + if e != nil { + switch err := e.(type) { + case runtime.Error: + panic(e) + case error: + *errp = err + default: + panic(e) + } + } +} + +// ExecuteTemplate applies the template associated with t that has the given name +// to the specified data object and writes the output to wr. +// If an error occurs executing the template or writing its output, +// execution stops, but partial results may already have been written to +// the output writer. +// A template may be executed safely in parallel. +func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error { + tmpl := t.tmpl[name] + if tmpl == nil { + return fmt.Errorf("template: no template %q associated with template %q", name, t.name) + } + return tmpl.Execute(wr, data) +} + +// Execute applies a parsed template to the specified data object, +// and writes the output to wr. +// If an error occurs executing the template or writing its output, +// execution stops, but partial results may already have been written to +// the output writer. +// A template may be executed safely in parallel. +func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { + defer errRecover(&err) + value := reflect.ValueOf(data) + state := &state{ + tmpl: t, + wr: wr, + vars: []variable{{"$", value}}, + } + t.init() + if t.Tree == nil || t.Root == nil { + var b bytes.Buffer + for name, tmpl := range t.tmpl { + if tmpl.Tree == nil || tmpl.Root == nil { + continue + } + if b.Len() > 0 { + b.WriteString(", ") + } + fmt.Fprintf(&b, "%q", name) + } + var s string + if b.Len() > 0 { + s = "; defined templates are: " + b.String() + } + state.errorf("%q is an incomplete or empty template%s", t.Name(), s) + } + state.walk(value, t.Root) + return +} + +// Walk functions step through the major pieces of the template structure, +// generating output as they go. +func (s *state) walk(dot reflect.Value, node parse.Node) { + s.at(node) + switch node := node.(type) { + case *parse.ActionNode: + // Do not pop variables so they persist until next end. + // Also, if the action declares variables, don't print the result. + val := s.evalPipeline(dot, node.Pipe) + if len(node.Pipe.Decl) == 0 { + s.printValue(node, val) + } + case *parse.IfNode: + s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList) + case *parse.ListNode: + for _, node := range node.Nodes { + s.walk(dot, node) + } + case *parse.RangeNode: + s.walkRange(dot, node) + case *parse.TemplateNode: + s.walkTemplate(dot, node) + case *parse.TextNode: + if _, err := s.wr.Write(node.Text); err != nil { + s.errorf("%s", err) + } + case *parse.WithNode: + s.walkIfOrWith(parse.NodeWith, dot, node.Pipe, node.List, node.ElseList) + default: + s.errorf("unknown node: %s", node) + } +} + +// walkIfOrWith walks an 'if' or 'with' node. The two control structures +// are identical in behavior except that 'with' sets dot. +func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.PipeNode, list, elseList *parse.ListNode) { + defer s.pop(s.mark()) + val := s.evalPipeline(dot, pipe) + truth, ok := isTrue(val) + if !ok { + s.errorf("if/with can't use %v", val) + } + if truth { + if typ == parse.NodeWith { + s.walk(val, list) + } else { + s.walk(dot, list) + } + } else if elseList != nil { + s.walk(dot, elseList) + } +} + +// isTrue reports whether the value is 'true', in the sense of not the zero of its type, +// and whether the value has a meaningful truth value. +func isTrue(val reflect.Value) (truth, ok bool) { + if !val.IsValid() { + // Something like var x interface{}, never set. It's a form of nil. + return false, true + } + switch val.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + truth = val.Len() > 0 + case reflect.Bool: + truth = val.Bool() + case reflect.Complex64, reflect.Complex128: + truth = val.Complex() != 0 + case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: + truth = !val.IsNil() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + truth = val.Int() != 0 + case reflect.Float32, reflect.Float64: + truth = val.Float() != 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + truth = val.Uint() != 0 + case reflect.Struct: + truth = true // Struct values are always true. + default: + return + } + return truth, true +} + +func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { + s.at(r) + defer s.pop(s.mark()) + val, _ := indirect(s.evalPipeline(dot, r.Pipe)) + // mark top of stack before any variables in the body are pushed. + mark := s.mark() + oneIteration := func(index, elem reflect.Value) { + // Set top var (lexically the second if there are two) to the element. + if len(r.Pipe.Decl) > 0 { + s.setVar(1, elem) + } + // Set next var (lexically the first if there are two) to the index. + if len(r.Pipe.Decl) > 1 { + s.setVar(2, index) + } + s.walk(elem, r.List) + s.pop(mark) + } + switch val.Kind() { + case reflect.Array, reflect.Slice: + if val.Len() == 0 { + break + } + for i := 0; i < val.Len(); i++ { + oneIteration(reflect.ValueOf(i), val.Index(i)) + } + return + case reflect.Map: + if val.Len() == 0 { + break + } + for _, key := range sortKeys(val.MapKeys()) { + oneIteration(key, val.MapIndex(key)) + } + return + case reflect.Chan: + if val.IsNil() { + break + } + i := 0 + for ; ; i++ { + elem, ok := val.Recv() + if !ok { + break + } + oneIteration(reflect.ValueOf(i), elem) + } + if i == 0 { + break + } + return + case reflect.Invalid: + break // An invalid value is likely a nil map, etc. and acts like an empty map. + default: + s.errorf("range can't iterate over %v", val) + } + if r.ElseList != nil { + s.walk(dot, r.ElseList) + } +} + +func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) { + s.at(t) + tmpl := s.tmpl.tmpl[t.Name] + if tmpl == nil { + s.errorf("template %q not defined", t.Name) + } + // Variables declared by the pipeline persist. + dot = s.evalPipeline(dot, t.Pipe) + newState := *s + newState.tmpl = tmpl + // No dynamic scoping: template invocations inherit no variables. + newState.vars = []variable{{"$", dot}} + newState.walk(dot, tmpl.Root) +} + +// Eval functions evaluate pipelines, commands, and their elements and extract +// values from the data structure by examining fields, calling methods, and so on. +// The printing of those values happens only through walk functions. + +// evalPipeline returns the value acquired by evaluating a pipeline. If the +// pipeline has a variable declaration, the variable will be pushed on the +// stack. Callers should therefore pop the stack after they are finished +// executing commands depending on the pipeline value. +func (s *state) evalPipeline(dot reflect.Value, pipe *parse.PipeNode) (value reflect.Value) { + if pipe == nil { + return + } + s.at(pipe) + for _, cmd := range pipe.Cmds { + value = s.evalCommand(dot, cmd, value) // previous value is this one's final arg. + // If the object has type interface{}, dig down one level to the thing inside. + if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 { + value = reflect.ValueOf(value.Interface()) // lovely! + } + } + for _, variable := range pipe.Decl { + s.push(variable.Ident[0], value) + } + return value +} + +func (s *state) notAFunction(args []parse.Node, final reflect.Value) { + if len(args) > 1 || final.IsValid() { + s.errorf("can't give argument to non-function %s", args[0]) + } +} + +func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode, final reflect.Value) reflect.Value { + firstWord := cmd.Args[0] + switch n := firstWord.(type) { + case *parse.FieldNode: + return s.evalFieldNode(dot, n, cmd.Args, final) + case *parse.ChainNode: + return s.evalChainNode(dot, n, cmd.Args, final) + case *parse.IdentifierNode: + // Must be a function. + return s.evalFunction(dot, n, cmd, cmd.Args, final) + case *parse.PipeNode: + // Parenthesized pipeline. The arguments are all inside the pipeline; final is ignored. + return s.evalPipeline(dot, n) + case *parse.VariableNode: + return s.evalVariableNode(dot, n, cmd.Args, final) + } + s.at(firstWord) + s.notAFunction(cmd.Args, final) + switch word := firstWord.(type) { + case *parse.BoolNode: + return reflect.ValueOf(word.True) + case *parse.DotNode: + return dot + case *parse.NilNode: + s.errorf("nil is not a command") + case *parse.NumberNode: + return s.idealConstant(word) + case *parse.StringNode: + return reflect.ValueOf(word.Text) + } + s.errorf("can't evaluate command %q", firstWord) + panic("not reached") +} + +// idealConstant is called to return the value of a number in a context where +// we don't know the type. In that case, the syntax of the number tells us +// its type, and we use Go rules to resolve. Note there is no such thing as +// a uint ideal constant in this situation - the value must be of int type. +func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value { + // These are ideal constants but we don't know the type + // and we have no context. (If it was a method argument, + // we'd know what we need.) The syntax guides us to some extent. + s.at(constant) + switch { + case constant.IsComplex: + return reflect.ValueOf(constant.Complex128) // incontrovertible. + case constant.IsFloat && !isHexConstant(constant.Text) && strings.IndexAny(constant.Text, ".eE") >= 0: + return reflect.ValueOf(constant.Float64) + case constant.IsInt: + n := int(constant.Int64) + if int64(n) != constant.Int64 { + s.errorf("%s overflows int", constant.Text) + } + return reflect.ValueOf(n) + case constant.IsUint: + s.errorf("%s overflows int", constant.Text) + } + return zero +} + +func isHexConstant(s string) bool { + return len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') +} + +func (s *state) evalFieldNode(dot reflect.Value, field *parse.FieldNode, args []parse.Node, final reflect.Value) reflect.Value { + s.at(field) + return s.evalFieldChain(dot, dot, field, field.Ident, args, final) +} + +func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNode, args []parse.Node, final reflect.Value) reflect.Value { + s.at(chain) + // (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields. + pipe := s.evalArg(dot, nil, chain.Node) + if len(chain.Field) == 0 { + s.errorf("internal error: no fields in evalChainNode") + } + return s.evalFieldChain(dot, pipe, chain, chain.Field, args, final) +} + +func (s *state) evalVariableNode(dot reflect.Value, variable *parse.VariableNode, args []parse.Node, final reflect.Value) reflect.Value { + // $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields. + s.at(variable) + value := s.varValue(variable.Ident[0]) + if len(variable.Ident) == 1 { + s.notAFunction(args, final) + return value + } + return s.evalFieldChain(dot, value, variable, variable.Ident[1:], args, final) +} + +// evalFieldChain evaluates .X.Y.Z possibly followed by arguments. +// dot is the environment in which to evaluate arguments, while +// receiver is the value being walked along the chain. +func (s *state) evalFieldChain(dot, receiver reflect.Value, node parse.Node, ident []string, args []parse.Node, final reflect.Value) reflect.Value { + n := len(ident) + for i := 0; i < n-1; i++ { + receiver = s.evalField(dot, ident[i], node, nil, zero, receiver) + } + // Now if it's a method, it gets the arguments. + return s.evalField(dot, ident[n-1], node, args, final, receiver) +} + +func (s *state) evalFunction(dot reflect.Value, node *parse.IdentifierNode, cmd parse.Node, args []parse.Node, final reflect.Value) reflect.Value { + s.at(node) + name := node.Ident + function, ok := findFunction(name, s.tmpl) + if !ok { + s.errorf("%q is not a defined function", name) + } + return s.evalCall(dot, function, cmd, name, args, final) +} + +// evalField evaluates an expression like (.Field) or (.Field arg1 arg2). +// The 'final' argument represents the return value from the preceding +// value of the pipeline, if any. +func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value { + if !receiver.IsValid() { + return zero + } + typ := receiver.Type() + receiver, _ = indirect(receiver) + // Unless it's an interface, need to get to a value of type *T to guarantee + // we see all methods of T and *T. + ptr := receiver + if ptr.Kind() != reflect.Interface && ptr.CanAddr() { + ptr = ptr.Addr() + } + if method := ptr.MethodByName(fieldName); method.IsValid() { + return s.evalCall(dot, method, node, fieldName, args, final) + } + hasArgs := len(args) > 1 || final.IsValid() + // It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil. + receiver, isNil := indirect(receiver) + if isNil { + s.errorf("nil pointer evaluating %s.%s", typ, fieldName) + } + switch receiver.Kind() { + case reflect.Struct: + tField, ok := receiver.Type().FieldByName(fieldName) + if ok { + field := receiver.FieldByIndex(tField.Index) + if tField.PkgPath != "" { // field is unexported + s.errorf("%s is an unexported field of struct type %s", fieldName, typ) + } + // If it's a function, we must call it. + if hasArgs { + s.errorf("%s has arguments but cannot be invoked as function", fieldName) + } + return field + } + s.errorf("%s is not a field of struct type %s", fieldName, typ) + case reflect.Map: + // If it's a map, attempt to use the field name as a key. + nameVal := reflect.ValueOf(fieldName) + if nameVal.Type().AssignableTo(receiver.Type().Key()) { + if hasArgs { + s.errorf("%s is not a method but has arguments", fieldName) + } + return receiver.MapIndex(nameVal) + } + } + s.errorf("can't evaluate field %s in type %s", fieldName, typ) + panic("not reached") +} + +var ( + errorType = reflect.TypeOf((*error)(nil)).Elem() + fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() +) + +// evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so +// it looks just like a function call. The arg list, if non-nil, includes (in the manner of the shell), arg[0] +// as the function itself. +func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name string, args []parse.Node, final reflect.Value) reflect.Value { + if args != nil { + args = args[1:] // Zeroth arg is function name/node; not passed to function. + } + typ := fun.Type() + numIn := len(args) + if final.IsValid() { + numIn++ + } + numFixed := len(args) + if typ.IsVariadic() { + numFixed = typ.NumIn() - 1 // last arg is the variadic one. + if numIn < numFixed { + s.errorf("wrong number of args for %s: want at least %d got %d", name, typ.NumIn()-1, len(args)) + } + } else if numIn < typ.NumIn()-1 || !typ.IsVariadic() && numIn != typ.NumIn() { + s.errorf("wrong number of args for %s: want %d got %d", name, typ.NumIn(), len(args)) + } + if !goodFunc(typ) { + // TODO: This could still be a confusing error; maybe goodFunc should provide info. + s.errorf("can't call method/function %q with %d results", name, typ.NumOut()) + } + // Build the arg list. + argv := make([]reflect.Value, numIn) + // Args must be evaluated. Fixed args first. + i := 0 + for ; i < numFixed && i < len(args); i++ { + argv[i] = s.evalArg(dot, typ.In(i), args[i]) + } + // Now the ... args. + if typ.IsVariadic() { + argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice. + for ; i < len(args); i++ { + argv[i] = s.evalArg(dot, argType, args[i]) + } + } + // Add final value if necessary. + if final.IsValid() { + t := typ.In(typ.NumIn() - 1) + if typ.IsVariadic() { + t = t.Elem() + } + argv[i] = s.validateType(final, t) + } + result := fun.Call(argv) + // If we have an error that is not nil, stop execution and return that error to the caller. + if len(result) == 2 && !result[1].IsNil() { + s.at(node) + s.errorf("error calling %s: %s", name, result[1].Interface().(error)) + } + return result[0] +} + +// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero. +func canBeNil(typ reflect.Type) bool { + switch typ.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return true + } + return false +} + +// validateType guarantees that the value is valid and assignable to the type. +func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value { + if !value.IsValid() { + if typ == nil || canBeNil(typ) { + // An untyped nil interface{}. Accept as a proper nil value. + return reflect.Zero(typ) + } + s.errorf("invalid value; expected %s", typ) + } + if typ != nil && !value.Type().AssignableTo(typ) { + if value.Kind() == reflect.Interface && !value.IsNil() { + value = value.Elem() + if value.Type().AssignableTo(typ) { + return value + } + // fallthrough + } + // Does one dereference or indirection work? We could do more, as we + // do with method receivers, but that gets messy and method receivers + // are much more constrained, so it makes more sense there than here. + // Besides, one is almost always all you need. + switch { + case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ): + value = value.Elem() + if !value.IsValid() { + s.errorf("dereference of nil pointer of type %s", typ) + } + case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr(): + value = value.Addr() + default: + s.errorf("wrong type for value; expected %s; got %s", typ, value.Type()) + } + } + return value +} + +func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) reflect.Value { + s.at(n) + switch arg := n.(type) { + case *parse.DotNode: + return s.validateType(dot, typ) + case *parse.NilNode: + if canBeNil(typ) { + return reflect.Zero(typ) + } + s.errorf("cannot assign nil to %s", typ) + case *parse.FieldNode: + return s.validateType(s.evalFieldNode(dot, arg, []parse.Node{n}, zero), typ) + case *parse.VariableNode: + return s.validateType(s.evalVariableNode(dot, arg, nil, zero), typ) + case *parse.PipeNode: + return s.validateType(s.evalPipeline(dot, arg), typ) + case *parse.IdentifierNode: + return s.evalFunction(dot, arg, arg, nil, zero) + case *parse.ChainNode: + return s.validateType(s.evalChainNode(dot, arg, nil, zero), typ) + } + switch typ.Kind() { + case reflect.Bool: + return s.evalBool(typ, n) + case reflect.Complex64, reflect.Complex128: + return s.evalComplex(typ, n) + case reflect.Float32, reflect.Float64: + return s.evalFloat(typ, n) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return s.evalInteger(typ, n) + case reflect.Interface: + if typ.NumMethod() == 0 { + return s.evalEmptyInterface(dot, n) + } + case reflect.String: + return s.evalString(typ, n) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return s.evalUnsignedInteger(typ, n) + } + s.errorf("can't handle %s for arg of type %s", n, typ) + panic("not reached") +} + +func (s *state) evalBool(typ reflect.Type, n parse.Node) reflect.Value { + s.at(n) + if n, ok := n.(*parse.BoolNode); ok { + value := reflect.New(typ).Elem() + value.SetBool(n.True) + return value + } + s.errorf("expected bool; found %s", n) + panic("not reached") +} + +func (s *state) evalString(typ reflect.Type, n parse.Node) reflect.Value { + s.at(n) + if n, ok := n.(*parse.StringNode); ok { + value := reflect.New(typ).Elem() + value.SetString(n.Text) + return value + } + s.errorf("expected string; found %s", n) + panic("not reached") +} + +func (s *state) evalInteger(typ reflect.Type, n parse.Node) reflect.Value { + s.at(n) + if n, ok := n.(*parse.NumberNode); ok && n.IsInt { + value := reflect.New(typ).Elem() + value.SetInt(n.Int64) + return value + } + s.errorf("expected integer; found %s", n) + panic("not reached") +} + +func (s *state) evalUnsignedInteger(typ reflect.Type, n parse.Node) reflect.Value { + s.at(n) + if n, ok := n.(*parse.NumberNode); ok && n.IsUint { + value := reflect.New(typ).Elem() + value.SetUint(n.Uint64) + return value + } + s.errorf("expected unsigned integer; found %s", n) + panic("not reached") +} + +func (s *state) evalFloat(typ reflect.Type, n parse.Node) reflect.Value { + s.at(n) + if n, ok := n.(*parse.NumberNode); ok && n.IsFloat { + value := reflect.New(typ).Elem() + value.SetFloat(n.Float64) + return value + } + s.errorf("expected float; found %s", n) + panic("not reached") +} + +func (s *state) evalComplex(typ reflect.Type, n parse.Node) reflect.Value { + if n, ok := n.(*parse.NumberNode); ok && n.IsComplex { + value := reflect.New(typ).Elem() + value.SetComplex(n.Complex128) + return value + } + s.errorf("expected complex; found %s", n) + panic("not reached") +} + +func (s *state) evalEmptyInterface(dot reflect.Value, n parse.Node) reflect.Value { + s.at(n) + switch n := n.(type) { + case *parse.BoolNode: + return reflect.ValueOf(n.True) + case *parse.DotNode: + return dot + case *parse.FieldNode: + return s.evalFieldNode(dot, n, nil, zero) + case *parse.IdentifierNode: + return s.evalFunction(dot, n, n, nil, zero) + case *parse.NilNode: + // NilNode is handled in evalArg, the only place that calls here. + s.errorf("evalEmptyInterface: nil (can't happen)") + case *parse.NumberNode: + return s.idealConstant(n) + case *parse.StringNode: + return reflect.ValueOf(n.Text) + case *parse.VariableNode: + return s.evalVariableNode(dot, n, nil, zero) + case *parse.PipeNode: + return s.evalPipeline(dot, n) + } + s.errorf("can't handle assignment of %s to empty interface argument", n) + panic("not reached") +} + +// indirect returns the item at the end of indirection, and a bool to indicate if it's nil. +// We indirect through pointers and empty interfaces (only) because +// non-empty interfaces have methods we might need. +func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { + for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { + if v.IsNil() { + return v, true + } + if v.Kind() == reflect.Interface && v.NumMethod() > 0 { + break + } + } + return v, false +} + +// printValue writes the textual representation of the value to the output of +// the template. +func (s *state) printValue(n parse.Node, v reflect.Value) { + s.at(n) + iface, ok := printableValue(v) + if !ok { + s.errorf("can't print %s of type %s", n, v.Type()) + } + fmt.Fprint(s.wr, iface) +} + +// printableValue returns the, possibly indirected, interface value inside v that +// is best for a call to formatted printer. +func printableValue(v reflect.Value) (interface{}, bool) { + if v.Kind() == reflect.Ptr { + v, _ = indirect(v) // fmt.Fprint handles nil. + } + if !v.IsValid() { + return "", true + } + + if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) { + if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) { + v = v.Addr() + } else { + switch v.Kind() { + case reflect.Chan, reflect.Func: + return nil, false + } + } + } + return v.Interface(), true +} + +// Types to help sort the keys in a map for reproducible output. + +type rvs []reflect.Value + +func (x rvs) Len() int { return len(x) } +func (x rvs) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +type rvInts struct{ rvs } + +func (x rvInts) Less(i, j int) bool { return x.rvs[i].Int() < x.rvs[j].Int() } + +type rvUints struct{ rvs } + +func (x rvUints) Less(i, j int) bool { return x.rvs[i].Uint() < x.rvs[j].Uint() } + +type rvFloats struct{ rvs } + +func (x rvFloats) Less(i, j int) bool { return x.rvs[i].Float() < x.rvs[j].Float() } + +type rvStrings struct{ rvs } + +func (x rvStrings) Less(i, j int) bool { return x.rvs[i].String() < x.rvs[j].String() } + +// sortKeys sorts (if it can) the slice of reflect.Values, which is a slice of map keys. +func sortKeys(v []reflect.Value) []reflect.Value { + if len(v) <= 1 { + return v + } + switch v[0].Kind() { + case reflect.Float32, reflect.Float64: + sort.Sort(rvFloats{v}) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + sort.Sort(rvInts{v}) + case reflect.String: + sort.Sort(rvStrings{v}) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + sort.Sort(rvUints{v}) + } + return v +} diff --git a/vendor/github.com/alecthomas/template/funcs.go b/vendor/github.com/alecthomas/template/funcs.go new file mode 100644 index 000000000..39ee5ed68 --- /dev/null +++ b/vendor/github.com/alecthomas/template/funcs.go @@ -0,0 +1,598 @@ +// Copyright 2011 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 template + +import ( + "bytes" + "errors" + "fmt" + "io" + "net/url" + "reflect" + "strings" + "unicode" + "unicode/utf8" +) + +// FuncMap is the type of the map defining the mapping from names to functions. +// Each function must have either a single return value, or two return values of +// which the second has type error. In that case, if the second (error) +// return value evaluates to non-nil during execution, execution terminates and +// Execute returns that error. +type FuncMap map[string]interface{} + +var builtins = FuncMap{ + "and": and, + "call": call, + "html": HTMLEscaper, + "index": index, + "js": JSEscaper, + "len": length, + "not": not, + "or": or, + "print": fmt.Sprint, + "printf": fmt.Sprintf, + "println": fmt.Sprintln, + "urlquery": URLQueryEscaper, + + // Comparisons + "eq": eq, // == + "ge": ge, // >= + "gt": gt, // > + "le": le, // <= + "lt": lt, // < + "ne": ne, // != +} + +var builtinFuncs = createValueFuncs(builtins) + +// createValueFuncs turns a FuncMap into a map[string]reflect.Value +func createValueFuncs(funcMap FuncMap) map[string]reflect.Value { + m := make(map[string]reflect.Value) + addValueFuncs(m, funcMap) + return m +} + +// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values. +func addValueFuncs(out map[string]reflect.Value, in FuncMap) { + for name, fn := range in { + v := reflect.ValueOf(fn) + if v.Kind() != reflect.Func { + panic("value for " + name + " not a function") + } + if !goodFunc(v.Type()) { + panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut())) + } + out[name] = v + } +} + +// addFuncs adds to values the functions in funcs. It does no checking of the input - +// call addValueFuncs first. +func addFuncs(out, in FuncMap) { + for name, fn := range in { + out[name] = fn + } +} + +// goodFunc checks that the function or method has the right result signature. +func goodFunc(typ reflect.Type) bool { + // We allow functions with 1 result or 2 results where the second is an error. + switch { + case typ.NumOut() == 1: + return true + case typ.NumOut() == 2 && typ.Out(1) == errorType: + return true + } + return false +} + +// findFunction looks for a function in the template, and global map. +func findFunction(name string, tmpl *Template) (reflect.Value, bool) { + if tmpl != nil && tmpl.common != nil { + if fn := tmpl.execFuncs[name]; fn.IsValid() { + return fn, true + } + } + if fn := builtinFuncs[name]; fn.IsValid() { + return fn, true + } + return reflect.Value{}, false +} + +// Indexing. + +// index returns the result of indexing its first argument by the following +// arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each +// indexed item must be a map, slice, or array. +func index(item interface{}, indices ...interface{}) (interface{}, error) { + v := reflect.ValueOf(item) + for _, i := range indices { + index := reflect.ValueOf(i) + var isNil bool + if v, isNil = indirect(v); isNil { + return nil, fmt.Errorf("index of nil pointer") + } + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.String: + var x int64 + switch index.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + x = index.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + x = int64(index.Uint()) + default: + return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type()) + } + if x < 0 || x >= int64(v.Len()) { + return nil, fmt.Errorf("index out of range: %d", x) + } + v = v.Index(int(x)) + case reflect.Map: + if !index.IsValid() { + index = reflect.Zero(v.Type().Key()) + } + if !index.Type().AssignableTo(v.Type().Key()) { + return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type()) + } + if x := v.MapIndex(index); x.IsValid() { + v = x + } else { + v = reflect.Zero(v.Type().Elem()) + } + default: + return nil, fmt.Errorf("can't index item of type %s", v.Type()) + } + } + return v.Interface(), nil +} + +// Length + +// length returns the length of the item, with an error if it has no defined length. +func length(item interface{}) (int, error) { + v, isNil := indirect(reflect.ValueOf(item)) + if isNil { + return 0, fmt.Errorf("len of nil pointer") + } + switch v.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: + return v.Len(), nil + } + return 0, fmt.Errorf("len of type %s", v.Type()) +} + +// Function invocation + +// call returns the result of evaluating the first argument as a function. +// The function must return 1 result, or 2 results, the second of which is an error. +func call(fn interface{}, args ...interface{}) (interface{}, error) { + v := reflect.ValueOf(fn) + typ := v.Type() + if typ.Kind() != reflect.Func { + return nil, fmt.Errorf("non-function of type %s", typ) + } + if !goodFunc(typ) { + return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut()) + } + numIn := typ.NumIn() + var dddType reflect.Type + if typ.IsVariadic() { + if len(args) < numIn-1 { + return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1) + } + dddType = typ.In(numIn - 1).Elem() + } else { + if len(args) != numIn { + return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn) + } + } + argv := make([]reflect.Value, len(args)) + for i, arg := range args { + value := reflect.ValueOf(arg) + // Compute the expected type. Clumsy because of variadics. + var argType reflect.Type + if !typ.IsVariadic() || i < numIn-1 { + argType = typ.In(i) + } else { + argType = dddType + } + if !value.IsValid() && canBeNil(argType) { + value = reflect.Zero(argType) + } + if !value.Type().AssignableTo(argType) { + return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType) + } + argv[i] = value + } + result := v.Call(argv) + if len(result) == 2 && !result[1].IsNil() { + return result[0].Interface(), result[1].Interface().(error) + } + return result[0].Interface(), nil +} + +// Boolean logic. + +func truth(a interface{}) bool { + t, _ := isTrue(reflect.ValueOf(a)) + return t +} + +// and computes the Boolean AND of its arguments, returning +// the first false argument it encounters, or the last argument. +func and(arg0 interface{}, args ...interface{}) interface{} { + if !truth(arg0) { + return arg0 + } + for i := range args { + arg0 = args[i] + if !truth(arg0) { + break + } + } + return arg0 +} + +// or computes the Boolean OR of its arguments, returning +// the first true argument it encounters, or the last argument. +func or(arg0 interface{}, args ...interface{}) interface{} { + if truth(arg0) { + return arg0 + } + for i := range args { + arg0 = args[i] + if truth(arg0) { + break + } + } + return arg0 +} + +// not returns the Boolean negation of its argument. +func not(arg interface{}) (truth bool) { + truth, _ = isTrue(reflect.ValueOf(arg)) + return !truth +} + +// Comparison. + +// TODO: Perhaps allow comparison between signed and unsigned integers. + +var ( + errBadComparisonType = errors.New("invalid type for comparison") + errBadComparison = errors.New("incompatible types for comparison") + errNoComparison = errors.New("missing argument for comparison") +) + +type kind int + +const ( + invalidKind kind = iota + boolKind + complexKind + intKind + floatKind + integerKind + stringKind + uintKind +) + +func basicKind(v reflect.Value) (kind, error) { + switch v.Kind() { + case reflect.Bool: + return boolKind, nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return intKind, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return uintKind, nil + case reflect.Float32, reflect.Float64: + return floatKind, nil + case reflect.Complex64, reflect.Complex128: + return complexKind, nil + case reflect.String: + return stringKind, nil + } + return invalidKind, errBadComparisonType +} + +// eq evaluates the comparison a == b || a == c || ... +func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) { + v1 := reflect.ValueOf(arg1) + k1, err := basicKind(v1) + if err != nil { + return false, err + } + if len(arg2) == 0 { + return false, errNoComparison + } + for _, arg := range arg2 { + v2 := reflect.ValueOf(arg) + k2, err := basicKind(v2) + if err != nil { + return false, err + } + truth := false + if k1 != k2 { + // Special case: Can compare integer values regardless of type's sign. + switch { + case k1 == intKind && k2 == uintKind: + truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint() + case k1 == uintKind && k2 == intKind: + truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int()) + default: + return false, errBadComparison + } + } else { + switch k1 { + case boolKind: + truth = v1.Bool() == v2.Bool() + case complexKind: + truth = v1.Complex() == v2.Complex() + case floatKind: + truth = v1.Float() == v2.Float() + case intKind: + truth = v1.Int() == v2.Int() + case stringKind: + truth = v1.String() == v2.String() + case uintKind: + truth = v1.Uint() == v2.Uint() + default: + panic("invalid kind") + } + } + if truth { + return true, nil + } + } + return false, nil +} + +// ne evaluates the comparison a != b. +func ne(arg1, arg2 interface{}) (bool, error) { + // != is the inverse of ==. + equal, err := eq(arg1, arg2) + return !equal, err +} + +// lt evaluates the comparison a < b. +func lt(arg1, arg2 interface{}) (bool, error) { + v1 := reflect.ValueOf(arg1) + k1, err := basicKind(v1) + if err != nil { + return false, err + } + v2 := reflect.ValueOf(arg2) + k2, err := basicKind(v2) + if err != nil { + return false, err + } + truth := false + if k1 != k2 { + // Special case: Can compare integer values regardless of type's sign. + switch { + case k1 == intKind && k2 == uintKind: + truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() + case k1 == uintKind && k2 == intKind: + truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int()) + default: + return false, errBadComparison + } + } else { + switch k1 { + case boolKind, complexKind: + return false, errBadComparisonType + case floatKind: + truth = v1.Float() < v2.Float() + case intKind: + truth = v1.Int() < v2.Int() + case stringKind: + truth = v1.String() < v2.String() + case uintKind: + truth = v1.Uint() < v2.Uint() + default: + panic("invalid kind") + } + } + return truth, nil +} + +// le evaluates the comparison <= b. +func le(arg1, arg2 interface{}) (bool, error) { + // <= is < or ==. + lessThan, err := lt(arg1, arg2) + if lessThan || err != nil { + return lessThan, err + } + return eq(arg1, arg2) +} + +// gt evaluates the comparison a > b. +func gt(arg1, arg2 interface{}) (bool, error) { + // > is the inverse of <=. + lessOrEqual, err := le(arg1, arg2) + if err != nil { + return false, err + } + return !lessOrEqual, nil +} + +// ge evaluates the comparison a >= b. +func ge(arg1, arg2 interface{}) (bool, error) { + // >= is the inverse of <. + lessThan, err := lt(arg1, arg2) + if err != nil { + return false, err + } + return !lessThan, nil +} + +// HTML escaping. + +var ( + htmlQuot = []byte(""") // shorter than """ + htmlApos = []byte("'") // shorter than "'" and apos was not in HTML until HTML5 + htmlAmp = []byte("&") + htmlLt = []byte("<") + htmlGt = []byte(">") +) + +// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b. +func HTMLEscape(w io.Writer, b []byte) { + last := 0 + for i, c := range b { + var html []byte + switch c { + case '"': + html = htmlQuot + case '\'': + html = htmlApos + case '&': + html = htmlAmp + case '<': + html = htmlLt + case '>': + html = htmlGt + default: + continue + } + w.Write(b[last:i]) + w.Write(html) + last = i + 1 + } + w.Write(b[last:]) +} + +// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s. +func HTMLEscapeString(s string) string { + // Avoid allocation if we can. + if strings.IndexAny(s, `'"&<>`) < 0 { + return s + } + var b bytes.Buffer + HTMLEscape(&b, []byte(s)) + return b.String() +} + +// HTMLEscaper returns the escaped HTML equivalent of the textual +// representation of its arguments. +func HTMLEscaper(args ...interface{}) string { + return HTMLEscapeString(evalArgs(args)) +} + +// JavaScript escaping. + +var ( + jsLowUni = []byte(`\u00`) + hex = []byte("0123456789ABCDEF") + + jsBackslash = []byte(`\\`) + jsApos = []byte(`\'`) + jsQuot = []byte(`\"`) + jsLt = []byte(`\x3C`) + jsGt = []byte(`\x3E`) +) + +// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. +func JSEscape(w io.Writer, b []byte) { + last := 0 + for i := 0; i < len(b); i++ { + c := b[i] + + if !jsIsSpecial(rune(c)) { + // fast path: nothing to do + continue + } + w.Write(b[last:i]) + + if c < utf8.RuneSelf { + // Quotes, slashes and angle brackets get quoted. + // Control characters get written as \u00XX. + switch c { + case '\\': + w.Write(jsBackslash) + case '\'': + w.Write(jsApos) + case '"': + w.Write(jsQuot) + case '<': + w.Write(jsLt) + case '>': + w.Write(jsGt) + default: + w.Write(jsLowUni) + t, b := c>>4, c&0x0f + w.Write(hex[t : t+1]) + w.Write(hex[b : b+1]) + } + } else { + // Unicode rune. + r, size := utf8.DecodeRune(b[i:]) + if unicode.IsPrint(r) { + w.Write(b[i : i+size]) + } else { + fmt.Fprintf(w, "\\u%04X", r) + } + i += size - 1 + } + last = i + 1 + } + w.Write(b[last:]) +} + +// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s. +func JSEscapeString(s string) string { + // Avoid allocation if we can. + if strings.IndexFunc(s, jsIsSpecial) < 0 { + return s + } + var b bytes.Buffer + JSEscape(&b, []byte(s)) + return b.String() +} + +func jsIsSpecial(r rune) bool { + switch r { + case '\\', '\'', '"', '<', '>': + return true + } + return r < ' ' || utf8.RuneSelf <= r +} + +// JSEscaper returns the escaped JavaScript equivalent of the textual +// representation of its arguments. +func JSEscaper(args ...interface{}) string { + return JSEscapeString(evalArgs(args)) +} + +// URLQueryEscaper returns the escaped value of the textual representation of +// its arguments in a form suitable for embedding in a URL query. +func URLQueryEscaper(args ...interface{}) string { + return url.QueryEscape(evalArgs(args)) +} + +// evalArgs formats the list of arguments into a string. It is therefore equivalent to +// fmt.Sprint(args...) +// except that each argument is indirected (if a pointer), as required, +// using the same rules as the default string evaluation during template +// execution. +func evalArgs(args []interface{}) string { + ok := false + var s string + // Fast path for simple common case. + if len(args) == 1 { + s, ok = args[0].(string) + } + if !ok { + for i, arg := range args { + a, ok := printableValue(reflect.ValueOf(arg)) + if ok { + args[i] = a + } // else left fmt do its thing + } + s = fmt.Sprint(args...) + } + return s +} diff --git a/vendor/github.com/alecthomas/template/helper.go b/vendor/github.com/alecthomas/template/helper.go new file mode 100644 index 000000000..3636fb54d --- /dev/null +++ b/vendor/github.com/alecthomas/template/helper.go @@ -0,0 +1,108 @@ +// Copyright 2011 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. + +// Helper functions to make constructing templates easier. + +package template + +import ( + "fmt" + "io/ioutil" + "path/filepath" +) + +// Functions and methods to parse templates. + +// Must is a helper that wraps a call to a function returning (*Template, error) +// and panics if the error is non-nil. It is intended for use in variable +// initializations such as +// var t = template.Must(template.New("name").Parse("text")) +func Must(t *Template, err error) *Template { + if err != nil { + panic(err) + } + return t +} + +// ParseFiles creates a new Template and parses the template definitions from +// the named files. The returned template's name will have the (base) name and +// (parsed) contents of the first file. There must be at least one file. +// If an error occurs, parsing stops and the returned *Template is nil. +func ParseFiles(filenames ...string) (*Template, error) { + return parseFiles(nil, filenames...) +} + +// ParseFiles parses the named files and associates the resulting templates with +// t. If an error occurs, parsing stops and the returned template is nil; +// otherwise it is t. There must be at least one file. +func (t *Template) ParseFiles(filenames ...string) (*Template, error) { + return parseFiles(t, filenames...) +} + +// parseFiles is the helper for the method and function. If the argument +// template is nil, it is created from the first file. +func parseFiles(t *Template, filenames ...string) (*Template, error) { + if len(filenames) == 0 { + // Not really a problem, but be consistent. + return nil, fmt.Errorf("template: no files named in call to ParseFiles") + } + for _, filename := range filenames { + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + s := string(b) + name := filepath.Base(filename) + // First template becomes return value if not already defined, + // and we use that one for subsequent New calls to associate + // all the templates together. Also, if this file has the same name + // as t, this file becomes the contents of t, so + // t, err := New(name).Funcs(xxx).ParseFiles(name) + // works. Otherwise we create a new template associated with t. + var tmpl *Template + if t == nil { + t = New(name) + } + if name == t.Name() { + tmpl = t + } else { + tmpl = t.New(name) + } + _, err = tmpl.Parse(s) + if err != nil { + return nil, err + } + } + return t, nil +} + +// ParseGlob creates a new Template and parses the template definitions from the +// files identified by the pattern, which must match at least one file. The +// returned template will have the (base) name and (parsed) contents of the +// first file matched by the pattern. ParseGlob is equivalent to calling +// ParseFiles with the list of files matched by the pattern. +func ParseGlob(pattern string) (*Template, error) { + return parseGlob(nil, pattern) +} + +// ParseGlob parses the template definitions in the files identified by the +// pattern and associates the resulting templates with t. The pattern is +// processed by filepath.Glob and must match at least one file. ParseGlob is +// equivalent to calling t.ParseFiles with the list of files matched by the +// pattern. +func (t *Template) ParseGlob(pattern string) (*Template, error) { + return parseGlob(t, pattern) +} + +// parseGlob is the implementation of the function and method ParseGlob. +func parseGlob(t *Template, pattern string) (*Template, error) { + filenames, err := filepath.Glob(pattern) + if err != nil { + return nil, err + } + if len(filenames) == 0 { + return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) + } + return parseFiles(t, filenames...) +} diff --git a/vendor/github.com/alecthomas/template/parse/lex.go b/vendor/github.com/alecthomas/template/parse/lex.go new file mode 100644 index 000000000..55f1c051e --- /dev/null +++ b/vendor/github.com/alecthomas/template/parse/lex.go @@ -0,0 +1,556 @@ +// Copyright 2011 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 parse + +import ( + "fmt" + "strings" + "unicode" + "unicode/utf8" +) + +// item represents a token or text string returned from the scanner. +type item struct { + typ itemType // The type of this item. + pos Pos // The starting position, in bytes, of this item in the input string. + val string // The value of this item. +} + +func (i item) String() string { + switch { + case i.typ == itemEOF: + return "EOF" + case i.typ == itemError: + return i.val + case i.typ > itemKeyword: + return fmt.Sprintf("<%s>", i.val) + case len(i.val) > 10: + return fmt.Sprintf("%.10q...", i.val) + } + return fmt.Sprintf("%q", i.val) +} + +// itemType identifies the type of lex items. +type itemType int + +const ( + itemError itemType = iota // error occurred; value is text of error + itemBool // boolean constant + itemChar // printable ASCII character; grab bag for comma etc. + itemCharConstant // character constant + itemComplex // complex constant (1+2i); imaginary is just a number + itemColonEquals // colon-equals (':=') introducing a declaration + itemEOF + itemField // alphanumeric identifier starting with '.' + itemIdentifier // alphanumeric identifier not starting with '.' + itemLeftDelim // left action delimiter + itemLeftParen // '(' inside action + itemNumber // simple number, including imaginary + itemPipe // pipe symbol + itemRawString // raw quoted string (includes quotes) + itemRightDelim // right action delimiter + itemElideNewline // elide newline after right delim + itemRightParen // ')' inside action + itemSpace // run of spaces separating arguments + itemString // quoted string (includes quotes) + itemText // plain text + itemVariable // variable starting with '$', such as '$' or '$1' or '$hello' + // Keywords appear after all the rest. + itemKeyword // used only to delimit the keywords + itemDot // the cursor, spelled '.' + itemDefine // define keyword + itemElse // else keyword + itemEnd // end keyword + itemIf // if keyword + itemNil // the untyped nil constant, easiest to treat as a keyword + itemRange // range keyword + itemTemplate // template keyword + itemWith // with keyword +) + +var key = map[string]itemType{ + ".": itemDot, + "define": itemDefine, + "else": itemElse, + "end": itemEnd, + "if": itemIf, + "range": itemRange, + "nil": itemNil, + "template": itemTemplate, + "with": itemWith, +} + +const eof = -1 + +// stateFn represents the state of the scanner as a function that returns the next state. +type stateFn func(*lexer) stateFn + +// lexer holds the state of the scanner. +type lexer struct { + name string // the name of the input; used only for error reports + input string // the string being scanned + leftDelim string // start of action + rightDelim string // end of action + state stateFn // the next lexing function to enter + pos Pos // current position in the input + start Pos // start position of this item + width Pos // width of last rune read from input + lastPos Pos // position of most recent item returned by nextItem + items chan item // channel of scanned items + parenDepth int // nesting depth of ( ) exprs +} + +// next returns the next rune in the input. +func (l *lexer) next() rune { + if int(l.pos) >= len(l.input) { + l.width = 0 + return eof + } + r, w := utf8.DecodeRuneInString(l.input[l.pos:]) + l.width = Pos(w) + l.pos += l.width + return r +} + +// peek returns but does not consume the next rune in the input. +func (l *lexer) peek() rune { + r := l.next() + l.backup() + return r +} + +// backup steps back one rune. Can only be called once per call of next. +func (l *lexer) backup() { + l.pos -= l.width +} + +// emit passes an item back to the client. +func (l *lexer) emit(t itemType) { + l.items <- item{t, l.start, l.input[l.start:l.pos]} + l.start = l.pos +} + +// ignore skips over the pending input before this point. +func (l *lexer) ignore() { + l.start = l.pos +} + +// accept consumes the next rune if it's from the valid set. +func (l *lexer) accept(valid string) bool { + if strings.IndexRune(valid, l.next()) >= 0 { + return true + } + l.backup() + return false +} + +// acceptRun consumes a run of runes from the valid set. +func (l *lexer) acceptRun(valid string) { + for strings.IndexRune(valid, l.next()) >= 0 { + } + l.backup() +} + +// lineNumber reports which line we're on, based on the position of +// the previous item returned by nextItem. Doing it this way +// means we don't have to worry about peek double counting. +func (l *lexer) lineNumber() int { + return 1 + strings.Count(l.input[:l.lastPos], "\n") +} + +// errorf returns an error token and terminates the scan by passing +// back a nil pointer that will be the next state, terminating l.nextItem. +func (l *lexer) errorf(format string, args ...interface{}) stateFn { + l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)} + return nil +} + +// nextItem returns the next item from the input. +func (l *lexer) nextItem() item { + item := <-l.items + l.lastPos = item.pos + return item +} + +// lex creates a new scanner for the input string. +func lex(name, input, left, right string) *lexer { + if left == "" { + left = leftDelim + } + if right == "" { + right = rightDelim + } + l := &lexer{ + name: name, + input: input, + leftDelim: left, + rightDelim: right, + items: make(chan item), + } + go l.run() + return l +} + +// run runs the state machine for the lexer. +func (l *lexer) run() { + for l.state = lexText; l.state != nil; { + l.state = l.state(l) + } +} + +// state functions + +const ( + leftDelim = "{{" + rightDelim = "}}" + leftComment = "/*" + rightComment = "*/" +) + +// lexText scans until an opening action delimiter, "{{". +func lexText(l *lexer) stateFn { + for { + if strings.HasPrefix(l.input[l.pos:], l.leftDelim) { + if l.pos > l.start { + l.emit(itemText) + } + return lexLeftDelim + } + if l.next() == eof { + break + } + } + // Correctly reached EOF. + if l.pos > l.start { + l.emit(itemText) + } + l.emit(itemEOF) + return nil +} + +// lexLeftDelim scans the left delimiter, which is known to be present. +func lexLeftDelim(l *lexer) stateFn { + l.pos += Pos(len(l.leftDelim)) + if strings.HasPrefix(l.input[l.pos:], leftComment) { + return lexComment + } + l.emit(itemLeftDelim) + l.parenDepth = 0 + return lexInsideAction +} + +// lexComment scans a comment. The left comment marker is known to be present. +func lexComment(l *lexer) stateFn { + l.pos += Pos(len(leftComment)) + i := strings.Index(l.input[l.pos:], rightComment) + if i < 0 { + return l.errorf("unclosed comment") + } + l.pos += Pos(i + len(rightComment)) + if !strings.HasPrefix(l.input[l.pos:], l.rightDelim) { + return l.errorf("comment ends before closing delimiter") + + } + l.pos += Pos(len(l.rightDelim)) + l.ignore() + return lexText +} + +// lexRightDelim scans the right delimiter, which is known to be present. +func lexRightDelim(l *lexer) stateFn { + l.pos += Pos(len(l.rightDelim)) + l.emit(itemRightDelim) + if l.peek() == '\\' { + l.pos++ + l.emit(itemElideNewline) + } + return lexText +} + +// lexInsideAction scans the elements inside action delimiters. +func lexInsideAction(l *lexer) stateFn { + // Either number, quoted string, or identifier. + // Spaces separate arguments; runs of spaces turn into itemSpace. + // Pipe symbols separate and are emitted. + if strings.HasPrefix(l.input[l.pos:], l.rightDelim+"\\") || strings.HasPrefix(l.input[l.pos:], l.rightDelim) { + if l.parenDepth == 0 { + return lexRightDelim + } + return l.errorf("unclosed left paren") + } + switch r := l.next(); { + case r == eof || isEndOfLine(r): + return l.errorf("unclosed action") + case isSpace(r): + return lexSpace + case r == ':': + if l.next() != '=' { + return l.errorf("expected :=") + } + l.emit(itemColonEquals) + case r == '|': + l.emit(itemPipe) + case r == '"': + return lexQuote + case r == '`': + return lexRawQuote + case r == '$': + return lexVariable + case r == '\'': + return lexChar + case r == '.': + // special look-ahead for ".field" so we don't break l.backup(). + if l.pos < Pos(len(l.input)) { + r := l.input[l.pos] + if r < '0' || '9' < r { + return lexField + } + } + fallthrough // '.' can start a number. + case r == '+' || r == '-' || ('0' <= r && r <= '9'): + l.backup() + return lexNumber + case isAlphaNumeric(r): + l.backup() + return lexIdentifier + case r == '(': + l.emit(itemLeftParen) + l.parenDepth++ + return lexInsideAction + case r == ')': + l.emit(itemRightParen) + l.parenDepth-- + if l.parenDepth < 0 { + return l.errorf("unexpected right paren %#U", r) + } + return lexInsideAction + case r <= unicode.MaxASCII && unicode.IsPrint(r): + l.emit(itemChar) + return lexInsideAction + default: + return l.errorf("unrecognized character in action: %#U", r) + } + return lexInsideAction +} + +// lexSpace scans a run of space characters. +// One space has already been seen. +func lexSpace(l *lexer) stateFn { + for isSpace(l.peek()) { + l.next() + } + l.emit(itemSpace) + return lexInsideAction +} + +// lexIdentifier scans an alphanumeric. +func lexIdentifier(l *lexer) stateFn { +Loop: + for { + switch r := l.next(); { + case isAlphaNumeric(r): + // absorb. + default: + l.backup() + word := l.input[l.start:l.pos] + if !l.atTerminator() { + return l.errorf("bad character %#U", r) + } + switch { + case key[word] > itemKeyword: + l.emit(key[word]) + case word[0] == '.': + l.emit(itemField) + case word == "true", word == "false": + l.emit(itemBool) + default: + l.emit(itemIdentifier) + } + break Loop + } + } + return lexInsideAction +} + +// lexField scans a field: .Alphanumeric. +// The . has been scanned. +func lexField(l *lexer) stateFn { + return lexFieldOrVariable(l, itemField) +} + +// lexVariable scans a Variable: $Alphanumeric. +// The $ has been scanned. +func lexVariable(l *lexer) stateFn { + if l.atTerminator() { // Nothing interesting follows -> "$". + l.emit(itemVariable) + return lexInsideAction + } + return lexFieldOrVariable(l, itemVariable) +} + +// lexVariable scans a field or variable: [.$]Alphanumeric. +// The . or $ has been scanned. +func lexFieldOrVariable(l *lexer, typ itemType) stateFn { + if l.atTerminator() { // Nothing interesting follows -> "." or "$". + if typ == itemVariable { + l.emit(itemVariable) + } else { + l.emit(itemDot) + } + return lexInsideAction + } + var r rune + for { + r = l.next() + if !isAlphaNumeric(r) { + l.backup() + break + } + } + if !l.atTerminator() { + return l.errorf("bad character %#U", r) + } + l.emit(typ) + return lexInsideAction +} + +// atTerminator reports whether the input is at valid termination character to +// appear after an identifier. Breaks .X.Y into two pieces. Also catches cases +// like "$x+2" not being acceptable without a space, in case we decide one +// day to implement arithmetic. +func (l *lexer) atTerminator() bool { + r := l.peek() + if isSpace(r) || isEndOfLine(r) { + return true + } + switch r { + case eof, '.', ',', '|', ':', ')', '(': + return true + } + // Does r start the delimiter? This can be ambiguous (with delim=="//", $x/2 will + // succeed but should fail) but only in extremely rare cases caused by willfully + // bad choice of delimiter. + if rd, _ := utf8.DecodeRuneInString(l.rightDelim); rd == r { + return true + } + return false +} + +// lexChar scans a character constant. The initial quote is already +// scanned. Syntax checking is done by the parser. +func lexChar(l *lexer) stateFn { +Loop: + for { + switch l.next() { + case '\\': + if r := l.next(); r != eof && r != '\n' { + break + } + fallthrough + case eof, '\n': + return l.errorf("unterminated character constant") + case '\'': + break Loop + } + } + l.emit(itemCharConstant) + return lexInsideAction +} + +// lexNumber scans a number: decimal, octal, hex, float, or imaginary. This +// isn't a perfect number scanner - for instance it accepts "." and "0x0.2" +// and "089" - but when it's wrong the input is invalid and the parser (via +// strconv) will notice. +func lexNumber(l *lexer) stateFn { + if !l.scanNumber() { + return l.errorf("bad number syntax: %q", l.input[l.start:l.pos]) + } + if sign := l.peek(); sign == '+' || sign == '-' { + // Complex: 1+2i. No spaces, must end in 'i'. + if !l.scanNumber() || l.input[l.pos-1] != 'i' { + return l.errorf("bad number syntax: %q", l.input[l.start:l.pos]) + } + l.emit(itemComplex) + } else { + l.emit(itemNumber) + } + return lexInsideAction +} + +func (l *lexer) scanNumber() bool { + // Optional leading sign. + l.accept("+-") + // Is it hex? + digits := "0123456789" + if l.accept("0") && l.accept("xX") { + digits = "0123456789abcdefABCDEF" + } + l.acceptRun(digits) + if l.accept(".") { + l.acceptRun(digits) + } + if l.accept("eE") { + l.accept("+-") + l.acceptRun("0123456789") + } + // Is it imaginary? + l.accept("i") + // Next thing mustn't be alphanumeric. + if isAlphaNumeric(l.peek()) { + l.next() + return false + } + return true +} + +// lexQuote scans a quoted string. +func lexQuote(l *lexer) stateFn { +Loop: + for { + switch l.next() { + case '\\': + if r := l.next(); r != eof && r != '\n' { + break + } + fallthrough + case eof, '\n': + return l.errorf("unterminated quoted string") + case '"': + break Loop + } + } + l.emit(itemString) + return lexInsideAction +} + +// lexRawQuote scans a raw quoted string. +func lexRawQuote(l *lexer) stateFn { +Loop: + for { + switch l.next() { + case eof, '\n': + return l.errorf("unterminated raw quoted string") + case '`': + break Loop + } + } + l.emit(itemRawString) + return lexInsideAction +} + +// isSpace reports whether r is a space character. +func isSpace(r rune) bool { + return r == ' ' || r == '\t' +} + +// isEndOfLine reports whether r is an end-of-line character. +func isEndOfLine(r rune) bool { + return r == '\r' || r == '\n' +} + +// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore. +func isAlphaNumeric(r rune) bool { + return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) +} diff --git a/vendor/github.com/alecthomas/template/parse/node.go b/vendor/github.com/alecthomas/template/parse/node.go new file mode 100644 index 000000000..55c37f6db --- /dev/null +++ b/vendor/github.com/alecthomas/template/parse/node.go @@ -0,0 +1,834 @@ +// Copyright 2011 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. + +// Parse nodes. + +package parse + +import ( + "bytes" + "fmt" + "strconv" + "strings" +) + +var textFormat = "%s" // Changed to "%q" in tests for better error messages. + +// A Node is an element in the parse tree. The interface is trivial. +// The interface contains an unexported method so that only +// types local to this package can satisfy it. +type Node interface { + Type() NodeType + String() string + // Copy does a deep copy of the Node and all its components. + // To avoid type assertions, some XxxNodes also have specialized + // CopyXxx methods that return *XxxNode. + Copy() Node + Position() Pos // byte position of start of node in full original input string + // tree returns the containing *Tree. + // It is unexported so all implementations of Node are in this package. + tree() *Tree +} + +// NodeType identifies the type of a parse tree node. +type NodeType int + +// Pos represents a byte position in the original input text from which +// this template was parsed. +type Pos int + +func (p Pos) Position() Pos { + return p +} + +// Type returns itself and provides an easy default implementation +// for embedding in a Node. Embedded in all non-trivial Nodes. +func (t NodeType) Type() NodeType { + return t +} + +const ( + NodeText NodeType = iota // Plain text. + NodeAction // A non-control action such as a field evaluation. + NodeBool // A boolean constant. + NodeChain // A sequence of field accesses. + NodeCommand // An element of a pipeline. + NodeDot // The cursor, dot. + nodeElse // An else action. Not added to tree. + nodeEnd // An end action. Not added to tree. + NodeField // A field or method name. + NodeIdentifier // An identifier; always a function name. + NodeIf // An if action. + NodeList // A list of Nodes. + NodeNil // An untyped nil constant. + NodeNumber // A numerical constant. + NodePipe // A pipeline of commands. + NodeRange // A range action. + NodeString // A string constant. + NodeTemplate // A template invocation action. + NodeVariable // A $ variable. + NodeWith // A with action. +) + +// Nodes. + +// ListNode holds a sequence of nodes. +type ListNode struct { + NodeType + Pos + tr *Tree + Nodes []Node // The element nodes in lexical order. +} + +func (t *Tree) newList(pos Pos) *ListNode { + return &ListNode{tr: t, NodeType: NodeList, Pos: pos} +} + +func (l *ListNode) append(n Node) { + l.Nodes = append(l.Nodes, n) +} + +func (l *ListNode) tree() *Tree { + return l.tr +} + +func (l *ListNode) String() string { + b := new(bytes.Buffer) + for _, n := range l.Nodes { + fmt.Fprint(b, n) + } + return b.String() +} + +func (l *ListNode) CopyList() *ListNode { + if l == nil { + return l + } + n := l.tr.newList(l.Pos) + for _, elem := range l.Nodes { + n.append(elem.Copy()) + } + return n +} + +func (l *ListNode) Copy() Node { + return l.CopyList() +} + +// TextNode holds plain text. +type TextNode struct { + NodeType + Pos + tr *Tree + Text []byte // The text; may span newlines. +} + +func (t *Tree) newText(pos Pos, text string) *TextNode { + return &TextNode{tr: t, NodeType: NodeText, Pos: pos, Text: []byte(text)} +} + +func (t *TextNode) String() string { + return fmt.Sprintf(textFormat, t.Text) +} + +func (t *TextNode) tree() *Tree { + return t.tr +} + +func (t *TextNode) Copy() Node { + return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: append([]byte{}, t.Text...)} +} + +// PipeNode holds a pipeline with optional declaration +type PipeNode struct { + NodeType + Pos + tr *Tree + Line int // The line number in the input (deprecated; kept for compatibility) + Decl []*VariableNode // Variable declarations in lexical order. + Cmds []*CommandNode // The commands in lexical order. +} + +func (t *Tree) newPipeline(pos Pos, line int, decl []*VariableNode) *PipeNode { + return &PipeNode{tr: t, NodeType: NodePipe, Pos: pos, Line: line, Decl: decl} +} + +func (p *PipeNode) append(command *CommandNode) { + p.Cmds = append(p.Cmds, command) +} + +func (p *PipeNode) String() string { + s := "" + if len(p.Decl) > 0 { + for i, v := range p.Decl { + if i > 0 { + s += ", " + } + s += v.String() + } + s += " := " + } + for i, c := range p.Cmds { + if i > 0 { + s += " | " + } + s += c.String() + } + return s +} + +func (p *PipeNode) tree() *Tree { + return p.tr +} + +func (p *PipeNode) CopyPipe() *PipeNode { + if p == nil { + return p + } + var decl []*VariableNode + for _, d := range p.Decl { + decl = append(decl, d.Copy().(*VariableNode)) + } + n := p.tr.newPipeline(p.Pos, p.Line, decl) + for _, c := range p.Cmds { + n.append(c.Copy().(*CommandNode)) + } + return n +} + +func (p *PipeNode) Copy() Node { + return p.CopyPipe() +} + +// ActionNode holds an action (something bounded by delimiters). +// Control actions have their own nodes; ActionNode represents simple +// ones such as field evaluations and parenthesized pipelines. +type ActionNode struct { + NodeType + Pos + tr *Tree + Line int // The line number in the input (deprecated; kept for compatibility) + Pipe *PipeNode // The pipeline in the action. +} + +func (t *Tree) newAction(pos Pos, line int, pipe *PipeNode) *ActionNode { + return &ActionNode{tr: t, NodeType: NodeAction, Pos: pos, Line: line, Pipe: pipe} +} + +func (a *ActionNode) String() string { + return fmt.Sprintf("{{%s}}", a.Pipe) + +} + +func (a *ActionNode) tree() *Tree { + return a.tr +} + +func (a *ActionNode) Copy() Node { + return a.tr.newAction(a.Pos, a.Line, a.Pipe.CopyPipe()) + +} + +// CommandNode holds a command (a pipeline inside an evaluating action). +type CommandNode struct { + NodeType + Pos + tr *Tree + Args []Node // Arguments in lexical order: Identifier, field, or constant. +} + +func (t *Tree) newCommand(pos Pos) *CommandNode { + return &CommandNode{tr: t, NodeType: NodeCommand, Pos: pos} +} + +func (c *CommandNode) append(arg Node) { + c.Args = append(c.Args, arg) +} + +func (c *CommandNode) String() string { + s := "" + for i, arg := range c.Args { + if i > 0 { + s += " " + } + if arg, ok := arg.(*PipeNode); ok { + s += "(" + arg.String() + ")" + continue + } + s += arg.String() + } + return s +} + +func (c *CommandNode) tree() *Tree { + return c.tr +} + +func (c *CommandNode) Copy() Node { + if c == nil { + return c + } + n := c.tr.newCommand(c.Pos) + for _, c := range c.Args { + n.append(c.Copy()) + } + return n +} + +// IdentifierNode holds an identifier. +type IdentifierNode struct { + NodeType + Pos + tr *Tree + Ident string // The identifier's name. +} + +// NewIdentifier returns a new IdentifierNode with the given identifier name. +func NewIdentifier(ident string) *IdentifierNode { + return &IdentifierNode{NodeType: NodeIdentifier, Ident: ident} +} + +// SetPos sets the position. NewIdentifier is a public method so we can't modify its signature. +// Chained for convenience. +// TODO: fix one day? +func (i *IdentifierNode) SetPos(pos Pos) *IdentifierNode { + i.Pos = pos + return i +} + +// SetTree sets the parent tree for the node. NewIdentifier is a public method so we can't modify its signature. +// Chained for convenience. +// TODO: fix one day? +func (i *IdentifierNode) SetTree(t *Tree) *IdentifierNode { + i.tr = t + return i +} + +func (i *IdentifierNode) String() string { + return i.Ident +} + +func (i *IdentifierNode) tree() *Tree { + return i.tr +} + +func (i *IdentifierNode) Copy() Node { + return NewIdentifier(i.Ident).SetTree(i.tr).SetPos(i.Pos) +} + +// VariableNode holds a list of variable names, possibly with chained field +// accesses. The dollar sign is part of the (first) name. +type VariableNode struct { + NodeType + Pos + tr *Tree + Ident []string // Variable name and fields in lexical order. +} + +func (t *Tree) newVariable(pos Pos, ident string) *VariableNode { + return &VariableNode{tr: t, NodeType: NodeVariable, Pos: pos, Ident: strings.Split(ident, ".")} +} + +func (v *VariableNode) String() string { + s := "" + for i, id := range v.Ident { + if i > 0 { + s += "." + } + s += id + } + return s +} + +func (v *VariableNode) tree() *Tree { + return v.tr +} + +func (v *VariableNode) Copy() Node { + return &VariableNode{tr: v.tr, NodeType: NodeVariable, Pos: v.Pos, Ident: append([]string{}, v.Ident...)} +} + +// DotNode holds the special identifier '.'. +type DotNode struct { + NodeType + Pos + tr *Tree +} + +func (t *Tree) newDot(pos Pos) *DotNode { + return &DotNode{tr: t, NodeType: NodeDot, Pos: pos} +} + +func (d *DotNode) Type() NodeType { + // Override method on embedded NodeType for API compatibility. + // TODO: Not really a problem; could change API without effect but + // api tool complains. + return NodeDot +} + +func (d *DotNode) String() string { + return "." +} + +func (d *DotNode) tree() *Tree { + return d.tr +} + +func (d *DotNode) Copy() Node { + return d.tr.newDot(d.Pos) +} + +// NilNode holds the special identifier 'nil' representing an untyped nil constant. +type NilNode struct { + NodeType + Pos + tr *Tree +} + +func (t *Tree) newNil(pos Pos) *NilNode { + return &NilNode{tr: t, NodeType: NodeNil, Pos: pos} +} + +func (n *NilNode) Type() NodeType { + // Override method on embedded NodeType for API compatibility. + // TODO: Not really a problem; could change API without effect but + // api tool complains. + return NodeNil +} + +func (n *NilNode) String() string { + return "nil" +} + +func (n *NilNode) tree() *Tree { + return n.tr +} + +func (n *NilNode) Copy() Node { + return n.tr.newNil(n.Pos) +} + +// FieldNode holds a field (identifier starting with '.'). +// The names may be chained ('.x.y'). +// The period is dropped from each ident. +type FieldNode struct { + NodeType + Pos + tr *Tree + Ident []string // The identifiers in lexical order. +} + +func (t *Tree) newField(pos Pos, ident string) *FieldNode { + return &FieldNode{tr: t, NodeType: NodeField, Pos: pos, Ident: strings.Split(ident[1:], ".")} // [1:] to drop leading period +} + +func (f *FieldNode) String() string { + s := "" + for _, id := range f.Ident { + s += "." + id + } + return s +} + +func (f *FieldNode) tree() *Tree { + return f.tr +} + +func (f *FieldNode) Copy() Node { + return &FieldNode{tr: f.tr, NodeType: NodeField, Pos: f.Pos, Ident: append([]string{}, f.Ident...)} +} + +// ChainNode holds a term followed by a chain of field accesses (identifier starting with '.'). +// The names may be chained ('.x.y'). +// The periods are dropped from each ident. +type ChainNode struct { + NodeType + Pos + tr *Tree + Node Node + Field []string // The identifiers in lexical order. +} + +func (t *Tree) newChain(pos Pos, node Node) *ChainNode { + return &ChainNode{tr: t, NodeType: NodeChain, Pos: pos, Node: node} +} + +// Add adds the named field (which should start with a period) to the end of the chain. +func (c *ChainNode) Add(field string) { + if len(field) == 0 || field[0] != '.' { + panic("no dot in field") + } + field = field[1:] // Remove leading dot. + if field == "" { + panic("empty field") + } + c.Field = append(c.Field, field) +} + +func (c *ChainNode) String() string { + s := c.Node.String() + if _, ok := c.Node.(*PipeNode); ok { + s = "(" + s + ")" + } + for _, field := range c.Field { + s += "." + field + } + return s +} + +func (c *ChainNode) tree() *Tree { + return c.tr +} + +func (c *ChainNode) Copy() Node { + return &ChainNode{tr: c.tr, NodeType: NodeChain, Pos: c.Pos, Node: c.Node, Field: append([]string{}, c.Field...)} +} + +// BoolNode holds a boolean constant. +type BoolNode struct { + NodeType + Pos + tr *Tree + True bool // The value of the boolean constant. +} + +func (t *Tree) newBool(pos Pos, true bool) *BoolNode { + return &BoolNode{tr: t, NodeType: NodeBool, Pos: pos, True: true} +} + +func (b *BoolNode) String() string { + if b.True { + return "true" + } + return "false" +} + +func (b *BoolNode) tree() *Tree { + return b.tr +} + +func (b *BoolNode) Copy() Node { + return b.tr.newBool(b.Pos, b.True) +} + +// NumberNode holds a number: signed or unsigned integer, float, or complex. +// The value is parsed and stored under all the types that can represent the value. +// This simulates in a small amount of code the behavior of Go's ideal constants. +type NumberNode struct { + NodeType + Pos + tr *Tree + IsInt bool // Number has an integral value. + IsUint bool // Number has an unsigned integral value. + IsFloat bool // Number has a floating-point value. + IsComplex bool // Number is complex. + Int64 int64 // The signed integer value. + Uint64 uint64 // The unsigned integer value. + Float64 float64 // The floating-point value. + Complex128 complex128 // The complex value. + Text string // The original textual representation from the input. +} + +func (t *Tree) newNumber(pos Pos, text string, typ itemType) (*NumberNode, error) { + n := &NumberNode{tr: t, NodeType: NodeNumber, Pos: pos, Text: text} + switch typ { + case itemCharConstant: + rune, _, tail, err := strconv.UnquoteChar(text[1:], text[0]) + if err != nil { + return nil, err + } + if tail != "'" { + return nil, fmt.Errorf("malformed character constant: %s", text) + } + n.Int64 = int64(rune) + n.IsInt = true + n.Uint64 = uint64(rune) + n.IsUint = true + n.Float64 = float64(rune) // odd but those are the rules. + n.IsFloat = true + return n, nil + case itemComplex: + // fmt.Sscan can parse the pair, so let it do the work. + if _, err := fmt.Sscan(text, &n.Complex128); err != nil { + return nil, err + } + n.IsComplex = true + n.simplifyComplex() + return n, nil + } + // Imaginary constants can only be complex unless they are zero. + if len(text) > 0 && text[len(text)-1] == 'i' { + f, err := strconv.ParseFloat(text[:len(text)-1], 64) + if err == nil { + n.IsComplex = true + n.Complex128 = complex(0, f) + n.simplifyComplex() + return n, nil + } + } + // Do integer test first so we get 0x123 etc. + u, err := strconv.ParseUint(text, 0, 64) // will fail for -0; fixed below. + if err == nil { + n.IsUint = true + n.Uint64 = u + } + i, err := strconv.ParseInt(text, 0, 64) + if err == nil { + n.IsInt = true + n.Int64 = i + if i == 0 { + n.IsUint = true // in case of -0. + n.Uint64 = u + } + } + // If an integer extraction succeeded, promote the float. + if n.IsInt { + n.IsFloat = true + n.Float64 = float64(n.Int64) + } else if n.IsUint { + n.IsFloat = true + n.Float64 = float64(n.Uint64) + } else { + f, err := strconv.ParseFloat(text, 64) + if err == nil { + n.IsFloat = true + n.Float64 = f + // If a floating-point extraction succeeded, extract the int if needed. + if !n.IsInt && float64(int64(f)) == f { + n.IsInt = true + n.Int64 = int64(f) + } + if !n.IsUint && float64(uint64(f)) == f { + n.IsUint = true + n.Uint64 = uint64(f) + } + } + } + if !n.IsInt && !n.IsUint && !n.IsFloat { + return nil, fmt.Errorf("illegal number syntax: %q", text) + } + return n, nil +} + +// simplifyComplex pulls out any other types that are represented by the complex number. +// These all require that the imaginary part be zero. +func (n *NumberNode) simplifyComplex() { + n.IsFloat = imag(n.Complex128) == 0 + if n.IsFloat { + n.Float64 = real(n.Complex128) + n.IsInt = float64(int64(n.Float64)) == n.Float64 + if n.IsInt { + n.Int64 = int64(n.Float64) + } + n.IsUint = float64(uint64(n.Float64)) == n.Float64 + if n.IsUint { + n.Uint64 = uint64(n.Float64) + } + } +} + +func (n *NumberNode) String() string { + return n.Text +} + +func (n *NumberNode) tree() *Tree { + return n.tr +} + +func (n *NumberNode) Copy() Node { + nn := new(NumberNode) + *nn = *n // Easy, fast, correct. + return nn +} + +// StringNode holds a string constant. The value has been "unquoted". +type StringNode struct { + NodeType + Pos + tr *Tree + Quoted string // The original text of the string, with quotes. + Text string // The string, after quote processing. +} + +func (t *Tree) newString(pos Pos, orig, text string) *StringNode { + return &StringNode{tr: t, NodeType: NodeString, Pos: pos, Quoted: orig, Text: text} +} + +func (s *StringNode) String() string { + return s.Quoted +} + +func (s *StringNode) tree() *Tree { + return s.tr +} + +func (s *StringNode) Copy() Node { + return s.tr.newString(s.Pos, s.Quoted, s.Text) +} + +// endNode represents an {{end}} action. +// It does not appear in the final parse tree. +type endNode struct { + NodeType + Pos + tr *Tree +} + +func (t *Tree) newEnd(pos Pos) *endNode { + return &endNode{tr: t, NodeType: nodeEnd, Pos: pos} +} + +func (e *endNode) String() string { + return "{{end}}" +} + +func (e *endNode) tree() *Tree { + return e.tr +} + +func (e *endNode) Copy() Node { + return e.tr.newEnd(e.Pos) +} + +// elseNode represents an {{else}} action. Does not appear in the final tree. +type elseNode struct { + NodeType + Pos + tr *Tree + Line int // The line number in the input (deprecated; kept for compatibility) +} + +func (t *Tree) newElse(pos Pos, line int) *elseNode { + return &elseNode{tr: t, NodeType: nodeElse, Pos: pos, Line: line} +} + +func (e *elseNode) Type() NodeType { + return nodeElse +} + +func (e *elseNode) String() string { + return "{{else}}" +} + +func (e *elseNode) tree() *Tree { + return e.tr +} + +func (e *elseNode) Copy() Node { + return e.tr.newElse(e.Pos, e.Line) +} + +// BranchNode is the common representation of if, range, and with. +type BranchNode struct { + NodeType + Pos + tr *Tree + Line int // The line number in the input (deprecated; kept for compatibility) + Pipe *PipeNode // The pipeline to be evaluated. + List *ListNode // What to execute if the value is non-empty. + ElseList *ListNode // What to execute if the value is empty (nil if absent). +} + +func (b *BranchNode) String() string { + name := "" + switch b.NodeType { + case NodeIf: + name = "if" + case NodeRange: + name = "range" + case NodeWith: + name = "with" + default: + panic("unknown branch type") + } + if b.ElseList != nil { + return fmt.Sprintf("{{%s %s}}%s{{else}}%s{{end}}", name, b.Pipe, b.List, b.ElseList) + } + return fmt.Sprintf("{{%s %s}}%s{{end}}", name, b.Pipe, b.List) +} + +func (b *BranchNode) tree() *Tree { + return b.tr +} + +func (b *BranchNode) Copy() Node { + switch b.NodeType { + case NodeIf: + return b.tr.newIf(b.Pos, b.Line, b.Pipe, b.List, b.ElseList) + case NodeRange: + return b.tr.newRange(b.Pos, b.Line, b.Pipe, b.List, b.ElseList) + case NodeWith: + return b.tr.newWith(b.Pos, b.Line, b.Pipe, b.List, b.ElseList) + default: + panic("unknown branch type") + } +} + +// IfNode represents an {{if}} action and its commands. +type IfNode struct { + BranchNode +} + +func (t *Tree) newIf(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *IfNode { + return &IfNode{BranchNode{tr: t, NodeType: NodeIf, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}} +} + +func (i *IfNode) Copy() Node { + return i.tr.newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList()) +} + +// RangeNode represents a {{range}} action and its commands. +type RangeNode struct { + BranchNode +} + +func (t *Tree) newRange(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *RangeNode { + return &RangeNode{BranchNode{tr: t, NodeType: NodeRange, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}} +} + +func (r *RangeNode) Copy() Node { + return r.tr.newRange(r.Pos, r.Line, r.Pipe.CopyPipe(), r.List.CopyList(), r.ElseList.CopyList()) +} + +// WithNode represents a {{with}} action and its commands. +type WithNode struct { + BranchNode +} + +func (t *Tree) newWith(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *WithNode { + return &WithNode{BranchNode{tr: t, NodeType: NodeWith, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}} +} + +func (w *WithNode) Copy() Node { + return w.tr.newWith(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList()) +} + +// TemplateNode represents a {{template}} action. +type TemplateNode struct { + NodeType + Pos + tr *Tree + Line int // The line number in the input (deprecated; kept for compatibility) + Name string // The name of the template (unquoted). + Pipe *PipeNode // The command to evaluate as dot for the template. +} + +func (t *Tree) newTemplate(pos Pos, line int, name string, pipe *PipeNode) *TemplateNode { + return &TemplateNode{tr: t, NodeType: NodeTemplate, Pos: pos, Line: line, Name: name, Pipe: pipe} +} + +func (t *TemplateNode) String() string { + if t.Pipe == nil { + return fmt.Sprintf("{{template %q}}", t.Name) + } + return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe) +} + +func (t *TemplateNode) tree() *Tree { + return t.tr +} + +func (t *TemplateNode) Copy() Node { + return t.tr.newTemplate(t.Pos, t.Line, t.Name, t.Pipe.CopyPipe()) +} diff --git a/vendor/github.com/alecthomas/template/parse/parse.go b/vendor/github.com/alecthomas/template/parse/parse.go new file mode 100644 index 000000000..0d77ade87 --- /dev/null +++ b/vendor/github.com/alecthomas/template/parse/parse.go @@ -0,0 +1,700 @@ +// Copyright 2011 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 parse builds parse trees for templates as defined by text/template +// and html/template. Clients should use those packages to construct templates +// rather than this one, which provides shared internal data structures not +// intended for general use. +package parse + +import ( + "bytes" + "fmt" + "runtime" + "strconv" + "strings" +) + +// Tree is the representation of a single parsed template. +type Tree struct { + Name string // name of the template represented by the tree. + ParseName string // name of the top-level template during parsing, for error messages. + Root *ListNode // top-level root of the tree. + text string // text parsed to create the template (or its parent) + // Parsing only; cleared after parse. + funcs []map[string]interface{} + lex *lexer + token [3]item // three-token lookahead for parser. + peekCount int + vars []string // variables defined at the moment. +} + +// Copy returns a copy of the Tree. Any parsing state is discarded. +func (t *Tree) Copy() *Tree { + if t == nil { + return nil + } + return &Tree{ + Name: t.Name, + ParseName: t.ParseName, + Root: t.Root.CopyList(), + text: t.text, + } +} + +// Parse returns a map from template name to parse.Tree, created by parsing the +// templates described in the argument string. The top-level template will be +// given the specified name. If an error is encountered, parsing stops and an +// empty map is returned with the error. +func Parse(name, text, leftDelim, rightDelim string, funcs ...map[string]interface{}) (treeSet map[string]*Tree, err error) { + treeSet = make(map[string]*Tree) + t := New(name) + t.text = text + _, err = t.Parse(text, leftDelim, rightDelim, treeSet, funcs...) + return +} + +// next returns the next token. +func (t *Tree) next() item { + if t.peekCount > 0 { + t.peekCount-- + } else { + t.token[0] = t.lex.nextItem() + } + return t.token[t.peekCount] +} + +// backup backs the input stream up one token. +func (t *Tree) backup() { + t.peekCount++ +} + +// backup2 backs the input stream up two tokens. +// The zeroth token is already there. +func (t *Tree) backup2(t1 item) { + t.token[1] = t1 + t.peekCount = 2 +} + +// backup3 backs the input stream up three tokens +// The zeroth token is already there. +func (t *Tree) backup3(t2, t1 item) { // Reverse order: we're pushing back. + t.token[1] = t1 + t.token[2] = t2 + t.peekCount = 3 +} + +// peek returns but does not consume the next token. +func (t *Tree) peek() item { + if t.peekCount > 0 { + return t.token[t.peekCount-1] + } + t.peekCount = 1 + t.token[0] = t.lex.nextItem() + return t.token[0] +} + +// nextNonSpace returns the next non-space token. +func (t *Tree) nextNonSpace() (token item) { + for { + token = t.next() + if token.typ != itemSpace { + break + } + } + return token +} + +// peekNonSpace returns but does not consume the next non-space token. +func (t *Tree) peekNonSpace() (token item) { + for { + token = t.next() + if token.typ != itemSpace { + break + } + } + t.backup() + return token +} + +// Parsing. + +// New allocates a new parse tree with the given name. +func New(name string, funcs ...map[string]interface{}) *Tree { + return &Tree{ + Name: name, + funcs: funcs, + } +} + +// ErrorContext returns a textual representation of the location of the node in the input text. +// The receiver is only used when the node does not have a pointer to the tree inside, +// which can occur in old code. +func (t *Tree) ErrorContext(n Node) (location, context string) { + pos := int(n.Position()) + tree := n.tree() + if tree == nil { + tree = t + } + text := tree.text[:pos] + byteNum := strings.LastIndex(text, "\n") + if byteNum == -1 { + byteNum = pos // On first line. + } else { + byteNum++ // After the newline. + byteNum = pos - byteNum + } + lineNum := 1 + strings.Count(text, "\n") + context = n.String() + if len(context) > 20 { + context = fmt.Sprintf("%.20s...", context) + } + return fmt.Sprintf("%s:%d:%d", tree.ParseName, lineNum, byteNum), context +} + +// errorf formats the error and terminates processing. +func (t *Tree) errorf(format string, args ...interface{}) { + t.Root = nil + format = fmt.Sprintf("template: %s:%d: %s", t.ParseName, t.lex.lineNumber(), format) + panic(fmt.Errorf(format, args...)) +} + +// error terminates processing. +func (t *Tree) error(err error) { + t.errorf("%s", err) +} + +// expect consumes the next token and guarantees it has the required type. +func (t *Tree) expect(expected itemType, context string) item { + token := t.nextNonSpace() + if token.typ != expected { + t.unexpected(token, context) + } + return token +} + +// expectOneOf consumes the next token and guarantees it has one of the required types. +func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item { + token := t.nextNonSpace() + if token.typ != expected1 && token.typ != expected2 { + t.unexpected(token, context) + } + return token +} + +// unexpected complains about the token and terminates processing. +func (t *Tree) unexpected(token item, context string) { + t.errorf("unexpected %s in %s", token, context) +} + +// recover is the handler that turns panics into returns from the top level of Parse. +func (t *Tree) recover(errp *error) { + e := recover() + if e != nil { + if _, ok := e.(runtime.Error); ok { + panic(e) + } + if t != nil { + t.stopParse() + } + *errp = e.(error) + } + return +} + +// startParse initializes the parser, using the lexer. +func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer) { + t.Root = nil + t.lex = lex + t.vars = []string{"$"} + t.funcs = funcs +} + +// stopParse terminates parsing. +func (t *Tree) stopParse() { + t.lex = nil + t.vars = nil + t.funcs = nil +} + +// Parse parses the template definition string to construct a representation of +// the template for execution. If either action delimiter string is empty, the +// default ("{{" or "}}") is used. Embedded template definitions are added to +// the treeSet map. +func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) { + defer t.recover(&err) + t.ParseName = t.Name + t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim)) + t.text = text + t.parse(treeSet) + t.add(treeSet) + t.stopParse() + return t, nil +} + +// add adds tree to the treeSet. +func (t *Tree) add(treeSet map[string]*Tree) { + tree := treeSet[t.Name] + if tree == nil || IsEmptyTree(tree.Root) { + treeSet[t.Name] = t + return + } + if !IsEmptyTree(t.Root) { + t.errorf("template: multiple definition of template %q", t.Name) + } +} + +// IsEmptyTree reports whether this tree (node) is empty of everything but space. +func IsEmptyTree(n Node) bool { + switch n := n.(type) { + case nil: + return true + case *ActionNode: + case *IfNode: + case *ListNode: + for _, node := range n.Nodes { + if !IsEmptyTree(node) { + return false + } + } + return true + case *RangeNode: + case *TemplateNode: + case *TextNode: + return len(bytes.TrimSpace(n.Text)) == 0 + case *WithNode: + default: + panic("unknown node: " + n.String()) + } + return false +} + +// parse is the top-level parser for a template, essentially the same +// as itemList except it also parses {{define}} actions. +// It runs to EOF. +func (t *Tree) parse(treeSet map[string]*Tree) (next Node) { + t.Root = t.newList(t.peek().pos) + for t.peek().typ != itemEOF { + if t.peek().typ == itemLeftDelim { + delim := t.next() + if t.nextNonSpace().typ == itemDefine { + newT := New("definition") // name will be updated once we know it. + newT.text = t.text + newT.ParseName = t.ParseName + newT.startParse(t.funcs, t.lex) + newT.parseDefinition(treeSet) + continue + } + t.backup2(delim) + } + n := t.textOrAction() + if n.Type() == nodeEnd { + t.errorf("unexpected %s", n) + } + t.Root.append(n) + } + return nil +} + +// parseDefinition parses a {{define}} ... {{end}} template definition and +// installs the definition in the treeSet map. The "define" keyword has already +// been scanned. +func (t *Tree) parseDefinition(treeSet map[string]*Tree) { + const context = "define clause" + name := t.expectOneOf(itemString, itemRawString, context) + var err error + t.Name, err = strconv.Unquote(name.val) + if err != nil { + t.error(err) + } + t.expect(itemRightDelim, context) + var end Node + t.Root, end = t.itemList() + if end.Type() != nodeEnd { + t.errorf("unexpected %s in %s", end, context) + } + t.add(treeSet) + t.stopParse() +} + +// itemList: +// textOrAction* +// Terminates at {{end}} or {{else}}, returned separately. +func (t *Tree) itemList() (list *ListNode, next Node) { + list = t.newList(t.peekNonSpace().pos) + for t.peekNonSpace().typ != itemEOF { + n := t.textOrAction() + switch n.Type() { + case nodeEnd, nodeElse: + return list, n + } + list.append(n) + } + t.errorf("unexpected EOF") + return +} + +// textOrAction: +// text | action +func (t *Tree) textOrAction() Node { + switch token := t.nextNonSpace(); token.typ { + case itemElideNewline: + return t.elideNewline() + case itemText: + return t.newText(token.pos, token.val) + case itemLeftDelim: + return t.action() + default: + t.unexpected(token, "input") + } + return nil +} + +// elideNewline: +// Remove newlines trailing rightDelim if \\ is present. +func (t *Tree) elideNewline() Node { + token := t.peek() + if token.typ != itemText { + t.unexpected(token, "input") + return nil + } + + t.next() + stripped := strings.TrimLeft(token.val, "\n\r") + diff := len(token.val) - len(stripped) + if diff > 0 { + // This is a bit nasty. We mutate the token in-place to remove + // preceding newlines. + token.pos += Pos(diff) + token.val = stripped + } + return t.newText(token.pos, token.val) +} + +// Action: +// control +// command ("|" command)* +// Left delim is past. Now get actions. +// First word could be a keyword such as range. +func (t *Tree) action() (n Node) { + switch token := t.nextNonSpace(); token.typ { + case itemElse: + return t.elseControl() + case itemEnd: + return t.endControl() + case itemIf: + return t.ifControl() + case itemRange: + return t.rangeControl() + case itemTemplate: + return t.templateControl() + case itemWith: + return t.withControl() + } + t.backup() + // Do not pop variables; they persist until "end". + return t.newAction(t.peek().pos, t.lex.lineNumber(), t.pipeline("command")) +} + +// Pipeline: +// declarations? command ('|' command)* +func (t *Tree) pipeline(context string) (pipe *PipeNode) { + var decl []*VariableNode + pos := t.peekNonSpace().pos + // Are there declarations? + for { + if v := t.peekNonSpace(); v.typ == itemVariable { + t.next() + // Since space is a token, we need 3-token look-ahead here in the worst case: + // in "$x foo" we need to read "foo" (as opposed to ":=") to know that $x is an + // argument variable rather than a declaration. So remember the token + // adjacent to the variable so we can push it back if necessary. + tokenAfterVariable := t.peek() + if next := t.peekNonSpace(); next.typ == itemColonEquals || (next.typ == itemChar && next.val == ",") { + t.nextNonSpace() + variable := t.newVariable(v.pos, v.val) + decl = append(decl, variable) + t.vars = append(t.vars, v.val) + if next.typ == itemChar && next.val == "," { + if context == "range" && len(decl) < 2 { + continue + } + t.errorf("too many declarations in %s", context) + } + } else if tokenAfterVariable.typ == itemSpace { + t.backup3(v, tokenAfterVariable) + } else { + t.backup2(v) + } + } + break + } + pipe = t.newPipeline(pos, t.lex.lineNumber(), decl) + for { + switch token := t.nextNonSpace(); token.typ { + case itemRightDelim, itemRightParen: + if len(pipe.Cmds) == 0 { + t.errorf("missing value for %s", context) + } + if token.typ == itemRightParen { + t.backup() + } + return + case itemBool, itemCharConstant, itemComplex, itemDot, itemField, itemIdentifier, + itemNumber, itemNil, itemRawString, itemString, itemVariable, itemLeftParen: + t.backup() + pipe.append(t.command()) + default: + t.unexpected(token, context) + } + } +} + +func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) { + defer t.popVars(len(t.vars)) + line = t.lex.lineNumber() + pipe = t.pipeline(context) + var next Node + list, next = t.itemList() + switch next.Type() { + case nodeEnd: //done + case nodeElse: + if allowElseIf { + // Special case for "else if". If the "else" is followed immediately by an "if", + // the elseControl will have left the "if" token pending. Treat + // {{if a}}_{{else if b}}_{{end}} + // as + // {{if a}}_{{else}}{{if b}}_{{end}}{{end}}. + // To do this, parse the if as usual and stop at it {{end}}; the subsequent{{end}} + // is assumed. This technique works even for long if-else-if chains. + // TODO: Should we allow else-if in with and range? + if t.peek().typ == itemIf { + t.next() // Consume the "if" token. + elseList = t.newList(next.Position()) + elseList.append(t.ifControl()) + // Do not consume the next item - only one {{end}} required. + break + } + } + elseList, next = t.itemList() + if next.Type() != nodeEnd { + t.errorf("expected end; found %s", next) + } + } + return pipe.Position(), line, pipe, list, elseList +} + +// If: +// {{if pipeline}} itemList {{end}} +// {{if pipeline}} itemList {{else}} itemList {{end}} +// If keyword is past. +func (t *Tree) ifControl() Node { + return t.newIf(t.parseControl(true, "if")) +} + +// Range: +// {{range pipeline}} itemList {{end}} +// {{range pipeline}} itemList {{else}} itemList {{end}} +// Range keyword is past. +func (t *Tree) rangeControl() Node { + return t.newRange(t.parseControl(false, "range")) +} + +// With: +// {{with pipeline}} itemList {{end}} +// {{with pipeline}} itemList {{else}} itemList {{end}} +// If keyword is past. +func (t *Tree) withControl() Node { + return t.newWith(t.parseControl(false, "with")) +} + +// End: +// {{end}} +// End keyword is past. +func (t *Tree) endControl() Node { + return t.newEnd(t.expect(itemRightDelim, "end").pos) +} + +// Else: +// {{else}} +// Else keyword is past. +func (t *Tree) elseControl() Node { + // Special case for "else if". + peek := t.peekNonSpace() + if peek.typ == itemIf { + // We see "{{else if ... " but in effect rewrite it to {{else}}{{if ... ". + return t.newElse(peek.pos, t.lex.lineNumber()) + } + return t.newElse(t.expect(itemRightDelim, "else").pos, t.lex.lineNumber()) +} + +// Template: +// {{template stringValue pipeline}} +// Template keyword is past. The name must be something that can evaluate +// to a string. +func (t *Tree) templateControl() Node { + var name string + token := t.nextNonSpace() + switch token.typ { + case itemString, itemRawString: + s, err := strconv.Unquote(token.val) + if err != nil { + t.error(err) + } + name = s + default: + t.unexpected(token, "template invocation") + } + var pipe *PipeNode + if t.nextNonSpace().typ != itemRightDelim { + t.backup() + // Do not pop variables; they persist until "end". + pipe = t.pipeline("template") + } + return t.newTemplate(token.pos, t.lex.lineNumber(), name, pipe) +} + +// command: +// operand (space operand)* +// space-separated arguments up to a pipeline character or right delimiter. +// we consume the pipe character but leave the right delim to terminate the action. +func (t *Tree) command() *CommandNode { + cmd := t.newCommand(t.peekNonSpace().pos) + for { + t.peekNonSpace() // skip leading spaces. + operand := t.operand() + if operand != nil { + cmd.append(operand) + } + switch token := t.next(); token.typ { + case itemSpace: + continue + case itemError: + t.errorf("%s", token.val) + case itemRightDelim, itemRightParen: + t.backup() + case itemPipe: + default: + t.errorf("unexpected %s in operand; missing space?", token) + } + break + } + if len(cmd.Args) == 0 { + t.errorf("empty command") + } + return cmd +} + +// operand: +// term .Field* +// An operand is a space-separated component of a command, +// a term possibly followed by field accesses. +// A nil return means the next item is not an operand. +func (t *Tree) operand() Node { + node := t.term() + if node == nil { + return nil + } + if t.peek().typ == itemField { + chain := t.newChain(t.peek().pos, node) + for t.peek().typ == itemField { + chain.Add(t.next().val) + } + // Compatibility with original API: If the term is of type NodeField + // or NodeVariable, just put more fields on the original. + // Otherwise, keep the Chain node. + // TODO: Switch to Chains always when we can. + switch node.Type() { + case NodeField: + node = t.newField(chain.Position(), chain.String()) + case NodeVariable: + node = t.newVariable(chain.Position(), chain.String()) + default: + node = chain + } + } + return node +} + +// term: +// literal (number, string, nil, boolean) +// function (identifier) +// . +// .Field +// $ +// '(' pipeline ')' +// A term is a simple "expression". +// A nil return means the next item is not a term. +func (t *Tree) term() Node { + switch token := t.nextNonSpace(); token.typ { + case itemError: + t.errorf("%s", token.val) + case itemIdentifier: + if !t.hasFunction(token.val) { + t.errorf("function %q not defined", token.val) + } + return NewIdentifier(token.val).SetTree(t).SetPos(token.pos) + case itemDot: + return t.newDot(token.pos) + case itemNil: + return t.newNil(token.pos) + case itemVariable: + return t.useVar(token.pos, token.val) + case itemField: + return t.newField(token.pos, token.val) + case itemBool: + return t.newBool(token.pos, token.val == "true") + case itemCharConstant, itemComplex, itemNumber: + number, err := t.newNumber(token.pos, token.val, token.typ) + if err != nil { + t.error(err) + } + return number + case itemLeftParen: + pipe := t.pipeline("parenthesized pipeline") + if token := t.next(); token.typ != itemRightParen { + t.errorf("unclosed right paren: unexpected %s", token) + } + return pipe + case itemString, itemRawString: + s, err := strconv.Unquote(token.val) + if err != nil { + t.error(err) + } + return t.newString(token.pos, token.val, s) + } + t.backup() + return nil +} + +// hasFunction reports if a function name exists in the Tree's maps. +func (t *Tree) hasFunction(name string) bool { + for _, funcMap := range t.funcs { + if funcMap == nil { + continue + } + if funcMap[name] != nil { + return true + } + } + return false +} + +// popVars trims the variable list to the specified length +func (t *Tree) popVars(n int) { + t.vars = t.vars[:n] +} + +// useVar returns a node for a variable reference. It errors if the +// variable is not defined. +func (t *Tree) useVar(pos Pos, name string) Node { + v := t.newVariable(pos, name) + for _, varName := range t.vars { + if varName == v.Ident[0] { + return v + } + } + t.errorf("undefined variable %q", v.Ident[0]) + return nil +} diff --git a/vendor/github.com/alecthomas/template/template.go b/vendor/github.com/alecthomas/template/template.go new file mode 100644 index 000000000..447ed2aba --- /dev/null +++ b/vendor/github.com/alecthomas/template/template.go @@ -0,0 +1,218 @@ +// Copyright 2011 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 template + +import ( + "fmt" + "reflect" + + "github.com/alecthomas/template/parse" +) + +// common holds the information shared by related templates. +type common struct { + tmpl map[string]*Template + // We use two maps, one for parsing and one for execution. + // This separation makes the API cleaner since it doesn't + // expose reflection to the client. + parseFuncs FuncMap + execFuncs map[string]reflect.Value +} + +// Template is the representation of a parsed template. The *parse.Tree +// field is exported only for use by html/template and should be treated +// as unexported by all other clients. +type Template struct { + name string + *parse.Tree + *common + leftDelim string + rightDelim string +} + +// New allocates a new template with the given name. +func New(name string) *Template { + return &Template{ + name: name, + } +} + +// Name returns the name of the template. +func (t *Template) Name() string { + return t.name +} + +// New allocates a new template associated with the given one and with the same +// delimiters. The association, which is transitive, allows one template to +// invoke another with a {{template}} action. +func (t *Template) New(name string) *Template { + t.init() + return &Template{ + name: name, + common: t.common, + leftDelim: t.leftDelim, + rightDelim: t.rightDelim, + } +} + +func (t *Template) init() { + if t.common == nil { + t.common = new(common) + t.tmpl = make(map[string]*Template) + t.parseFuncs = make(FuncMap) + t.execFuncs = make(map[string]reflect.Value) + } +} + +// Clone returns a duplicate of the template, including all associated +// templates. The actual representation is not copied, but the name space of +// associated templates is, so further calls to Parse in the copy will add +// templates to the copy but not to the original. Clone can be used to prepare +// common templates and use them with variant definitions for other templates +// by adding the variants after the clone is made. +func (t *Template) Clone() (*Template, error) { + nt := t.copy(nil) + nt.init() + nt.tmpl[t.name] = nt + for k, v := range t.tmpl { + if k == t.name { // Already installed. + continue + } + // The associated templates share nt's common structure. + tmpl := v.copy(nt.common) + nt.tmpl[k] = tmpl + } + for k, v := range t.parseFuncs { + nt.parseFuncs[k] = v + } + for k, v := range t.execFuncs { + nt.execFuncs[k] = v + } + return nt, nil +} + +// copy returns a shallow copy of t, with common set to the argument. +func (t *Template) copy(c *common) *Template { + nt := New(t.name) + nt.Tree = t.Tree + nt.common = c + nt.leftDelim = t.leftDelim + nt.rightDelim = t.rightDelim + return nt +} + +// AddParseTree creates a new template with the name and parse tree +// and associates it with t. +func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) { + if t.common != nil && t.tmpl[name] != nil { + return nil, fmt.Errorf("template: redefinition of template %q", name) + } + nt := t.New(name) + nt.Tree = tree + t.tmpl[name] = nt + return nt, nil +} + +// Templates returns a slice of the templates associated with t, including t +// itself. +func (t *Template) Templates() []*Template { + if t.common == nil { + return nil + } + // Return a slice so we don't expose the map. + m := make([]*Template, 0, len(t.tmpl)) + for _, v := range t.tmpl { + m = append(m, v) + } + return m +} + +// Delims sets the action delimiters to the specified strings, to be used in +// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template +// definitions will inherit the settings. An empty delimiter stands for the +// corresponding default: {{ or }}. +// The return value is the template, so calls can be chained. +func (t *Template) Delims(left, right string) *Template { + t.leftDelim = left + t.rightDelim = right + return t +} + +// Funcs adds the elements of the argument map to the template's function map. +// It panics if a value in the map is not a function with appropriate return +// type. However, it is legal to overwrite elements of the map. The return +// value is the template, so calls can be chained. +func (t *Template) Funcs(funcMap FuncMap) *Template { + t.init() + addValueFuncs(t.execFuncs, funcMap) + addFuncs(t.parseFuncs, funcMap) + return t +} + +// Lookup returns the template with the given name that is associated with t, +// or nil if there is no such template. +func (t *Template) Lookup(name string) *Template { + if t.common == nil { + return nil + } + return t.tmpl[name] +} + +// Parse parses a string into a template. Nested template definitions will be +// associated with the top-level template t. Parse may be called multiple times +// to parse definitions of templates to associate with t. It is an error if a +// resulting template is non-empty (contains content other than template +// definitions) and would replace a non-empty template with the same name. +// (In multiple calls to Parse with the same receiver template, only one call +// can contain text other than space, comments, and template definitions.) +func (t *Template) Parse(text string) (*Template, error) { + t.init() + trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins) + if err != nil { + return nil, err + } + // Add the newly parsed trees, including the one for t, into our common structure. + for name, tree := range trees { + // If the name we parsed is the name of this template, overwrite this template. + // The associate method checks it's not a redefinition. + tmpl := t + if name != t.name { + tmpl = t.New(name) + } + // Even if t == tmpl, we need to install it in the common.tmpl map. + if replace, err := t.associate(tmpl, tree); err != nil { + return nil, err + } else if replace { + tmpl.Tree = tree + } + tmpl.leftDelim = t.leftDelim + tmpl.rightDelim = t.rightDelim + } + return t, nil +} + +// associate installs the new template into the group of templates associated +// with t. It is an error to reuse a name except to overwrite an empty +// template. The two are already known to share the common structure. +// The boolean return value reports wither to store this tree as t.Tree. +func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) { + if new.common != t.common { + panic("internal error: associate not common") + } + name := new.name + if old := t.tmpl[name]; old != nil { + oldIsEmpty := parse.IsEmptyTree(old.Root) + newIsEmpty := parse.IsEmptyTree(tree.Root) + if newIsEmpty { + // Whether old is empty or not, new is empty; no reason to replace old. + return false, nil + } + if !oldIsEmpty { + return false, fmt.Errorf("template: redefinition of template %q", name) + } + } + t.tmpl[name] = new + return true, nil +} diff --git a/vendor/github.com/alecthomas/units/COPYING b/vendor/github.com/alecthomas/units/COPYING new file mode 100644 index 000000000..2993ec085 --- /dev/null +++ b/vendor/github.com/alecthomas/units/COPYING @@ -0,0 +1,19 @@ +Copyright (C) 2014 Alec Thomas + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/alecthomas/units/bytes.go b/vendor/github.com/alecthomas/units/bytes.go new file mode 100644 index 000000000..eaadeb800 --- /dev/null +++ b/vendor/github.com/alecthomas/units/bytes.go @@ -0,0 +1,83 @@ +package units + +// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte, +// etc.). +type Base2Bytes int64 + +// Base-2 byte units. +const ( + Kibibyte Base2Bytes = 1024 + KiB = Kibibyte + Mebibyte = Kibibyte * 1024 + MiB = Mebibyte + Gibibyte = Mebibyte * 1024 + GiB = Gibibyte + Tebibyte = Gibibyte * 1024 + TiB = Tebibyte + Pebibyte = Tebibyte * 1024 + PiB = Pebibyte + Exbibyte = Pebibyte * 1024 + EiB = Exbibyte +) + +var ( + bytesUnitMap = MakeUnitMap("iB", "B", 1024) + oldBytesUnitMap = MakeUnitMap("B", "B", 1024) +) + +// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB +// and KiB are both 1024. +func ParseBase2Bytes(s string) (Base2Bytes, error) { + n, err := ParseUnit(s, bytesUnitMap) + if err != nil { + n, err = ParseUnit(s, oldBytesUnitMap) + } + return Base2Bytes(n), err +} + +func (b Base2Bytes) String() string { + return ToString(int64(b), 1024, "iB", "B") +} + +var ( + metricBytesUnitMap = MakeUnitMap("B", "B", 1000) +) + +// MetricBytes are SI byte units (1000 bytes in a kilobyte). +type MetricBytes SI + +// SI base-10 byte units. +const ( + Kilobyte MetricBytes = 1000 + KB = Kilobyte + Megabyte = Kilobyte * 1000 + MB = Megabyte + Gigabyte = Megabyte * 1000 + GB = Gigabyte + Terabyte = Gigabyte * 1000 + TB = Terabyte + Petabyte = Terabyte * 1000 + PB = Petabyte + Exabyte = Petabyte * 1000 + EB = Exabyte +) + +// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes. +func ParseMetricBytes(s string) (MetricBytes, error) { + n, err := ParseUnit(s, metricBytesUnitMap) + return MetricBytes(n), err +} + +func (m MetricBytes) String() string { + return ToString(int64(m), 1000, "B", "B") +} + +// ParseStrictBytes supports both iB and B suffixes for base 2 and metric, +// respectively. That is, KiB represents 1024 and KB represents 1000. +func ParseStrictBytes(s string) (int64, error) { + n, err := ParseUnit(s, bytesUnitMap) + if err != nil { + n, err = ParseUnit(s, metricBytesUnitMap) + } + return int64(n), err +} diff --git a/vendor/github.com/alecthomas/units/doc.go b/vendor/github.com/alecthomas/units/doc.go new file mode 100644 index 000000000..156ae3867 --- /dev/null +++ b/vendor/github.com/alecthomas/units/doc.go @@ -0,0 +1,13 @@ +// Package units provides helpful unit multipliers and functions for Go. +// +// The goal of this package is to have functionality similar to the time [1] package. +// +// +// [1] http://golang.org/pkg/time/ +// +// It allows for code like this: +// +// n, err := ParseBase2Bytes("1KB") +// // n == 1024 +// n = units.Mebibyte * 512 +package units diff --git a/vendor/github.com/alecthomas/units/si.go b/vendor/github.com/alecthomas/units/si.go new file mode 100644 index 000000000..8234a9d52 --- /dev/null +++ b/vendor/github.com/alecthomas/units/si.go @@ -0,0 +1,26 @@ +package units + +// SI units. +type SI int64 + +// SI unit multiples. +const ( + Kilo SI = 1000 + Mega = Kilo * 1000 + Giga = Mega * 1000 + Tera = Giga * 1000 + Peta = Tera * 1000 + Exa = Peta * 1000 +) + +func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 { + return map[string]float64{ + shortSuffix: 1, + "K" + suffix: float64(scale), + "M" + suffix: float64(scale * scale), + "G" + suffix: float64(scale * scale * scale), + "T" + suffix: float64(scale * scale * scale * scale), + "P" + suffix: float64(scale * scale * scale * scale * scale), + "E" + suffix: float64(scale * scale * scale * scale * scale * scale), + } +} diff --git a/vendor/github.com/alecthomas/units/util.go b/vendor/github.com/alecthomas/units/util.go new file mode 100644 index 000000000..6527e92d1 --- /dev/null +++ b/vendor/github.com/alecthomas/units/util.go @@ -0,0 +1,138 @@ +package units + +import ( + "errors" + "fmt" + "strings" +) + +var ( + siUnits = []string{"", "K", "M", "G", "T", "P", "E"} +) + +func ToString(n int64, scale int64, suffix, baseSuffix string) string { + mn := len(siUnits) + out := make([]string, mn) + for i, m := range siUnits { + if n%scale != 0 || i == 0 && n == 0 { + s := suffix + if i == 0 { + s = baseSuffix + } + out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s) + } + n /= scale + if n == 0 { + break + } + } + return strings.Join(out, "") +} + +// Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123 +var errLeadingInt = errors.New("units: bad [0-9]*") // never printed + +// leadingInt consumes the leading [0-9]* from s. +func leadingInt(s string) (x int64, rem string, err error) { + i := 0 + for ; i < len(s); i++ { + c := s[i] + if c < '0' || c > '9' { + break + } + if x >= (1<<63-10)/10 { + // overflow + return 0, "", errLeadingInt + } + x = x*10 + int64(c) - '0' + } + return x, s[i:], nil +} + +func ParseUnit(s string, unitMap map[string]float64) (int64, error) { + // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+ + orig := s + f := float64(0) + neg := false + + // Consume [-+]? + if s != "" { + c := s[0] + if c == '-' || c == '+' { + neg = c == '-' + s = s[1:] + } + } + // Special case: if all that is left is "0", this is zero. + if s == "0" { + return 0, nil + } + if s == "" { + return 0, errors.New("units: invalid " + orig) + } + for s != "" { + g := float64(0) // this element of the sequence + + var x int64 + var err error + + // The next character must be [0-9.] + if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) { + return 0, errors.New("units: invalid " + orig) + } + // Consume [0-9]* + pl := len(s) + x, s, err = leadingInt(s) + if err != nil { + return 0, errors.New("units: invalid " + orig) + } + g = float64(x) + pre := pl != len(s) // whether we consumed anything before a period + + // Consume (\.[0-9]*)? + post := false + if s != "" && s[0] == '.' { + s = s[1:] + pl := len(s) + x, s, err = leadingInt(s) + if err != nil { + return 0, errors.New("units: invalid " + orig) + } + scale := 1.0 + for n := pl - len(s); n > 0; n-- { + scale *= 10 + } + g += float64(x) / scale + post = pl != len(s) + } + if !pre && !post { + // no digits (e.g. ".s" or "-.s") + return 0, errors.New("units: invalid " + orig) + } + + // Consume unit. + i := 0 + for ; i < len(s); i++ { + c := s[i] + if c == '.' || ('0' <= c && c <= '9') { + break + } + } + u := s[:i] + s = s[i:] + unit, ok := unitMap[u] + if !ok { + return 0, errors.New("units: unknown unit " + u + " in " + orig) + } + + f += g * unit + } + + if neg { + f = -f + } + if f < float64(-1<<63) || f > float64(1<<63-1) { + return 0, errors.New("units: overflow parsing unit") + } + return int64(f), nil +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/LICENSE b/vendor/github.com/apache/thrift/lib/go/thrift/LICENSE new file mode 100644 index 000000000..3b6d7d74c --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/LICENSE @@ -0,0 +1,239 @@ + + 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. + +-------------------------------------------------- +SOFTWARE DISTRIBUTED WITH THRIFT: + +The Apache Thrift software includes a number of subcomponents with +separate copyright notices and license terms. Your use of the source +code for the these subcomponents is subject to the terms and +conditions of the following licenses. + +-------------------------------------------------- +Portions of the following files are licensed under the MIT License: + + lib/erl/src/Makefile.am + +Please see doc/otp-base-license.txt for the full terms of this license. + +-------------------------------------------------- +For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components: + +# Copyright (c) 2007 Thomas Porschberg +# +# Copying and distribution of this file, with or without +# modification, are permitted in any medium without royalty provided +# the copyright notice and this notice are preserved. + +-------------------------------------------------- +For the lib/nodejs/lib/thrift/json_parse.js: + +/* + json_parse.js + 2015-05-02 + Public Domain. + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + +*/ +(By Douglas Crockford ) +-------------------------------------------------- diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/application_exception.go b/vendor/github.com/apache/thrift/lib/go/thrift/application_exception.go new file mode 100644 index 000000000..b9d7eedcd --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/application_exception.go @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +const ( + UNKNOWN_APPLICATION_EXCEPTION = 0 + UNKNOWN_METHOD = 1 + INVALID_MESSAGE_TYPE_EXCEPTION = 2 + WRONG_METHOD_NAME = 3 + BAD_SEQUENCE_ID = 4 + MISSING_RESULT = 5 + INTERNAL_ERROR = 6 + PROTOCOL_ERROR = 7 +) + +var defaultApplicationExceptionMessage = map[int32]string{ + UNKNOWN_APPLICATION_EXCEPTION: "unknown application exception", + UNKNOWN_METHOD: "unknown method", + INVALID_MESSAGE_TYPE_EXCEPTION: "invalid message type", + WRONG_METHOD_NAME: "wrong method name", + BAD_SEQUENCE_ID: "bad sequence ID", + MISSING_RESULT: "missing result", + INTERNAL_ERROR: "unknown internal error", + PROTOCOL_ERROR: "unknown protocol error", +} + +// Application level Thrift exception +type TApplicationException interface { + TException + TypeId() int32 + Read(iprot TProtocol) error + Write(oprot TProtocol) error +} + +type tApplicationException struct { + message string + type_ int32 +} + +func (e tApplicationException) Error() string { + if e.message != "" { + return e.message + } + return defaultApplicationExceptionMessage[e.type_] +} + +func NewTApplicationException(type_ int32, message string) TApplicationException { + return &tApplicationException{message, type_} +} + +func (p *tApplicationException) TypeId() int32 { + return p.type_ +} + +func (p *tApplicationException) Read(iprot TProtocol) error { + // TODO: this should really be generated by the compiler + _, err := iprot.ReadStructBegin() + if err != nil { + return err + } + + message := "" + type_ := int32(UNKNOWN_APPLICATION_EXCEPTION) + + for { + _, ttype, id, err := iprot.ReadFieldBegin() + if err != nil { + return err + } + if ttype == STOP { + break + } + switch id { + case 1: + if ttype == STRING { + if message, err = iprot.ReadString(); err != nil { + return err + } + } else { + if err = SkipDefaultDepth(iprot, ttype); err != nil { + return err + } + } + case 2: + if ttype == I32 { + if type_, err = iprot.ReadI32(); err != nil { + return err + } + } else { + if err = SkipDefaultDepth(iprot, ttype); err != nil { + return err + } + } + default: + if err = SkipDefaultDepth(iprot, ttype); err != nil { + return err + } + } + if err = iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return err + } + + p.message = message + p.type_ = type_ + + return nil +} + +func (p *tApplicationException) Write(oprot TProtocol) (err error) { + err = oprot.WriteStructBegin("TApplicationException") + if len(p.Error()) > 0 { + err = oprot.WriteFieldBegin("message", STRING, 1) + if err != nil { + return + } + err = oprot.WriteString(p.Error()) + if err != nil { + return + } + err = oprot.WriteFieldEnd() + if err != nil { + return + } + } + err = oprot.WriteFieldBegin("type", I32, 2) + if err != nil { + return + } + err = oprot.WriteI32(p.type_) + if err != nil { + return + } + err = oprot.WriteFieldEnd() + if err != nil { + return + } + err = oprot.WriteFieldStop() + if err != nil { + return + } + err = oprot.WriteStructEnd() + return +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/binary_protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/binary_protocol.go new file mode 100644 index 000000000..de0f6a7a5 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/binary_protocol.go @@ -0,0 +1,515 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "fmt" + "io" + "math" +) + +type TBinaryProtocol struct { + trans TRichTransport + origTransport TTransport + reader io.Reader + writer io.Writer + strictRead bool + strictWrite bool + buffer [64]byte +} + +type TBinaryProtocolFactory struct { + strictRead bool + strictWrite bool +} + +func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol { + return NewTBinaryProtocol(t, false, true) +} + +func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol { + p := &TBinaryProtocol{origTransport: t, strictRead: strictRead, strictWrite: strictWrite} + if et, ok := t.(TRichTransport); ok { + p.trans = et + } else { + p.trans = NewTRichTransport(t) + } + p.reader = p.trans + p.writer = p.trans + return p +} + +func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory { + return NewTBinaryProtocolFactory(false, true) +} + +func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory { + return &TBinaryProtocolFactory{strictRead: strictRead, strictWrite: strictWrite} +} + +func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol { + return NewTBinaryProtocol(t, p.strictRead, p.strictWrite) +} + +/** + * Writing Methods + */ + +func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { + if p.strictWrite { + version := uint32(VERSION_1) | uint32(typeId) + e := p.WriteI32(int32(version)) + if e != nil { + return e + } + e = p.WriteString(name) + if e != nil { + return e + } + e = p.WriteI32(seqId) + return e + } else { + e := p.WriteString(name) + if e != nil { + return e + } + e = p.WriteByte(int8(typeId)) + if e != nil { + return e + } + e = p.WriteI32(seqId) + return e + } + return nil +} + +func (p *TBinaryProtocol) WriteMessageEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteStructBegin(name string) error { + return nil +} + +func (p *TBinaryProtocol) WriteStructEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + e := p.WriteByte(int8(typeId)) + if e != nil { + return e + } + e = p.WriteI16(id) + return e +} + +func (p *TBinaryProtocol) WriteFieldEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteFieldStop() error { + e := p.WriteByte(STOP) + return e +} + +func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + e := p.WriteByte(int8(keyType)) + if e != nil { + return e + } + e = p.WriteByte(int8(valueType)) + if e != nil { + return e + } + e = p.WriteI32(int32(size)) + return e +} + +func (p *TBinaryProtocol) WriteMapEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) error { + e := p.WriteByte(int8(elemType)) + if e != nil { + return e + } + e = p.WriteI32(int32(size)) + return e +} + +func (p *TBinaryProtocol) WriteListEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) error { + e := p.WriteByte(int8(elemType)) + if e != nil { + return e + } + e = p.WriteI32(int32(size)) + return e +} + +func (p *TBinaryProtocol) WriteSetEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteBool(value bool) error { + if value { + return p.WriteByte(1) + } + return p.WriteByte(0) +} + +func (p *TBinaryProtocol) WriteByte(value int8) error { + e := p.trans.WriteByte(byte(value)) + return NewTProtocolException(e) +} + +func (p *TBinaryProtocol) WriteI16(value int16) error { + v := p.buffer[0:2] + binary.BigEndian.PutUint16(v, uint16(value)) + _, e := p.writer.Write(v) + return NewTProtocolException(e) +} + +func (p *TBinaryProtocol) WriteI32(value int32) error { + v := p.buffer[0:4] + binary.BigEndian.PutUint32(v, uint32(value)) + _, e := p.writer.Write(v) + return NewTProtocolException(e) +} + +func (p *TBinaryProtocol) WriteI64(value int64) error { + v := p.buffer[0:8] + binary.BigEndian.PutUint64(v, uint64(value)) + _, err := p.writer.Write(v) + return NewTProtocolException(err) +} + +func (p *TBinaryProtocol) WriteDouble(value float64) error { + return p.WriteI64(int64(math.Float64bits(value))) +} + +func (p *TBinaryProtocol) WriteString(value string) error { + e := p.WriteI32(int32(len(value))) + if e != nil { + return e + } + _, err := p.trans.WriteString(value) + return NewTProtocolException(err) +} + +func (p *TBinaryProtocol) WriteBinary(value []byte) error { + e := p.WriteI32(int32(len(value))) + if e != nil { + return e + } + _, err := p.writer.Write(value) + return NewTProtocolException(err) +} + +/** + * Reading methods + */ + +func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + size, e := p.ReadI32() + if e != nil { + return "", typeId, 0, NewTProtocolException(e) + } + if size < 0 { + typeId = TMessageType(size & 0x0ff) + version := int64(int64(size) & VERSION_MASK) + if version != VERSION_1 { + return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin")) + } + name, e = p.ReadString() + if e != nil { + return name, typeId, seqId, NewTProtocolException(e) + } + seqId, e = p.ReadI32() + if e != nil { + return name, typeId, seqId, NewTProtocolException(e) + } + return name, typeId, seqId, nil + } + if p.strictRead { + return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Missing version in ReadMessageBegin")) + } + name, e2 := p.readStringBody(size) + if e2 != nil { + return name, typeId, seqId, e2 + } + b, e3 := p.ReadByte() + if e3 != nil { + return name, typeId, seqId, e3 + } + typeId = TMessageType(b) + seqId, e4 := p.ReadI32() + if e4 != nil { + return name, typeId, seqId, e4 + } + return name, typeId, seqId, nil +} + +func (p *TBinaryProtocol) ReadMessageEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadStructBegin() (name string, err error) { + return +} + +func (p *TBinaryProtocol) ReadStructEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err error) { + t, err := p.ReadByte() + typeId = TType(t) + if err != nil { + return name, typeId, seqId, err + } + if t != STOP { + seqId, err = p.ReadI16() + } + return name, typeId, seqId, err +} + +func (p *TBinaryProtocol) ReadFieldEnd() error { + return nil +} + +var invalidDataLength = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Invalid data length")) + +func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) { + k, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + kType = TType(k) + v, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + vType = TType(v) + size32, e := p.ReadI32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + return kType, vType, size, nil +} + +func (p *TBinaryProtocol) ReadMapEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error) { + b, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + elemType = TType(b) + size32, e := p.ReadI32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + + return +} + +func (p *TBinaryProtocol) ReadListEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) { + b, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + elemType = TType(b) + size32, e := p.ReadI32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + return elemType, size, nil +} + +func (p *TBinaryProtocol) ReadSetEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadBool() (bool, error) { + b, e := p.ReadByte() + v := true + if b != 1 { + v = false + } + return v, e +} + +func (p *TBinaryProtocol) ReadByte() (int8, error) { + v, err := p.trans.ReadByte() + return int8(v), err +} + +func (p *TBinaryProtocol) ReadI16() (value int16, err error) { + buf := p.buffer[0:2] + err = p.readAll(buf) + value = int16(binary.BigEndian.Uint16(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadI32() (value int32, err error) { + buf := p.buffer[0:4] + err = p.readAll(buf) + value = int32(binary.BigEndian.Uint32(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadI64() (value int64, err error) { + buf := p.buffer[0:8] + err = p.readAll(buf) + value = int64(binary.BigEndian.Uint64(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadDouble() (value float64, err error) { + buf := p.buffer[0:8] + err = p.readAll(buf) + value = math.Float64frombits(binary.BigEndian.Uint64(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadString() (value string, err error) { + size, e := p.ReadI32() + if e != nil { + return "", e + } + if size < 0 { + err = invalidDataLength + return + } + + return p.readStringBody(size) +} + +func (p *TBinaryProtocol) ReadBinary() ([]byte, error) { + size, e := p.ReadI32() + if e != nil { + return nil, e + } + if size < 0 { + return nil, invalidDataLength + } + if uint64(size) > p.trans.RemainingBytes() { + return nil, invalidDataLength + } + + isize := int(size) + buf := make([]byte, isize) + _, err := io.ReadFull(p.trans, buf) + return buf, NewTProtocolException(err) +} + +func (p *TBinaryProtocol) Flush(ctx context.Context) (err error) { + return NewTProtocolException(p.trans.Flush(ctx)) +} + +func (p *TBinaryProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TBinaryProtocol) Transport() TTransport { + return p.origTransport +} + +func (p *TBinaryProtocol) readAll(buf []byte) error { + _, err := io.ReadFull(p.reader, buf) + return NewTProtocolException(err) +} + +const readLimit = 32768 + +func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) { + if size < 0 { + return "", nil + } + if uint64(size) > p.trans.RemainingBytes() { + return "", invalidDataLength + } + + var ( + buf bytes.Buffer + e error + b []byte + ) + + switch { + case int(size) <= len(p.buffer): + b = p.buffer[:size] // avoids allocation for small reads + case int(size) < readLimit: + b = make([]byte, size) + default: + b = make([]byte, readLimit) + } + + for size > 0 { + _, e = io.ReadFull(p.trans, b) + buf.Write(b) + if e != nil { + break + } + size -= readLimit + if size < readLimit && size > 0 { + b = b[:size] + } + } + return buf.String(), NewTProtocolException(e) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/buffered_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/buffered_transport.go new file mode 100644 index 000000000..96702061b --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/buffered_transport.go @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bufio" + "context" +) + +type TBufferedTransportFactory struct { + size int +} + +type TBufferedTransport struct { + bufio.ReadWriter + tp TTransport +} + +func (p *TBufferedTransportFactory) GetTransport(trans TTransport) (TTransport, error) { + return NewTBufferedTransport(trans, p.size), nil +} + +func NewTBufferedTransportFactory(bufferSize int) *TBufferedTransportFactory { + return &TBufferedTransportFactory{size: bufferSize} +} + +func NewTBufferedTransport(trans TTransport, bufferSize int) *TBufferedTransport { + return &TBufferedTransport{ + ReadWriter: bufio.ReadWriter{ + Reader: bufio.NewReaderSize(trans, bufferSize), + Writer: bufio.NewWriterSize(trans, bufferSize), + }, + tp: trans, + } +} + +func (p *TBufferedTransport) IsOpen() bool { + return p.tp.IsOpen() +} + +func (p *TBufferedTransport) Open() (err error) { + return p.tp.Open() +} + +func (p *TBufferedTransport) Close() (err error) { + return p.tp.Close() +} + +func (p *TBufferedTransport) Read(b []byte) (int, error) { + n, err := p.ReadWriter.Read(b) + if err != nil { + p.ReadWriter.Reader.Reset(p.tp) + } + return n, err +} + +func (p *TBufferedTransport) Write(b []byte) (int, error) { + n, err := p.ReadWriter.Write(b) + if err != nil { + p.ReadWriter.Writer.Reset(p.tp) + } + return n, err +} + +func (p *TBufferedTransport) Flush(ctx context.Context) error { + if err := p.ReadWriter.Flush(); err != nil { + p.ReadWriter.Writer.Reset(p.tp) + return err + } + return p.tp.Flush(ctx) +} + +func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) { + return p.tp.RemainingBytes() +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/client.go b/vendor/github.com/apache/thrift/lib/go/thrift/client.go new file mode 100644 index 000000000..28791ccd0 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/client.go @@ -0,0 +1,85 @@ +package thrift + +import ( + "context" + "fmt" +) + +type TClient interface { + Call(ctx context.Context, method string, args, result TStruct) error +} + +type TStandardClient struct { + seqId int32 + iprot, oprot TProtocol +} + +// TStandardClient implements TClient, and uses the standard message format for Thrift. +// It is not safe for concurrent use. +func NewTStandardClient(inputProtocol, outputProtocol TProtocol) *TStandardClient { + return &TStandardClient{ + iprot: inputProtocol, + oprot: outputProtocol, + } +} + +func (p *TStandardClient) Send(ctx context.Context, oprot TProtocol, seqId int32, method string, args TStruct) error { + if err := oprot.WriteMessageBegin(method, CALL, seqId); err != nil { + return err + } + if err := args.Write(oprot); err != nil { + return err + } + if err := oprot.WriteMessageEnd(); err != nil { + return err + } + return oprot.Flush(ctx) +} + +func (p *TStandardClient) Recv(iprot TProtocol, seqId int32, method string, result TStruct) error { + rMethod, rTypeId, rSeqId, err := iprot.ReadMessageBegin() + if err != nil { + return err + } + + if method != rMethod { + return NewTApplicationException(WRONG_METHOD_NAME, fmt.Sprintf("%s: wrong method name", method)) + } else if seqId != rSeqId { + return NewTApplicationException(BAD_SEQUENCE_ID, fmt.Sprintf("%s: out of order sequence response", method)) + } else if rTypeId == EXCEPTION { + var exception tApplicationException + if err := exception.Read(iprot); err != nil { + return err + } + + if err := iprot.ReadMessageEnd(); err != nil { + return err + } + + return &exception + } else if rTypeId != REPLY { + return NewTApplicationException(INVALID_MESSAGE_TYPE_EXCEPTION, fmt.Sprintf("%s: invalid message type", method)) + } + + if err := result.Read(iprot); err != nil { + return err + } + + return iprot.ReadMessageEnd() +} + +func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) error { + p.seqId++ + seqId := p.seqId + + if err := p.Send(ctx, p.oprot, seqId, method, args); err != nil { + return err + } + + // method is oneway + if result == nil { + return nil + } + + return p.Recv(p.iprot, seqId, method, result) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go new file mode 100644 index 000000000..66fbf5c33 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go @@ -0,0 +1,816 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "encoding/binary" + "fmt" + "io" + "math" +) + +const ( + COMPACT_PROTOCOL_ID = 0x082 + COMPACT_VERSION = 1 + COMPACT_VERSION_MASK = 0x1f + COMPACT_TYPE_MASK = 0x0E0 + COMPACT_TYPE_BITS = 0x07 + COMPACT_TYPE_SHIFT_AMOUNT = 5 +) + +type tCompactType byte + +const ( + COMPACT_BOOLEAN_TRUE = 0x01 + COMPACT_BOOLEAN_FALSE = 0x02 + COMPACT_BYTE = 0x03 + COMPACT_I16 = 0x04 + COMPACT_I32 = 0x05 + COMPACT_I64 = 0x06 + COMPACT_DOUBLE = 0x07 + COMPACT_BINARY = 0x08 + COMPACT_LIST = 0x09 + COMPACT_SET = 0x0A + COMPACT_MAP = 0x0B + COMPACT_STRUCT = 0x0C +) + +var ( + ttypeToCompactType map[TType]tCompactType +) + +func init() { + ttypeToCompactType = map[TType]tCompactType{ + STOP: STOP, + BOOL: COMPACT_BOOLEAN_TRUE, + BYTE: COMPACT_BYTE, + I16: COMPACT_I16, + I32: COMPACT_I32, + I64: COMPACT_I64, + DOUBLE: COMPACT_DOUBLE, + STRING: COMPACT_BINARY, + LIST: COMPACT_LIST, + SET: COMPACT_SET, + MAP: COMPACT_MAP, + STRUCT: COMPACT_STRUCT, + } +} + +type TCompactProtocolFactory struct{} + +func NewTCompactProtocolFactory() *TCompactProtocolFactory { + return &TCompactProtocolFactory{} +} + +func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol { + return NewTCompactProtocol(trans) +} + +type TCompactProtocol struct { + trans TRichTransport + origTransport TTransport + + // Used to keep track of the last field for the current and previous structs, + // so we can do the delta stuff. + lastField []int + lastFieldId int + + // If we encounter a boolean field begin, save the TField here so it can + // have the value incorporated. + booleanFieldName string + booleanFieldId int16 + booleanFieldPending bool + + // If we read a field header, and it's a boolean field, save the boolean + // value here so that readBool can use it. + boolValue bool + boolValueIsNotNull bool + buffer [64]byte +} + +// Create a TCompactProtocol given a TTransport +func NewTCompactProtocol(trans TTransport) *TCompactProtocol { + p := &TCompactProtocol{origTransport: trans, lastField: []int{}} + if et, ok := trans.(TRichTransport); ok { + p.trans = et + } else { + p.trans = NewTRichTransport(trans) + } + + return p + +} + +// +// Public Writing methods. +// + +// Write a message header to the wire. Compact Protocol messages contain the +// protocol version so we can migrate forwards in the future if need be. +func (p *TCompactProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) error { + err := p.writeByteDirect(COMPACT_PROTOCOL_ID) + if err != nil { + return NewTProtocolException(err) + } + err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK)) + if err != nil { + return NewTProtocolException(err) + } + _, err = p.writeVarint32(seqid) + if err != nil { + return NewTProtocolException(err) + } + e := p.WriteString(name) + return e + +} + +func (p *TCompactProtocol) WriteMessageEnd() error { return nil } + +// Write a struct begin. This doesn't actually put anything on the wire. We +// use it as an opportunity to put special placeholder markers on the field +// stack so we can get the field id deltas correct. +func (p *TCompactProtocol) WriteStructBegin(name string) error { + p.lastField = append(p.lastField, p.lastFieldId) + p.lastFieldId = 0 + return nil +} + +// Write a struct end. This doesn't actually put anything on the wire. We use +// this as an opportunity to pop the last field from the current struct off +// of the field stack. +func (p *TCompactProtocol) WriteStructEnd() error { + p.lastFieldId = p.lastField[len(p.lastField)-1] + p.lastField = p.lastField[:len(p.lastField)-1] + return nil +} + +func (p *TCompactProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + if typeId == BOOL { + // we want to possibly include the value, so we'll wait. + p.booleanFieldName, p.booleanFieldId, p.booleanFieldPending = name, id, true + return nil + } + _, err := p.writeFieldBeginInternal(name, typeId, id, 0xFF) + return NewTProtocolException(err) +} + +// The workhorse of writeFieldBegin. It has the option of doing a +// 'type override' of the type header. This is used specifically in the +// boolean field case. +func (p *TCompactProtocol) writeFieldBeginInternal(name string, typeId TType, id int16, typeOverride byte) (int, error) { + // short lastField = lastField_.pop(); + + // if there's a type override, use that. + var typeToWrite byte + if typeOverride == 0xFF { + typeToWrite = byte(p.getCompactType(typeId)) + } else { + typeToWrite = typeOverride + } + // check if we can use delta encoding for the field id + fieldId := int(id) + written := 0 + if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 { + // write them together + err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite) + if err != nil { + return 0, err + } + } else { + // write them separate + err := p.writeByteDirect(typeToWrite) + if err != nil { + return 0, err + } + err = p.WriteI16(id) + written = 1 + 2 + if err != nil { + return 0, err + } + } + + p.lastFieldId = fieldId + // p.lastField.Push(field.id); + return written, nil +} + +func (p *TCompactProtocol) WriteFieldEnd() error { return nil } + +func (p *TCompactProtocol) WriteFieldStop() error { + err := p.writeByteDirect(STOP) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + if size == 0 { + err := p.writeByteDirect(0) + return NewTProtocolException(err) + } + _, err := p.writeVarint32(int32(size)) + if err != nil { + return NewTProtocolException(err) + } + err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType))) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteMapEnd() error { return nil } + +// Write a list header. +func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) error { + _, err := p.writeCollectionBegin(elemType, size) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteListEnd() error { return nil } + +// Write a set header. +func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) error { + _, err := p.writeCollectionBegin(elemType, size) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteSetEnd() error { return nil } + +func (p *TCompactProtocol) WriteBool(value bool) error { + v := byte(COMPACT_BOOLEAN_FALSE) + if value { + v = byte(COMPACT_BOOLEAN_TRUE) + } + if p.booleanFieldPending { + // we haven't written the field header yet + _, err := p.writeFieldBeginInternal(p.booleanFieldName, BOOL, p.booleanFieldId, v) + p.booleanFieldPending = false + return NewTProtocolException(err) + } + // we're not part of a field, so just write the value. + err := p.writeByteDirect(v) + return NewTProtocolException(err) +} + +// Write a byte. Nothing to see here! +func (p *TCompactProtocol) WriteByte(value int8) error { + err := p.writeByteDirect(byte(value)) + return NewTProtocolException(err) +} + +// Write an I16 as a zigzag varint. +func (p *TCompactProtocol) WriteI16(value int16) error { + _, err := p.writeVarint32(p.int32ToZigzag(int32(value))) + return NewTProtocolException(err) +} + +// Write an i32 as a zigzag varint. +func (p *TCompactProtocol) WriteI32(value int32) error { + _, err := p.writeVarint32(p.int32ToZigzag(value)) + return NewTProtocolException(err) +} + +// Write an i64 as a zigzag varint. +func (p *TCompactProtocol) WriteI64(value int64) error { + _, err := p.writeVarint64(p.int64ToZigzag(value)) + return NewTProtocolException(err) +} + +// Write a double to the wire as 8 bytes. +func (p *TCompactProtocol) WriteDouble(value float64) error { + buf := p.buffer[0:8] + binary.LittleEndian.PutUint64(buf, math.Float64bits(value)) + _, err := p.trans.Write(buf) + return NewTProtocolException(err) +} + +// Write a string to the wire with a varint size preceding. +func (p *TCompactProtocol) WriteString(value string) error { + _, e := p.writeVarint32(int32(len(value))) + if e != nil { + return NewTProtocolException(e) + } + if len(value) > 0 { + } + _, e = p.trans.WriteString(value) + return e +} + +// Write a byte array, using a varint for the size. +func (p *TCompactProtocol) WriteBinary(bin []byte) error { + _, e := p.writeVarint32(int32(len(bin))) + if e != nil { + return NewTProtocolException(e) + } + if len(bin) > 0 { + _, e = p.trans.Write(bin) + return NewTProtocolException(e) + } + return nil +} + +// +// Reading methods. +// + +// Read a message header. +func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + + protocolId, err := p.readByteDirect() + if err != nil { + return + } + + if protocolId != COMPACT_PROTOCOL_ID { + e := fmt.Errorf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId) + return "", typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, e) + } + + versionAndType, err := p.readByteDirect() + if err != nil { + return + } + + version := versionAndType & COMPACT_VERSION_MASK + typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS) + if version != COMPACT_VERSION { + e := fmt.Errorf("Expected version %02x but got %02x", COMPACT_VERSION, version) + err = NewTProtocolExceptionWithType(BAD_VERSION, e) + return + } + seqId, e := p.readVarint32() + if e != nil { + err = NewTProtocolException(e) + return + } + name, err = p.ReadString() + return +} + +func (p *TCompactProtocol) ReadMessageEnd() error { return nil } + +// Read a struct begin. There's nothing on the wire for this, but it is our +// opportunity to push a new struct begin marker onto the field stack. +func (p *TCompactProtocol) ReadStructBegin() (name string, err error) { + p.lastField = append(p.lastField, p.lastFieldId) + p.lastFieldId = 0 + return +} + +// Doesn't actually consume any wire data, just removes the last field for +// this struct from the field stack. +func (p *TCompactProtocol) ReadStructEnd() error { + // consume the last field we read off the wire. + p.lastFieldId = p.lastField[len(p.lastField)-1] + p.lastField = p.lastField[:len(p.lastField)-1] + return nil +} + +// Read a field header off the wire. +func (p *TCompactProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err error) { + t, err := p.readByteDirect() + if err != nil { + return + } + + // if it's a stop, then we can return immediately, as the struct is over. + if (t & 0x0f) == STOP { + return "", STOP, 0, nil + } + + // mask off the 4 MSB of the type header. it could contain a field id delta. + modifier := int16((t & 0xf0) >> 4) + if modifier == 0 { + // not a delta. look ahead for the zigzag varint field id. + id, err = p.ReadI16() + if err != nil { + return + } + } else { + // has a delta. add the delta to the last read field id. + id = int16(p.lastFieldId) + modifier + } + typeId, e := p.getTType(tCompactType(t & 0x0f)) + if e != nil { + err = NewTProtocolException(e) + return + } + + // if this happens to be a boolean field, the value is encoded in the type + if p.isBoolType(t) { + // save the boolean value in a special instance variable. + p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE) + p.boolValueIsNotNull = true + } + + // push the new field onto the field stack so we can keep the deltas going. + p.lastFieldId = int(id) + return +} + +func (p *TCompactProtocol) ReadFieldEnd() error { return nil } + +// Read a map header off the wire. If the size is zero, skip reading the key +// and value type. This means that 0-length maps will yield TMaps without the +// "correct" types. +func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err error) { + size32, e := p.readVarint32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + + keyAndValueType := byte(STOP) + if size != 0 { + keyAndValueType, err = p.readByteDirect() + if err != nil { + return + } + } + keyType, _ = p.getTType(tCompactType(keyAndValueType >> 4)) + valueType, _ = p.getTType(tCompactType(keyAndValueType & 0xf)) + return +} + +func (p *TCompactProtocol) ReadMapEnd() error { return nil } + +// Read a list header off the wire. If the list size is 0-14, the size will +// be packed into the element type header. If it's a longer list, the 4 MSB +// of the element type header will be 0xF, and a varint will follow with the +// true size. +func (p *TCompactProtocol) ReadListBegin() (elemType TType, size int, err error) { + size_and_type, err := p.readByteDirect() + if err != nil { + return + } + size = int((size_and_type >> 4) & 0x0f) + if size == 15 { + size2, e := p.readVarint32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size2 < 0 { + err = invalidDataLength + return + } + size = int(size2) + } + elemType, e := p.getTType(tCompactType(size_and_type)) + if e != nil { + err = NewTProtocolException(e) + return + } + return +} + +func (p *TCompactProtocol) ReadListEnd() error { return nil } + +// Read a set header off the wire. If the set size is 0-14, the size will +// be packed into the element type header. If it's a longer set, the 4 MSB +// of the element type header will be 0xF, and a varint will follow with the +// true size. +func (p *TCompactProtocol) ReadSetBegin() (elemType TType, size int, err error) { + return p.ReadListBegin() +} + +func (p *TCompactProtocol) ReadSetEnd() error { return nil } + +// Read a boolean off the wire. If this is a boolean field, the value should +// already have been read during readFieldBegin, so we'll just consume the +// pre-stored value. Otherwise, read a byte. +func (p *TCompactProtocol) ReadBool() (value bool, err error) { + if p.boolValueIsNotNull { + p.boolValueIsNotNull = false + return p.boolValue, nil + } + v, err := p.readByteDirect() + return v == COMPACT_BOOLEAN_TRUE, err +} + +// Read a single byte off the wire. Nothing interesting here. +func (p *TCompactProtocol) ReadByte() (int8, error) { + v, err := p.readByteDirect() + if err != nil { + return 0, NewTProtocolException(err) + } + return int8(v), err +} + +// Read an i16 from the wire as a zigzag varint. +func (p *TCompactProtocol) ReadI16() (value int16, err error) { + v, err := p.ReadI32() + return int16(v), err +} + +// Read an i32 from the wire as a zigzag varint. +func (p *TCompactProtocol) ReadI32() (value int32, err error) { + v, e := p.readVarint32() + if e != nil { + return 0, NewTProtocolException(e) + } + value = p.zigzagToInt32(v) + return value, nil +} + +// Read an i64 from the wire as a zigzag varint. +func (p *TCompactProtocol) ReadI64() (value int64, err error) { + v, e := p.readVarint64() + if e != nil { + return 0, NewTProtocolException(e) + } + value = p.zigzagToInt64(v) + return value, nil +} + +// No magic here - just read a double off the wire. +func (p *TCompactProtocol) ReadDouble() (value float64, err error) { + longBits := p.buffer[0:8] + _, e := io.ReadFull(p.trans, longBits) + if e != nil { + return 0.0, NewTProtocolException(e) + } + return math.Float64frombits(p.bytesToUint64(longBits)), nil +} + +// Reads a []byte (via readBinary), and then UTF-8 decodes it. +func (p *TCompactProtocol) ReadString() (value string, err error) { + length, e := p.readVarint32() + if e != nil { + return "", NewTProtocolException(e) + } + if length < 0 { + return "", invalidDataLength + } + if uint64(length) > p.trans.RemainingBytes() { + return "", invalidDataLength + } + + if length == 0 { + return "", nil + } + var buf []byte + if length <= int32(len(p.buffer)) { + buf = p.buffer[0:length] + } else { + buf = make([]byte, length) + } + _, e = io.ReadFull(p.trans, buf) + return string(buf), NewTProtocolException(e) +} + +// Read a []byte from the wire. +func (p *TCompactProtocol) ReadBinary() (value []byte, err error) { + length, e := p.readVarint32() + if e != nil { + return nil, NewTProtocolException(e) + } + if length == 0 { + return []byte{}, nil + } + if length < 0 { + return nil, invalidDataLength + } + if uint64(length) > p.trans.RemainingBytes() { + return nil, invalidDataLength + } + + buf := make([]byte, length) + _, e = io.ReadFull(p.trans, buf) + return buf, NewTProtocolException(e) +} + +func (p *TCompactProtocol) Flush(ctx context.Context) (err error) { + return NewTProtocolException(p.trans.Flush(ctx)) +} + +func (p *TCompactProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TCompactProtocol) Transport() TTransport { + return p.origTransport +} + +// +// Internal writing methods +// + +// Abstract method for writing the start of lists and sets. List and sets on +// the wire differ only by the type indicator. +func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, error) { + if size <= 14 { + return 1, p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType)))) + } + err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType))) + if err != nil { + return 0, err + } + m, err := p.writeVarint32(int32(size)) + return 1 + m, err +} + +// Write an i32 as a varint. Results in 1-5 bytes on the wire. +// TODO(pomack): make a permanent buffer like writeVarint64? +func (p *TCompactProtocol) writeVarint32(n int32) (int, error) { + i32buf := p.buffer[0:5] + idx := 0 + for { + if (n & ^0x7F) == 0 { + i32buf[idx] = byte(n) + idx++ + // p.writeByteDirect(byte(n)); + break + // return; + } else { + i32buf[idx] = byte((n & 0x7F) | 0x80) + idx++ + // p.writeByteDirect(byte(((n & 0x7F) | 0x80))); + u := uint32(n) + n = int32(u >> 7) + } + } + return p.trans.Write(i32buf[0:idx]) +} + +// Write an i64 as a varint. Results in 1-10 bytes on the wire. +func (p *TCompactProtocol) writeVarint64(n int64) (int, error) { + varint64out := p.buffer[0:10] + idx := 0 + for { + if (n & ^0x7F) == 0 { + varint64out[idx] = byte(n) + idx++ + break + } else { + varint64out[idx] = byte((n & 0x7F) | 0x80) + idx++ + u := uint64(n) + n = int64(u >> 7) + } + } + return p.trans.Write(varint64out[0:idx]) +} + +// Convert l into a zigzag long. This allows negative numbers to be +// represented compactly as a varint. +func (p *TCompactProtocol) int64ToZigzag(l int64) int64 { + return (l << 1) ^ (l >> 63) +} + +// Convert l into a zigzag long. This allows negative numbers to be +// represented compactly as a varint. +func (p *TCompactProtocol) int32ToZigzag(n int32) int32 { + return (n << 1) ^ (n >> 31) +} + +func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) { + binary.LittleEndian.PutUint64(buf, n) +} + +func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) { + binary.LittleEndian.PutUint64(buf, uint64(n)) +} + +// Writes a byte without any possibility of all that field header nonsense. +// Used internally by other writing methods that know they need to write a byte. +func (p *TCompactProtocol) writeByteDirect(b byte) error { + return p.trans.WriteByte(b) +} + +// Writes a byte without any possibility of all that field header nonsense. +func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, error) { + return 1, p.writeByteDirect(byte(n)) +} + +// +// Internal reading methods +// + +// Read an i32 from the wire as a varint. The MSB of each byte is set +// if there is another byte to follow. This can read up to 5 bytes. +func (p *TCompactProtocol) readVarint32() (int32, error) { + // if the wire contains the right stuff, this will just truncate the i64 we + // read and get us the right sign. + v, err := p.readVarint64() + return int32(v), err +} + +// Read an i64 from the wire as a proper varint. The MSB of each byte is set +// if there is another byte to follow. This can read up to 10 bytes. +func (p *TCompactProtocol) readVarint64() (int64, error) { + shift := uint(0) + result := int64(0) + for { + b, err := p.readByteDirect() + if err != nil { + return 0, err + } + result |= int64(b&0x7f) << shift + if (b & 0x80) != 0x80 { + break + } + shift += 7 + } + return result, nil +} + +// Read a byte, unlike ReadByte that reads Thrift-byte that is i8. +func (p *TCompactProtocol) readByteDirect() (byte, error) { + return p.trans.ReadByte() +} + +// +// encoding helpers +// + +// Convert from zigzag int to int. +func (p *TCompactProtocol) zigzagToInt32(n int32) int32 { + u := uint32(n) + return int32(u>>1) ^ -(n & 1) +} + +// Convert from zigzag long to long. +func (p *TCompactProtocol) zigzagToInt64(n int64) int64 { + u := uint64(n) + return int64(u>>1) ^ -(n & 1) +} + +// Note that it's important that the mask bytes are long literals, +// otherwise they'll default to ints, and when you shift an int left 56 bits, +// you just get a messed up int. +func (p *TCompactProtocol) bytesToInt64(b []byte) int64 { + return int64(binary.LittleEndian.Uint64(b)) +} + +// Note that it's important that the mask bytes are long literals, +// otherwise they'll default to ints, and when you shift an int left 56 bits, +// you just get a messed up int. +func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 { + return binary.LittleEndian.Uint64(b) +} + +// +// type testing and converting +// + +func (p *TCompactProtocol) isBoolType(b byte) bool { + return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE +} + +// Given a tCompactType constant, convert it to its corresponding +// TType value. +func (p *TCompactProtocol) getTType(t tCompactType) (TType, error) { + switch byte(t) & 0x0f { + case STOP: + return STOP, nil + case COMPACT_BOOLEAN_FALSE, COMPACT_BOOLEAN_TRUE: + return BOOL, nil + case COMPACT_BYTE: + return BYTE, nil + case COMPACT_I16: + return I16, nil + case COMPACT_I32: + return I32, nil + case COMPACT_I64: + return I64, nil + case COMPACT_DOUBLE: + return DOUBLE, nil + case COMPACT_BINARY: + return STRING, nil + case COMPACT_LIST: + return LIST, nil + case COMPACT_SET: + return SET, nil + case COMPACT_MAP: + return MAP, nil + case COMPACT_STRUCT: + return STRUCT, nil + } + return STOP, TException(fmt.Errorf("don't know what type: %v", t&0x0f)) +} + +// Given a TType value, find the appropriate TCompactProtocol.Types constant. +func (p *TCompactProtocol) getCompactType(t TType) tCompactType { + return ttypeToCompactType[t] +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/context.go b/vendor/github.com/apache/thrift/lib/go/thrift/context.go new file mode 100644 index 000000000..d15c1bcf8 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/context.go @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import "context" + +var defaultCtx = context.Background() diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/debug_protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/debug_protocol.go new file mode 100644 index 000000000..57943e0f3 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/debug_protocol.go @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "log" +) + +type TDebugProtocol struct { + Delegate TProtocol + LogPrefix string +} + +type TDebugProtocolFactory struct { + Underlying TProtocolFactory + LogPrefix string +} + +func NewTDebugProtocolFactory(underlying TProtocolFactory, logPrefix string) *TDebugProtocolFactory { + return &TDebugProtocolFactory{ + Underlying: underlying, + LogPrefix: logPrefix, + } +} + +func (t *TDebugProtocolFactory) GetProtocol(trans TTransport) TProtocol { + return &TDebugProtocol{ + Delegate: t.Underlying.GetProtocol(trans), + LogPrefix: t.LogPrefix, + } +} + +func (tdp *TDebugProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) error { + err := tdp.Delegate.WriteMessageBegin(name, typeId, seqid) + log.Printf("%sWriteMessageBegin(name=%#v, typeId=%#v, seqid=%#v) => %#v", tdp.LogPrefix, name, typeId, seqid, err) + return err +} +func (tdp *TDebugProtocol) WriteMessageEnd() error { + err := tdp.Delegate.WriteMessageEnd() + log.Printf("%sWriteMessageEnd() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteStructBegin(name string) error { + err := tdp.Delegate.WriteStructBegin(name) + log.Printf("%sWriteStructBegin(name=%#v) => %#v", tdp.LogPrefix, name, err) + return err +} +func (tdp *TDebugProtocol) WriteStructEnd() error { + err := tdp.Delegate.WriteStructEnd() + log.Printf("%sWriteStructEnd() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + err := tdp.Delegate.WriteFieldBegin(name, typeId, id) + log.Printf("%sWriteFieldBegin(name=%#v, typeId=%#v, id%#v) => %#v", tdp.LogPrefix, name, typeId, id, err) + return err +} +func (tdp *TDebugProtocol) WriteFieldEnd() error { + err := tdp.Delegate.WriteFieldEnd() + log.Printf("%sWriteFieldEnd() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteFieldStop() error { + err := tdp.Delegate.WriteFieldStop() + log.Printf("%sWriteFieldStop() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + err := tdp.Delegate.WriteMapBegin(keyType, valueType, size) + log.Printf("%sWriteMapBegin(keyType=%#v, valueType=%#v, size=%#v) => %#v", tdp.LogPrefix, keyType, valueType, size, err) + return err +} +func (tdp *TDebugProtocol) WriteMapEnd() error { + err := tdp.Delegate.WriteMapEnd() + log.Printf("%sWriteMapEnd() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteListBegin(elemType TType, size int) error { + err := tdp.Delegate.WriteListBegin(elemType, size) + log.Printf("%sWriteListBegin(elemType=%#v, size=%#v) => %#v", tdp.LogPrefix, elemType, size, err) + return err +} +func (tdp *TDebugProtocol) WriteListEnd() error { + err := tdp.Delegate.WriteListEnd() + log.Printf("%sWriteListEnd() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteSetBegin(elemType TType, size int) error { + err := tdp.Delegate.WriteSetBegin(elemType, size) + log.Printf("%sWriteSetBegin(elemType=%#v, size=%#v) => %#v", tdp.LogPrefix, elemType, size, err) + return err +} +func (tdp *TDebugProtocol) WriteSetEnd() error { + err := tdp.Delegate.WriteSetEnd() + log.Printf("%sWriteSetEnd() => %#v", tdp.LogPrefix, err) + return err +} +func (tdp *TDebugProtocol) WriteBool(value bool) error { + err := tdp.Delegate.WriteBool(value) + log.Printf("%sWriteBool(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteByte(value int8) error { + err := tdp.Delegate.WriteByte(value) + log.Printf("%sWriteByte(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteI16(value int16) error { + err := tdp.Delegate.WriteI16(value) + log.Printf("%sWriteI16(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteI32(value int32) error { + err := tdp.Delegate.WriteI32(value) + log.Printf("%sWriteI32(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteI64(value int64) error { + err := tdp.Delegate.WriteI64(value) + log.Printf("%sWriteI64(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteDouble(value float64) error { + err := tdp.Delegate.WriteDouble(value) + log.Printf("%sWriteDouble(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteString(value string) error { + err := tdp.Delegate.WriteString(value) + log.Printf("%sWriteString(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} +func (tdp *TDebugProtocol) WriteBinary(value []byte) error { + err := tdp.Delegate.WriteBinary(value) + log.Printf("%sWriteBinary(value=%#v) => %#v", tdp.LogPrefix, value, err) + return err +} + +func (tdp *TDebugProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err error) { + name, typeId, seqid, err = tdp.Delegate.ReadMessageBegin() + log.Printf("%sReadMessageBegin() (name=%#v, typeId=%#v, seqid=%#v, err=%#v)", tdp.LogPrefix, name, typeId, seqid, err) + return +} +func (tdp *TDebugProtocol) ReadMessageEnd() (err error) { + err = tdp.Delegate.ReadMessageEnd() + log.Printf("%sReadMessageEnd() err=%#v", tdp.LogPrefix, err) + return +} +func (tdp *TDebugProtocol) ReadStructBegin() (name string, err error) { + name, err = tdp.Delegate.ReadStructBegin() + log.Printf("%sReadStructBegin() (name%#v, err=%#v)", tdp.LogPrefix, name, err) + return +} +func (tdp *TDebugProtocol) ReadStructEnd() (err error) { + err = tdp.Delegate.ReadStructEnd() + log.Printf("%sReadStructEnd() err=%#v", tdp.LogPrefix, err) + return +} +func (tdp *TDebugProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err error) { + name, typeId, id, err = tdp.Delegate.ReadFieldBegin() + log.Printf("%sReadFieldBegin() (name=%#v, typeId=%#v, id=%#v, err=%#v)", tdp.LogPrefix, name, typeId, id, err) + return +} +func (tdp *TDebugProtocol) ReadFieldEnd() (err error) { + err = tdp.Delegate.ReadFieldEnd() + log.Printf("%sReadFieldEnd() err=%#v", tdp.LogPrefix, err) + return +} +func (tdp *TDebugProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err error) { + keyType, valueType, size, err = tdp.Delegate.ReadMapBegin() + log.Printf("%sReadMapBegin() (keyType=%#v, valueType=%#v, size=%#v, err=%#v)", tdp.LogPrefix, keyType, valueType, size, err) + return +} +func (tdp *TDebugProtocol) ReadMapEnd() (err error) { + err = tdp.Delegate.ReadMapEnd() + log.Printf("%sReadMapEnd() err=%#v", tdp.LogPrefix, err) + return +} +func (tdp *TDebugProtocol) ReadListBegin() (elemType TType, size int, err error) { + elemType, size, err = tdp.Delegate.ReadListBegin() + log.Printf("%sReadListBegin() (elemType=%#v, size=%#v, err=%#v)", tdp.LogPrefix, elemType, size, err) + return +} +func (tdp *TDebugProtocol) ReadListEnd() (err error) { + err = tdp.Delegate.ReadListEnd() + log.Printf("%sReadListEnd() err=%#v", tdp.LogPrefix, err) + return +} +func (tdp *TDebugProtocol) ReadSetBegin() (elemType TType, size int, err error) { + elemType, size, err = tdp.Delegate.ReadSetBegin() + log.Printf("%sReadSetBegin() (elemType=%#v, size=%#v, err=%#v)", tdp.LogPrefix, elemType, size, err) + return +} +func (tdp *TDebugProtocol) ReadSetEnd() (err error) { + err = tdp.Delegate.ReadSetEnd() + log.Printf("%sReadSetEnd() err=%#v", tdp.LogPrefix, err) + return +} +func (tdp *TDebugProtocol) ReadBool() (value bool, err error) { + value, err = tdp.Delegate.ReadBool() + log.Printf("%sReadBool() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadByte() (value int8, err error) { + value, err = tdp.Delegate.ReadByte() + log.Printf("%sReadByte() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadI16() (value int16, err error) { + value, err = tdp.Delegate.ReadI16() + log.Printf("%sReadI16() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadI32() (value int32, err error) { + value, err = tdp.Delegate.ReadI32() + log.Printf("%sReadI32() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadI64() (value int64, err error) { + value, err = tdp.Delegate.ReadI64() + log.Printf("%sReadI64() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadDouble() (value float64, err error) { + value, err = tdp.Delegate.ReadDouble() + log.Printf("%sReadDouble() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadString() (value string, err error) { + value, err = tdp.Delegate.ReadString() + log.Printf("%sReadString() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) ReadBinary() (value []byte, err error) { + value, err = tdp.Delegate.ReadBinary() + log.Printf("%sReadBinary() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) + return +} +func (tdp *TDebugProtocol) Skip(fieldType TType) (err error) { + err = tdp.Delegate.Skip(fieldType) + log.Printf("%sSkip(fieldType=%#v) (err=%#v)", tdp.LogPrefix, fieldType, err) + return +} +func (tdp *TDebugProtocol) Flush(ctx context.Context) (err error) { + err = tdp.Delegate.Flush(ctx) + log.Printf("%sFlush() (err=%#v)", tdp.LogPrefix, err) + return +} + +func (tdp *TDebugProtocol) Transport() TTransport { + return tdp.Delegate.Transport() +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/deserializer.go b/vendor/github.com/apache/thrift/lib/go/thrift/deserializer.go new file mode 100644 index 000000000..91a0983a4 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/deserializer.go @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +type TDeserializer struct { + Transport TTransport + Protocol TProtocol +} + +func NewTDeserializer() *TDeserializer { + var transport TTransport + transport = NewTMemoryBufferLen(1024) + + protocol := NewTBinaryProtocolFactoryDefault().GetProtocol(transport) + + return &TDeserializer{ + transport, + protocol} +} + +func (t *TDeserializer) ReadString(msg TStruct, s string) (err error) { + err = nil + if _, err = t.Transport.Write([]byte(s)); err != nil { + return + } + if err = msg.Read(t.Protocol); err != nil { + return + } + return +} + +func (t *TDeserializer) Read(msg TStruct, b []byte) (err error) { + err = nil + if _, err = t.Transport.Write(b); err != nil { + return + } + if err = msg.Read(t.Protocol); err != nil { + return + } + return +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/exception.go b/vendor/github.com/apache/thrift/lib/go/thrift/exception.go new file mode 100644 index 000000000..ea8d6f661 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/exception.go @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "errors" +) + +// Generic Thrift exception +type TException interface { + error +} + +// Prepends additional information to an error without losing the Thrift exception interface +func PrependError(prepend string, err error) error { + if t, ok := err.(TTransportException); ok { + return NewTTransportException(t.TypeId(), prepend+t.Error()) + } + if t, ok := err.(TProtocolException); ok { + return NewTProtocolExceptionWithType(t.TypeId(), errors.New(prepend+err.Error())) + } + if t, ok := err.(TApplicationException); ok { + return NewTApplicationException(t.TypeId(), prepend+t.Error()) + } + + return errors.New(prepend + err.Error()) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/field.go b/vendor/github.com/apache/thrift/lib/go/thrift/field.go new file mode 100644 index 000000000..9d6652550 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/field.go @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Helper class that encapsulates field metadata. +type field struct { + name string + typeId TType + id int +} + +func newField(n string, t TType, i int) *field { + return &field{name: n, typeId: t, id: i} +} + +func (p *field) Name() string { + if p == nil { + return "" + } + return p.name +} + +func (p *field) TypeId() TType { + if p == nil { + return TType(VOID) + } + return p.typeId +} + +func (p *field) Id() int { + if p == nil { + return -1 + } + return p.id +} + +func (p *field) String() string { + if p == nil { + return "" + } + return "" +} + +var ANONYMOUS_FIELD *field + +type fieldSlice []field + +func (p fieldSlice) Len() int { + return len(p) +} + +func (p fieldSlice) Less(i, j int) bool { + return p[i].Id() < p[j].Id() +} + +func (p fieldSlice) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} + +func init() { + ANONYMOUS_FIELD = newField("", STOP, 0) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/framed_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/framed_transport.go new file mode 100644 index 000000000..81fa65aaa --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/framed_transport.go @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bufio" + "bytes" + "context" + "encoding/binary" + "fmt" + "io" +) + +const DEFAULT_MAX_LENGTH = 16384000 + +type TFramedTransport struct { + transport TTransport + buf bytes.Buffer + reader *bufio.Reader + frameSize uint32 //Current remaining size of the frame. if ==0 read next frame header + buffer [4]byte + maxLength uint32 +} + +type tFramedTransportFactory struct { + factory TTransportFactory + maxLength uint32 +} + +func NewTFramedTransportFactory(factory TTransportFactory) TTransportFactory { + return &tFramedTransportFactory{factory: factory, maxLength: DEFAULT_MAX_LENGTH} +} + +func NewTFramedTransportFactoryMaxLength(factory TTransportFactory, maxLength uint32) TTransportFactory { + return &tFramedTransportFactory{factory: factory, maxLength: maxLength} +} + +func (p *tFramedTransportFactory) GetTransport(base TTransport) (TTransport, error) { + tt, err := p.factory.GetTransport(base) + if err != nil { + return nil, err + } + return NewTFramedTransportMaxLength(tt, p.maxLength), nil +} + +func NewTFramedTransport(transport TTransport) *TFramedTransport { + return &TFramedTransport{transport: transport, reader: bufio.NewReader(transport), maxLength: DEFAULT_MAX_LENGTH} +} + +func NewTFramedTransportMaxLength(transport TTransport, maxLength uint32) *TFramedTransport { + return &TFramedTransport{transport: transport, reader: bufio.NewReader(transport), maxLength: maxLength} +} + +func (p *TFramedTransport) Open() error { + return p.transport.Open() +} + +func (p *TFramedTransport) IsOpen() bool { + return p.transport.IsOpen() +} + +func (p *TFramedTransport) Close() error { + return p.transport.Close() +} + +func (p *TFramedTransport) Read(buf []byte) (l int, err error) { + if p.frameSize == 0 { + p.frameSize, err = p.readFrameHeader() + if err != nil { + return + } + } + if p.frameSize < uint32(len(buf)) { + frameSize := p.frameSize + tmp := make([]byte, p.frameSize) + l, err = p.Read(tmp) + copy(buf, tmp) + if err == nil { + err = NewTTransportExceptionFromError(fmt.Errorf("Not enough frame size %d to read %d bytes", frameSize, len(buf))) + return + } + } + got, err := p.reader.Read(buf) + p.frameSize = p.frameSize - uint32(got) + //sanity check + if p.frameSize < 0 { + return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Negative frame size") + } + return got, NewTTransportExceptionFromError(err) +} + +func (p *TFramedTransport) ReadByte() (c byte, err error) { + if p.frameSize == 0 { + p.frameSize, err = p.readFrameHeader() + if err != nil { + return + } + } + if p.frameSize < 1 { + return 0, NewTTransportExceptionFromError(fmt.Errorf("Not enough frame size %d to read %d bytes", p.frameSize, 1)) + } + c, err = p.reader.ReadByte() + if err == nil { + p.frameSize-- + } + return +} + +func (p *TFramedTransport) Write(buf []byte) (int, error) { + n, err := p.buf.Write(buf) + return n, NewTTransportExceptionFromError(err) +} + +func (p *TFramedTransport) WriteByte(c byte) error { + return p.buf.WriteByte(c) +} + +func (p *TFramedTransport) WriteString(s string) (n int, err error) { + return p.buf.WriteString(s) +} + +func (p *TFramedTransport) Flush(ctx context.Context) error { + size := p.buf.Len() + buf := p.buffer[:4] + binary.BigEndian.PutUint32(buf, uint32(size)) + _, err := p.transport.Write(buf) + if err != nil { + p.buf.Truncate(0) + return NewTTransportExceptionFromError(err) + } + if size > 0 { + if n, err := p.buf.WriteTo(p.transport); err != nil { + print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error(), "\n") + p.buf.Truncate(0) + return NewTTransportExceptionFromError(err) + } + } + err = p.transport.Flush(ctx) + return NewTTransportExceptionFromError(err) +} + +func (p *TFramedTransport) readFrameHeader() (uint32, error) { + buf := p.buffer[:4] + if _, err := io.ReadFull(p.reader, buf); err != nil { + return 0, err + } + size := binary.BigEndian.Uint32(buf) + if size < 0 || size > p.maxLength { + return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, fmt.Sprintf("Incorrect frame size (%d)", size)) + } + return size, nil +} + +func (p *TFramedTransport) RemainingBytes() (num_bytes uint64) { + return uint64(p.frameSize) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/http_client.go b/vendor/github.com/apache/thrift/lib/go/thrift/http_client.go new file mode 100644 index 000000000..5c82bf538 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/http_client.go @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bytes" + "context" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" +) + +// Default to using the shared http client. Library users are +// free to change this global client or specify one through +// THttpClientOptions. +var DefaultHttpClient *http.Client = http.DefaultClient + +type THttpClient struct { + client *http.Client + response *http.Response + url *url.URL + requestBuffer *bytes.Buffer + header http.Header + nsecConnectTimeout int64 + nsecReadTimeout int64 +} + +type THttpClientTransportFactory struct { + options THttpClientOptions + url string +} + +func (p *THttpClientTransportFactory) GetTransport(trans TTransport) (TTransport, error) { + if trans != nil { + t, ok := trans.(*THttpClient) + if ok && t.url != nil { + return NewTHttpClientWithOptions(t.url.String(), p.options) + } + } + return NewTHttpClientWithOptions(p.url, p.options) +} + +type THttpClientOptions struct { + // If nil, DefaultHttpClient is used + Client *http.Client +} + +func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory { + return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{}) +} + +func NewTHttpClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { + return &THttpClientTransportFactory{url: url, options: options} +} + +func NewTHttpClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { + parsedURL, err := url.Parse(urlstr) + if err != nil { + return nil, err + } + buf := make([]byte, 0, 1024) + client := options.Client + if client == nil { + client = DefaultHttpClient + } + httpHeader := map[string][]string{"Content-Type": {"application/x-thrift"}} + return &THttpClient{client: client, url: parsedURL, requestBuffer: bytes.NewBuffer(buf), header: httpHeader}, nil +} + +func NewTHttpClient(urlstr string) (TTransport, error) { + return NewTHttpClientWithOptions(urlstr, THttpClientOptions{}) +} + +// Set the HTTP Header for this specific Thrift Transport +// It is important that you first assert the TTransport as a THttpClient type +// like so: +// +// httpTrans := trans.(THttpClient) +// httpTrans.SetHeader("User-Agent","Thrift Client 1.0") +func (p *THttpClient) SetHeader(key string, value string) { + p.header.Add(key, value) +} + +// Get the HTTP Header represented by the supplied Header Key for this specific Thrift Transport +// It is important that you first assert the TTransport as a THttpClient type +// like so: +// +// httpTrans := trans.(THttpClient) +// hdrValue := httpTrans.GetHeader("User-Agent") +func (p *THttpClient) GetHeader(key string) string { + return p.header.Get(key) +} + +// Deletes the HTTP Header given a Header Key for this specific Thrift Transport +// It is important that you first assert the TTransport as a THttpClient type +// like so: +// +// httpTrans := trans.(THttpClient) +// httpTrans.DelHeader("User-Agent") +func (p *THttpClient) DelHeader(key string) { + p.header.Del(key) +} + +func (p *THttpClient) Open() error { + // do nothing + return nil +} + +func (p *THttpClient) IsOpen() bool { + return p.response != nil || p.requestBuffer != nil +} + +func (p *THttpClient) closeResponse() error { + var err error + if p.response != nil && p.response.Body != nil { + // The docs specify that if keepalive is enabled and the response body is not + // read to completion the connection will never be returned to the pool and + // reused. Errors are being ignored here because if the connection is invalid + // and this fails for some reason, the Close() method will do any remaining + // cleanup. + io.Copy(ioutil.Discard, p.response.Body) + + err = p.response.Body.Close() + } + + p.response = nil + return err +} + +func (p *THttpClient) Close() error { + if p.requestBuffer != nil { + p.requestBuffer.Reset() + p.requestBuffer = nil + } + return p.closeResponse() +} + +func (p *THttpClient) Read(buf []byte) (int, error) { + if p.response == nil { + return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.") + } + n, err := p.response.Body.Read(buf) + if n > 0 && (err == nil || err == io.EOF) { + return n, nil + } + return n, NewTTransportExceptionFromError(err) +} + +func (p *THttpClient) ReadByte() (c byte, err error) { + return readByte(p.response.Body) +} + +func (p *THttpClient) Write(buf []byte) (int, error) { + n, err := p.requestBuffer.Write(buf) + return n, err +} + +func (p *THttpClient) WriteByte(c byte) error { + return p.requestBuffer.WriteByte(c) +} + +func (p *THttpClient) WriteString(s string) (n int, err error) { + return p.requestBuffer.WriteString(s) +} + +func (p *THttpClient) Flush(ctx context.Context) error { + // Close any previous response body to avoid leaking connections. + p.closeResponse() + + req, err := http.NewRequest("POST", p.url.String(), p.requestBuffer) + if err != nil { + return NewTTransportExceptionFromError(err) + } + req.Header = p.header + if ctx != nil { + req = req.WithContext(ctx) + } + response, err := p.client.Do(req) + if err != nil { + return NewTTransportExceptionFromError(err) + } + if response.StatusCode != http.StatusOK { + // Close the response to avoid leaking file descriptors. closeResponse does + // more than just call Close(), so temporarily assign it and reuse the logic. + p.response = response + p.closeResponse() + + // TODO(pomack) log bad response + return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+strconv.Itoa(response.StatusCode)) + } + p.response = response + return nil +} + +func (p *THttpClient) RemainingBytes() (num_bytes uint64) { + len := p.response.ContentLength + if len >= 0 { + return uint64(len) + } + + const maxSize = ^uint64(0) + return maxSize // the thruth is, we just don't know unless framed is used +} + +// Deprecated: Use NewTHttpClientTransportFactory instead. +func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory { + return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{}) +} + +// Deprecated: Use NewTHttpClientTransportFactoryWithOptions instead. +func NewTHttpPostClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { + return NewTHttpClientTransportFactoryWithOptions(url, options) +} + +// Deprecated: Use NewTHttpClientWithOptions instead. +func NewTHttpPostClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { + return NewTHttpClientWithOptions(urlstr, options) +} + +// Deprecated: Use NewTHttpClient instead. +func NewTHttpPostClient(urlstr string) (TTransport, error) { + return NewTHttpClientWithOptions(urlstr, THttpClientOptions{}) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/http_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/http_transport.go new file mode 100644 index 000000000..66f0f388a --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/http_transport.go @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "compress/gzip" + "io" + "net/http" + "strings" +) + +// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function +func NewThriftHandlerFunc(processor TProcessor, + inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { + + return gz(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/x-thrift") + + transport := NewStreamTransport(r.Body, w) + processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) + }) +} + +// gz transparently compresses the HTTP response if the client supports it. +func gz(handler http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { + handler(w, r) + return + } + w.Header().Set("Content-Encoding", "gzip") + gz := gzip.NewWriter(w) + defer gz.Close() + gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w} + handler(gzw, r) + } +} + +type gzipResponseWriter struct { + io.Writer + http.ResponseWriter +} + +func (w gzipResponseWriter) Write(b []byte) (int, error) { + return w.Writer.Write(b) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/iostream_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/iostream_transport.go new file mode 100644 index 000000000..fea93bcef --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/iostream_transport.go @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bufio" + "context" + "io" +) + +// StreamTransport is a Transport made of an io.Reader and/or an io.Writer +type StreamTransport struct { + io.Reader + io.Writer + isReadWriter bool + closed bool +} + +type StreamTransportFactory struct { + Reader io.Reader + Writer io.Writer + isReadWriter bool +} + +func (p *StreamTransportFactory) GetTransport(trans TTransport) (TTransport, error) { + if trans != nil { + t, ok := trans.(*StreamTransport) + if ok { + if t.isReadWriter { + return NewStreamTransportRW(t.Reader.(io.ReadWriter)), nil + } + if t.Reader != nil && t.Writer != nil { + return NewStreamTransport(t.Reader, t.Writer), nil + } + if t.Reader != nil && t.Writer == nil { + return NewStreamTransportR(t.Reader), nil + } + if t.Reader == nil && t.Writer != nil { + return NewStreamTransportW(t.Writer), nil + } + return &StreamTransport{}, nil + } + } + if p.isReadWriter { + return NewStreamTransportRW(p.Reader.(io.ReadWriter)), nil + } + if p.Reader != nil && p.Writer != nil { + return NewStreamTransport(p.Reader, p.Writer), nil + } + if p.Reader != nil && p.Writer == nil { + return NewStreamTransportR(p.Reader), nil + } + if p.Reader == nil && p.Writer != nil { + return NewStreamTransportW(p.Writer), nil + } + return &StreamTransport{}, nil +} + +func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory { + return &StreamTransportFactory{Reader: reader, Writer: writer, isReadWriter: isReadWriter} +} + +func NewStreamTransport(r io.Reader, w io.Writer) *StreamTransport { + return &StreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)} +} + +func NewStreamTransportR(r io.Reader) *StreamTransport { + return &StreamTransport{Reader: bufio.NewReader(r)} +} + +func NewStreamTransportW(w io.Writer) *StreamTransport { + return &StreamTransport{Writer: bufio.NewWriter(w)} +} + +func NewStreamTransportRW(rw io.ReadWriter) *StreamTransport { + bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw)) + return &StreamTransport{Reader: bufrw, Writer: bufrw, isReadWriter: true} +} + +func (p *StreamTransport) IsOpen() bool { + return !p.closed +} + +// implicitly opened on creation, can't be reopened once closed +func (p *StreamTransport) Open() error { + if !p.closed { + return NewTTransportException(ALREADY_OPEN, "StreamTransport already open.") + } else { + return NewTTransportException(NOT_OPEN, "cannot reopen StreamTransport.") + } +} + +// Closes both the input and output streams. +func (p *StreamTransport) Close() error { + if p.closed { + return NewTTransportException(NOT_OPEN, "StreamTransport already closed.") + } + p.closed = true + closedReader := false + if p.Reader != nil { + c, ok := p.Reader.(io.Closer) + if ok { + e := c.Close() + closedReader = true + if e != nil { + return e + } + } + p.Reader = nil + } + if p.Writer != nil && (!closedReader || !p.isReadWriter) { + c, ok := p.Writer.(io.Closer) + if ok { + e := c.Close() + if e != nil { + return e + } + } + p.Writer = nil + } + return nil +} + +// Flushes the underlying output stream if not null. +func (p *StreamTransport) Flush(ctx context.Context) error { + if p.Writer == nil { + return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") + } + f, ok := p.Writer.(Flusher) + if ok { + err := f.Flush() + if err != nil { + return NewTTransportExceptionFromError(err) + } + } + return nil +} + +func (p *StreamTransport) Read(c []byte) (n int, err error) { + n, err = p.Reader.Read(c) + if err != nil { + err = NewTTransportExceptionFromError(err) + } + return +} + +func (p *StreamTransport) ReadByte() (c byte, err error) { + f, ok := p.Reader.(io.ByteReader) + if ok { + c, err = f.ReadByte() + } else { + c, err = readByte(p.Reader) + } + if err != nil { + err = NewTTransportExceptionFromError(err) + } + return +} + +func (p *StreamTransport) Write(c []byte) (n int, err error) { + n, err = p.Writer.Write(c) + if err != nil { + err = NewTTransportExceptionFromError(err) + } + return +} + +func (p *StreamTransport) WriteByte(c byte) (err error) { + f, ok := p.Writer.(io.ByteWriter) + if ok { + err = f.WriteByte(c) + } else { + err = writeByte(p.Writer, c) + } + if err != nil { + err = NewTTransportExceptionFromError(err) + } + return +} + +func (p *StreamTransport) WriteString(s string) (n int, err error) { + f, ok := p.Writer.(stringWriter) + if ok { + n, err = f.WriteString(s) + } else { + n, err = p.Writer.Write([]byte(s)) + } + if err != nil { + err = NewTTransportExceptionFromError(err) + } + return +} + +func (p *StreamTransport) RemainingBytes() (num_bytes uint64) { + const maxSize = ^uint64(0) + return maxSize // the thruth is, we just don't know unless framed is used +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/json_protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/json_protocol.go new file mode 100644 index 000000000..7be685d43 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/json_protocol.go @@ -0,0 +1,584 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "encoding/base64" + "fmt" +) + +const ( + THRIFT_JSON_PROTOCOL_VERSION = 1 +) + +// for references to _ParseContext see tsimplejson_protocol.go + +// JSON protocol implementation for thrift. +// +// This protocol produces/consumes a simple output format +// suitable for parsing by scripting languages. It should not be +// confused with the full-featured TJSONProtocol. +// +type TJSONProtocol struct { + *TSimpleJSONProtocol +} + +// Constructor +func NewTJSONProtocol(t TTransport) *TJSONProtocol { + v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)} + v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) + v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL)) + return v +} + +// Factory +type TJSONProtocolFactory struct{} + +func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { + return NewTJSONProtocol(trans) +} + +func NewTJSONProtocolFactory() *TJSONProtocolFactory { + return &TJSONProtocolFactory{} +} + +func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { + p.resetContextStack() // THRIFT-3735 + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); e != nil { + return e + } + if e := p.WriteString(name); e != nil { + return e + } + if e := p.WriteByte(int8(typeId)); e != nil { + return e + } + if e := p.WriteI32(seqId); e != nil { + return e + } + return nil +} + +func (p *TJSONProtocol) WriteMessageEnd() error { + return p.OutputListEnd() +} + +func (p *TJSONProtocol) WriteStructBegin(name string) error { + if e := p.OutputObjectBegin(); e != nil { + return e + } + return nil +} + +func (p *TJSONProtocol) WriteStructEnd() error { + return p.OutputObjectEnd() +} + +func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + if e := p.WriteI16(id); e != nil { + return e + } + if e := p.OutputObjectBegin(); e != nil { + return e + } + s, e1 := p.TypeIdToString(typeId) + if e1 != nil { + return e1 + } + if e := p.WriteString(s); e != nil { + return e + } + return nil +} + +func (p *TJSONProtocol) WriteFieldEnd() error { + return p.OutputObjectEnd() +} + +func (p *TJSONProtocol) WriteFieldStop() error { return nil } + +func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + s, e1 := p.TypeIdToString(keyType) + if e1 != nil { + return e1 + } + if e := p.WriteString(s); e != nil { + return e + } + s, e1 = p.TypeIdToString(valueType) + if e1 != nil { + return e1 + } + if e := p.WriteString(s); e != nil { + return e + } + if e := p.WriteI64(int64(size)); e != nil { + return e + } + return p.OutputObjectBegin() +} + +func (p *TJSONProtocol) WriteMapEnd() error { + if e := p.OutputObjectEnd(); e != nil { + return e + } + return p.OutputListEnd() +} + +func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error { + return p.OutputElemListBegin(elemType, size) +} + +func (p *TJSONProtocol) WriteListEnd() error { + return p.OutputListEnd() +} + +func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error { + return p.OutputElemListBegin(elemType, size) +} + +func (p *TJSONProtocol) WriteSetEnd() error { + return p.OutputListEnd() +} + +func (p *TJSONProtocol) WriteBool(b bool) error { + if b { + return p.WriteI32(1) + } + return p.WriteI32(0) +} + +func (p *TJSONProtocol) WriteByte(b int8) error { + return p.WriteI32(int32(b)) +} + +func (p *TJSONProtocol) WriteI16(v int16) error { + return p.WriteI32(int32(v)) +} + +func (p *TJSONProtocol) WriteI32(v int32) error { + return p.OutputI64(int64(v)) +} + +func (p *TJSONProtocol) WriteI64(v int64) error { + return p.OutputI64(int64(v)) +} + +func (p *TJSONProtocol) WriteDouble(v float64) error { + return p.OutputF64(v) +} + +func (p *TJSONProtocol) WriteString(v string) error { + return p.OutputString(v) +} + +func (p *TJSONProtocol) WriteBinary(v []byte) error { + // JSON library only takes in a string, + // not an arbitrary byte array, to ensure bytes are transmitted + // efficiently we must convert this into a valid JSON string + // therefore we use base64 encoding to avoid excessive escaping/quoting + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_QUOTE_BYTES); e != nil { + return NewTProtocolException(e) + } + writer := base64.NewEncoder(base64.StdEncoding, p.writer) + if _, e := writer.Write(v); e != nil { + p.writer.Reset(p.trans) // THRIFT-3735 + return NewTProtocolException(e) + } + if e := writer.Close(); e != nil { + return NewTProtocolException(e) + } + if _, e := p.write(JSON_QUOTE_BYTES); e != nil { + return NewTProtocolException(e) + } + return p.OutputPostValue() +} + +// Reading methods. +func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + p.resetContextStack() // THRIFT-3735 + if isNull, err := p.ParseListBegin(); isNull || err != nil { + return name, typeId, seqId, err + } + version, err := p.ReadI32() + if err != nil { + return name, typeId, seqId, err + } + if version != THRIFT_JSON_PROTOCOL_VERSION { + e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION) + return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e) + + } + if name, err = p.ReadString(); err != nil { + return name, typeId, seqId, err + } + bTypeId, err := p.ReadByte() + typeId = TMessageType(bTypeId) + if err != nil { + return name, typeId, seqId, err + } + if seqId, err = p.ReadI32(); err != nil { + return name, typeId, seqId, err + } + return name, typeId, seqId, nil +} + +func (p *TJSONProtocol) ReadMessageEnd() error { + err := p.ParseListEnd() + return err +} + +func (p *TJSONProtocol) ReadStructBegin() (name string, err error) { + _, err = p.ParseObjectStart() + return "", err +} + +func (p *TJSONProtocol) ReadStructEnd() error { + return p.ParseObjectEnd() +} + +func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) { + b, _ := p.reader.Peek(1) + if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] { + return "", STOP, -1, nil + } + fieldId, err := p.ReadI16() + if err != nil { + return "", STOP, fieldId, err + } + if _, err = p.ParseObjectStart(); err != nil { + return "", STOP, fieldId, err + } + sType, err := p.ReadString() + if err != nil { + return "", STOP, fieldId, err + } + fType, err := p.StringToTypeId(sType) + return "", fType, fieldId, err +} + +func (p *TJSONProtocol) ReadFieldEnd() error { + return p.ParseObjectEnd() +} + +func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, VOID, 0, e + } + + // read keyType + sKeyType, e := p.ReadString() + if e != nil { + return keyType, valueType, size, e + } + keyType, e = p.StringToTypeId(sKeyType) + if e != nil { + return keyType, valueType, size, e + } + + // read valueType + sValueType, e := p.ReadString() + if e != nil { + return keyType, valueType, size, e + } + valueType, e = p.StringToTypeId(sValueType) + if e != nil { + return keyType, valueType, size, e + } + + // read size + iSize, e := p.ReadI64() + if e != nil { + return keyType, valueType, size, e + } + size = int(iSize) + + _, e = p.ParseObjectStart() + return keyType, valueType, size, e +} + +func (p *TJSONProtocol) ReadMapEnd() error { + e := p.ParseObjectEnd() + if e != nil { + return e + } + return p.ParseListEnd() +} + +func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) { + return p.ParseElemListBegin() +} + +func (p *TJSONProtocol) ReadListEnd() error { + return p.ParseListEnd() +} + +func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) { + return p.ParseElemListBegin() +} + +func (p *TJSONProtocol) ReadSetEnd() error { + return p.ParseListEnd() +} + +func (p *TJSONProtocol) ReadBool() (bool, error) { + value, err := p.ReadI32() + return (value != 0), err +} + +func (p *TJSONProtocol) ReadByte() (int8, error) { + v, err := p.ReadI64() + return int8(v), err +} + +func (p *TJSONProtocol) ReadI16() (int16, error) { + v, err := p.ReadI64() + return int16(v), err +} + +func (p *TJSONProtocol) ReadI32() (int32, error) { + v, err := p.ReadI64() + return int32(v), err +} + +func (p *TJSONProtocol) ReadI64() (int64, error) { + v, _, err := p.ParseI64() + return v, err +} + +func (p *TJSONProtocol) ReadDouble() (float64, error) { + v, _, err := p.ParseF64() + return v, err +} + +func (p *TJSONProtocol) ReadString() (string, error) { + var v string + if err := p.ParsePreValue(); err != nil { + return v, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 && f[0] == JSON_QUOTE { + p.reader.ReadByte() + value, err := p.ParseStringBody() + v = value + if err != nil { + return v, err + } + } else if len(f) > 0 && f[0] == JSON_NULL[0] { + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return v, NewTProtocolException(err) + } + if string(b) != string(JSON_NULL) { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } else { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return v, p.ParsePostValue() +} + +func (p *TJSONProtocol) ReadBinary() ([]byte, error) { + var v []byte + if err := p.ParsePreValue(); err != nil { + return nil, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 && f[0] == JSON_QUOTE { + p.reader.ReadByte() + value, err := p.ParseBase64EncodedBody() + v = value + if err != nil { + return v, err + } + } else if len(f) > 0 && f[0] == JSON_NULL[0] { + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return v, NewTProtocolException(err) + } + if string(b) != string(JSON_NULL) { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } else { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + + return v, p.ParsePostValue() +} + +func (p *TJSONProtocol) Flush(ctx context.Context) (err error) { + err = p.writer.Flush() + if err == nil { + err = p.trans.Flush(ctx) + } + return NewTProtocolException(err) +} + +func (p *TJSONProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TJSONProtocol) Transport() TTransport { + return p.trans +} + +func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + s, e1 := p.TypeIdToString(elemType) + if e1 != nil { + return e1 + } + if e := p.WriteString(s); e != nil { + return e + } + if e := p.WriteI64(int64(size)); e != nil { + return e + } + return nil +} + +func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, 0, e + } + sElemType, err := p.ReadString() + if err != nil { + return VOID, size, err + } + elemType, err = p.StringToTypeId(sElemType) + if err != nil { + return elemType, size, err + } + nSize, err2 := p.ReadI64() + size = int(nSize) + return elemType, size, err2 +} + +func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, 0, e + } + sElemType, err := p.ReadString() + if err != nil { + return VOID, size, err + } + elemType, err = p.StringToTypeId(sElemType) + if err != nil { + return elemType, size, err + } + nSize, err2 := p.ReadI64() + size = int(nSize) + return elemType, size, err2 +} + +func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + s, e1 := p.TypeIdToString(elemType) + if e1 != nil { + return e1 + } + if e := p.OutputString(s); e != nil { + return e + } + if e := p.OutputI64(int64(size)); e != nil { + return e + } + return nil +} + +func (p *TJSONProtocol) TypeIdToString(fieldType TType) (string, error) { + switch byte(fieldType) { + case BOOL: + return "tf", nil + case BYTE: + return "i8", nil + case I16: + return "i16", nil + case I32: + return "i32", nil + case I64: + return "i64", nil + case DOUBLE: + return "dbl", nil + case STRING: + return "str", nil + case STRUCT: + return "rec", nil + case MAP: + return "map", nil + case SET: + return "set", nil + case LIST: + return "lst", nil + } + + e := fmt.Errorf("Unknown fieldType: %d", int(fieldType)) + return "", NewTProtocolExceptionWithType(INVALID_DATA, e) +} + +func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) { + switch fieldType { + case "tf": + return TType(BOOL), nil + case "i8": + return TType(BYTE), nil + case "i16": + return TType(I16), nil + case "i32": + return TType(I32), nil + case "i64": + return TType(I64), nil + case "dbl": + return TType(DOUBLE), nil + case "str": + return TType(STRING), nil + case "rec": + return TType(STRUCT), nil + case "map": + return TType(MAP), nil + case "set": + return TType(SET), nil + case "lst": + return TType(LIST), nil + } + + e := fmt.Errorf("Unknown type identifier: %s", fieldType) + return TType(STOP), NewTProtocolExceptionWithType(INVALID_DATA, e) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/memory_buffer.go b/vendor/github.com/apache/thrift/lib/go/thrift/memory_buffer.go new file mode 100644 index 000000000..5936d2730 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/memory_buffer.go @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bytes" + "context" +) + +// Memory buffer-based implementation of the TTransport interface. +type TMemoryBuffer struct { + *bytes.Buffer + size int +} + +type TMemoryBufferTransportFactory struct { + size int +} + +func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) (TTransport, error) { + if trans != nil { + t, ok := trans.(*TMemoryBuffer) + if ok && t.size > 0 { + return NewTMemoryBufferLen(t.size), nil + } + } + return NewTMemoryBufferLen(p.size), nil +} + +func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory { + return &TMemoryBufferTransportFactory{size: size} +} + +func NewTMemoryBuffer() *TMemoryBuffer { + return &TMemoryBuffer{Buffer: &bytes.Buffer{}, size: 0} +} + +func NewTMemoryBufferLen(size int) *TMemoryBuffer { + buf := make([]byte, 0, size) + return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size} +} + +func (p *TMemoryBuffer) IsOpen() bool { + return true +} + +func (p *TMemoryBuffer) Open() error { + return nil +} + +func (p *TMemoryBuffer) Close() error { + p.Buffer.Reset() + return nil +} + +// Flushing a memory buffer is a no-op +func (p *TMemoryBuffer) Flush(ctx context.Context) error { + return nil +} + +func (p *TMemoryBuffer) RemainingBytes() (num_bytes uint64) { + return uint64(p.Buffer.Len()) +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/messagetype.go b/vendor/github.com/apache/thrift/lib/go/thrift/messagetype.go new file mode 100644 index 000000000..25ab2e98a --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/messagetype.go @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Message type constants in the Thrift protocol. +type TMessageType int32 + +const ( + INVALID_TMESSAGE_TYPE TMessageType = 0 + CALL TMessageType = 1 + REPLY TMessageType = 2 + EXCEPTION TMessageType = 3 + ONEWAY TMessageType = 4 +) diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/multiplexed_protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/multiplexed_protocol.go new file mode 100644 index 000000000..d028a30b3 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/multiplexed_protocol.go @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "fmt" + "strings" +) + +/* +TMultiplexedProtocol is a protocol-independent concrete decorator +that allows a Thrift client to communicate with a multiplexing Thrift server, +by prepending the service name to the function name during function calls. + +NOTE: THIS IS NOT USED BY SERVERS. On the server, use TMultiplexedProcessor to handle request +from a multiplexing client. + +This example uses a single socket transport to invoke two services: + +socket := thrift.NewTSocketFromAddrTimeout(addr, TIMEOUT) +transport := thrift.NewTFramedTransport(socket) +protocol := thrift.NewTBinaryProtocolTransport(transport) + +mp := thrift.NewTMultiplexedProtocol(protocol, "Calculator") +service := Calculator.NewCalculatorClient(mp) + +mp2 := thrift.NewTMultiplexedProtocol(protocol, "WeatherReport") +service2 := WeatherReport.NewWeatherReportClient(mp2) + +err := transport.Open() +if err != nil { + t.Fatal("Unable to open client socket", err) +} + +fmt.Println(service.Add(2,2)) +fmt.Println(service2.GetTemperature()) +*/ + +type TMultiplexedProtocol struct { + TProtocol + serviceName string +} + +const MULTIPLEXED_SEPARATOR = ":" + +func NewTMultiplexedProtocol(protocol TProtocol, serviceName string) *TMultiplexedProtocol { + return &TMultiplexedProtocol{ + TProtocol: protocol, + serviceName: serviceName, + } +} + +func (t *TMultiplexedProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) error { + if typeId == CALL || typeId == ONEWAY { + return t.TProtocol.WriteMessageBegin(t.serviceName+MULTIPLEXED_SEPARATOR+name, typeId, seqid) + } else { + return t.TProtocol.WriteMessageBegin(name, typeId, seqid) + } +} + +/* +TMultiplexedProcessor is a TProcessor allowing +a single TServer to provide multiple services. + +To do so, you instantiate the processor and then register additional +processors with it, as shown in the following example: + +var processor = thrift.NewTMultiplexedProcessor() + +firstProcessor := +processor.RegisterProcessor("FirstService", firstProcessor) + +processor.registerProcessor( + "Calculator", + Calculator.NewCalculatorProcessor(&CalculatorHandler{}), +) + +processor.registerProcessor( + "WeatherReport", + WeatherReport.NewWeatherReportProcessor(&WeatherReportHandler{}), +) + +serverTransport, err := thrift.NewTServerSocketTimeout(addr, TIMEOUT) +if err != nil { + t.Fatal("Unable to create server socket", err) +} +server := thrift.NewTSimpleServer2(processor, serverTransport) +server.Serve(); +*/ + +type TMultiplexedProcessor struct { + serviceProcessorMap map[string]TProcessor + DefaultProcessor TProcessor +} + +func NewTMultiplexedProcessor() *TMultiplexedProcessor { + return &TMultiplexedProcessor{ + serviceProcessorMap: make(map[string]TProcessor), + } +} + +func (t *TMultiplexedProcessor) RegisterDefault(processor TProcessor) { + t.DefaultProcessor = processor +} + +func (t *TMultiplexedProcessor) RegisterProcessor(name string, processor TProcessor) { + if t.serviceProcessorMap == nil { + t.serviceProcessorMap = make(map[string]TProcessor) + } + t.serviceProcessorMap[name] = processor +} + +func (t *TMultiplexedProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { + name, typeId, seqid, err := in.ReadMessageBegin() + if err != nil { + return false, err + } + if typeId != CALL && typeId != ONEWAY { + return false, fmt.Errorf("Unexpected message type %v", typeId) + } + //extract the service name + v := strings.SplitN(name, MULTIPLEXED_SEPARATOR, 2) + if len(v) != 2 { + if t.DefaultProcessor != nil { + smb := NewStoredMessageProtocol(in, name, typeId, seqid) + return t.DefaultProcessor.Process(ctx, smb, out) + } + return false, fmt.Errorf("Service name not found in message name: %s. Did you forget to use a TMultiplexProtocol in your client?", name) + } + actualProcessor, ok := t.serviceProcessorMap[v[0]] + if !ok { + return false, fmt.Errorf("Service name not found: %s. Did you forget to call registerProcessor()?", v[0]) + } + smb := NewStoredMessageProtocol(in, v[1], typeId, seqid) + return actualProcessor.Process(ctx, smb, out) +} + +//Protocol that use stored message for ReadMessageBegin +type storedMessageProtocol struct { + TProtocol + name string + typeId TMessageType + seqid int32 +} + +func NewStoredMessageProtocol(protocol TProtocol, name string, typeId TMessageType, seqid int32) *storedMessageProtocol { + return &storedMessageProtocol{protocol, name, typeId, seqid} +} + +func (s *storedMessageProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err error) { + return s.name, s.typeId, s.seqid, nil +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/numeric.go b/vendor/github.com/apache/thrift/lib/go/thrift/numeric.go new file mode 100644 index 000000000..aa8daa9b5 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/numeric.go @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "math" + "strconv" +) + +type Numeric interface { + Int64() int64 + Int32() int32 + Int16() int16 + Byte() byte + Int() int + Float64() float64 + Float32() float32 + String() string + isNull() bool +} + +type numeric struct { + iValue int64 + dValue float64 + sValue string + isNil bool +} + +var ( + INFINITY Numeric + NEGATIVE_INFINITY Numeric + NAN Numeric + ZERO Numeric + NUMERIC_NULL Numeric +) + +func NewNumericFromDouble(dValue float64) Numeric { + if math.IsInf(dValue, 1) { + return INFINITY + } + if math.IsInf(dValue, -1) { + return NEGATIVE_INFINITY + } + if math.IsNaN(dValue) { + return NAN + } + iValue := int64(dValue) + sValue := strconv.FormatFloat(dValue, 'g', 10, 64) + isNil := false + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromI64(iValue int64) Numeric { + dValue := float64(iValue) + sValue := string(iValue) + isNil := false + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromI32(iValue int32) Numeric { + dValue := float64(iValue) + sValue := string(iValue) + isNil := false + return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromString(sValue string) Numeric { + if sValue == INFINITY.String() { + return INFINITY + } + if sValue == NEGATIVE_INFINITY.String() { + return NEGATIVE_INFINITY + } + if sValue == NAN.String() { + return NAN + } + iValue, _ := strconv.ParseInt(sValue, 10, 64) + dValue, _ := strconv.ParseFloat(sValue, 64) + isNil := len(sValue) == 0 + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromJSONString(sValue string, isNull bool) Numeric { + if isNull { + return NewNullNumeric() + } + if sValue == JSON_INFINITY { + return INFINITY + } + if sValue == JSON_NEGATIVE_INFINITY { + return NEGATIVE_INFINITY + } + if sValue == JSON_NAN { + return NAN + } + iValue, _ := strconv.ParseInt(sValue, 10, 64) + dValue, _ := strconv.ParseFloat(sValue, 64) + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull} +} + +func NewNullNumeric() Numeric { + return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true} +} + +func (p *numeric) Int64() int64 { + return p.iValue +} + +func (p *numeric) Int32() int32 { + return int32(p.iValue) +} + +func (p *numeric) Int16() int16 { + return int16(p.iValue) +} + +func (p *numeric) Byte() byte { + return byte(p.iValue) +} + +func (p *numeric) Int() int { + return int(p.iValue) +} + +func (p *numeric) Float64() float64 { + return p.dValue +} + +func (p *numeric) Float32() float32 { + return float32(p.dValue) +} + +func (p *numeric) String() string { + return p.sValue +} + +func (p *numeric) isNull() bool { + return p.isNil +} + +func init() { + INFINITY = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false} + NEGATIVE_INFINITY = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false} + NAN = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false} + ZERO = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false} + NUMERIC_NULL = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true} +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/pointerize.go b/vendor/github.com/apache/thrift/lib/go/thrift/pointerize.go new file mode 100644 index 000000000..8d6b2c215 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/pointerize.go @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +/////////////////////////////////////////////////////////////////////////////// +// This file is home to helpers that convert from various base types to +// respective pointer types. This is necessary because Go does not permit +// references to constants, nor can a pointer type to base type be allocated +// and initialized in a single expression. +// +// E.g., this is not allowed: +// +// var ip *int = &5 +// +// But this *is* allowed: +// +// func IntPtr(i int) *int { return &i } +// var ip *int = IntPtr(5) +// +// Since pointers to base types are commonplace as [optional] fields in +// exported thrift structs, we factor such helpers here. +/////////////////////////////////////////////////////////////////////////////// + +func Float32Ptr(v float32) *float32 { return &v } +func Float64Ptr(v float64) *float64 { return &v } +func IntPtr(v int) *int { return &v } +func Int32Ptr(v int32) *int32 { return &v } +func Int64Ptr(v int64) *int64 { return &v } +func StringPtr(v string) *string { return &v } +func Uint32Ptr(v uint32) *uint32 { return &v } +func Uint64Ptr(v uint64) *uint64 { return &v } +func BoolPtr(v bool) *bool { return &v } +func ByteSlicePtr(v []byte) *[]byte { return &v } diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/processor_factory.go b/vendor/github.com/apache/thrift/lib/go/thrift/processor_factory.go new file mode 100644 index 000000000..e4b132b30 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/processor_factory.go @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import "context" + +// A processor is a generic object which operates upon an input stream and +// writes to some output stream. +type TProcessor interface { + Process(ctx context.Context, in, out TProtocol) (bool, TException) +} + +type TProcessorFunction interface { + Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) +} + +// The default processor factory just returns a singleton +// instance. +type TProcessorFactory interface { + GetProcessor(trans TTransport) TProcessor +} + +type tProcessorFactory struct { + processor TProcessor +} + +func NewTProcessorFactory(p TProcessor) TProcessorFactory { + return &tProcessorFactory{processor: p} +} + +func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor { + return p.processor +} + +/** + * The default processor factory just returns a singleton + * instance. + */ +type TProcessorFunctionFactory interface { + GetProcessorFunction(trans TTransport) TProcessorFunction +} + +type tProcessorFunctionFactory struct { + processor TProcessorFunction +} + +func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory { + return &tProcessorFunctionFactory{processor: p} +} + +func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction { + return p.processor +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/protocol.go new file mode 100644 index 000000000..615b7a4a8 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/protocol.go @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "errors" + "fmt" +) + +const ( + VERSION_MASK = 0xffff0000 + VERSION_1 = 0x80010000 +) + +type TProtocol interface { + WriteMessageBegin(name string, typeId TMessageType, seqid int32) error + WriteMessageEnd() error + WriteStructBegin(name string) error + WriteStructEnd() error + WriteFieldBegin(name string, typeId TType, id int16) error + WriteFieldEnd() error + WriteFieldStop() error + WriteMapBegin(keyType TType, valueType TType, size int) error + WriteMapEnd() error + WriteListBegin(elemType TType, size int) error + WriteListEnd() error + WriteSetBegin(elemType TType, size int) error + WriteSetEnd() error + WriteBool(value bool) error + WriteByte(value int8) error + WriteI16(value int16) error + WriteI32(value int32) error + WriteI64(value int64) error + WriteDouble(value float64) error + WriteString(value string) error + WriteBinary(value []byte) error + + ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err error) + ReadMessageEnd() error + ReadStructBegin() (name string, err error) + ReadStructEnd() error + ReadFieldBegin() (name string, typeId TType, id int16, err error) + ReadFieldEnd() error + ReadMapBegin() (keyType TType, valueType TType, size int, err error) + ReadMapEnd() error + ReadListBegin() (elemType TType, size int, err error) + ReadListEnd() error + ReadSetBegin() (elemType TType, size int, err error) + ReadSetEnd() error + ReadBool() (value bool, err error) + ReadByte() (value int8, err error) + ReadI16() (value int16, err error) + ReadI32() (value int32, err error) + ReadI64() (value int64, err error) + ReadDouble() (value float64, err error) + ReadString() (value string, err error) + ReadBinary() (value []byte, err error) + + Skip(fieldType TType) (err error) + Flush(ctx context.Context) (err error) + + Transport() TTransport +} + +// The maximum recursive depth the skip() function will traverse +const DEFAULT_RECURSION_DEPTH = 64 + +// Skips over the next data element from the provided input TProtocol object. +func SkipDefaultDepth(prot TProtocol, typeId TType) (err error) { + return Skip(prot, typeId, DEFAULT_RECURSION_DEPTH) +} + +// Skips over the next data element from the provided input TProtocol object. +func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) { + + if maxDepth <= 0 { + return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded")) + } + + switch fieldType { + case STOP: + return + case BOOL: + _, err = self.ReadBool() + return + case BYTE: + _, err = self.ReadByte() + return + case I16: + _, err = self.ReadI16() + return + case I32: + _, err = self.ReadI32() + return + case I64: + _, err = self.ReadI64() + return + case DOUBLE: + _, err = self.ReadDouble() + return + case STRING: + _, err = self.ReadString() + return + case STRUCT: + if _, err = self.ReadStructBegin(); err != nil { + return err + } + for { + _, typeId, _, _ := self.ReadFieldBegin() + if typeId == STOP { + break + } + err := Skip(self, typeId, maxDepth-1) + if err != nil { + return err + } + self.ReadFieldEnd() + } + return self.ReadStructEnd() + case MAP: + keyType, valueType, size, err := self.ReadMapBegin() + if err != nil { + return err + } + for i := 0; i < size; i++ { + err := Skip(self, keyType, maxDepth-1) + if err != nil { + return err + } + self.Skip(valueType) + } + return self.ReadMapEnd() + case SET: + elemType, size, err := self.ReadSetBegin() + if err != nil { + return err + } + for i := 0; i < size; i++ { + err := Skip(self, elemType, maxDepth-1) + if err != nil { + return err + } + } + return self.ReadSetEnd() + case LIST: + elemType, size, err := self.ReadListBegin() + if err != nil { + return err + } + for i := 0; i < size; i++ { + err := Skip(self, elemType, maxDepth-1) + if err != nil { + return err + } + } + return self.ReadListEnd() + default: + return NewTProtocolExceptionWithType(INVALID_DATA, errors.New(fmt.Sprintf("Unknown data type %d", fieldType))) + } + return nil +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/protocol_exception.go b/vendor/github.com/apache/thrift/lib/go/thrift/protocol_exception.go new file mode 100644 index 000000000..29ab75d92 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/protocol_exception.go @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "encoding/base64" +) + +// Thrift Protocol exception +type TProtocolException interface { + TException + TypeId() int +} + +const ( + UNKNOWN_PROTOCOL_EXCEPTION = 0 + INVALID_DATA = 1 + NEGATIVE_SIZE = 2 + SIZE_LIMIT = 3 + BAD_VERSION = 4 + NOT_IMPLEMENTED = 5 + DEPTH_LIMIT = 6 +) + +type tProtocolException struct { + typeId int + message string +} + +func (p *tProtocolException) TypeId() int { + return p.typeId +} + +func (p *tProtocolException) String() string { + return p.message +} + +func (p *tProtocolException) Error() string { + return p.message +} + +func NewTProtocolException(err error) TProtocolException { + if err == nil { + return nil + } + if e, ok := err.(TProtocolException); ok { + return e + } + if _, ok := err.(base64.CorruptInputError); ok { + return &tProtocolException{INVALID_DATA, err.Error()} + } + return &tProtocolException{UNKNOWN_PROTOCOL_EXCEPTION, err.Error()} +} + +func NewTProtocolExceptionWithType(errType int, err error) TProtocolException { + if err == nil { + return nil + } + return &tProtocolException{errType, err.Error()} +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/protocol_factory.go b/vendor/github.com/apache/thrift/lib/go/thrift/protocol_factory.go new file mode 100644 index 000000000..c40f796d8 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/protocol_factory.go @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Factory interface for constructing protocol instances. +type TProtocolFactory interface { + GetProtocol(trans TTransport) TProtocol +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/rich_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/rich_transport.go new file mode 100644 index 000000000..4025bebea --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/rich_transport.go @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import "io" + +type RichTransport struct { + TTransport +} + +// Wraps Transport to provide TRichTransport interface +func NewTRichTransport(trans TTransport) *RichTransport { + return &RichTransport{trans} +} + +func (r *RichTransport) ReadByte() (c byte, err error) { + return readByte(r.TTransport) +} + +func (r *RichTransport) WriteByte(c byte) error { + return writeByte(r.TTransport, c) +} + +func (r *RichTransport) WriteString(s string) (n int, err error) { + return r.Write([]byte(s)) +} + +func (r *RichTransport) RemainingBytes() (num_bytes uint64) { + return r.TTransport.RemainingBytes() +} + +func readByte(r io.Reader) (c byte, err error) { + v := [1]byte{0} + n, err := r.Read(v[0:1]) + if n > 0 && (err == nil || err == io.EOF) { + return v[0], nil + } + if n > 0 && err != nil { + return v[0], err + } + if err != nil { + return 0, err + } + return v[0], nil +} + +func writeByte(w io.Writer, c byte) error { + v := [1]byte{c} + _, err := w.Write(v[0:1]) + return err +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/serializer.go b/vendor/github.com/apache/thrift/lib/go/thrift/serializer.go new file mode 100644 index 000000000..1ff4d3754 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/serializer.go @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" +) + +type TSerializer struct { + Transport *TMemoryBuffer + Protocol TProtocol +} + +type TStruct interface { + Write(p TProtocol) error + Read(p TProtocol) error +} + +func NewTSerializer() *TSerializer { + transport := NewTMemoryBufferLen(1024) + protocol := NewTBinaryProtocolFactoryDefault().GetProtocol(transport) + + return &TSerializer{ + transport, + protocol} +} + +func (t *TSerializer) WriteString(ctx context.Context, msg TStruct) (s string, err error) { + t.Transport.Reset() + + if err = msg.Write(t.Protocol); err != nil { + return + } + + if err = t.Protocol.Flush(ctx); err != nil { + return + } + if err = t.Transport.Flush(ctx); err != nil { + return + } + + return t.Transport.String(), nil +} + +func (t *TSerializer) Write(ctx context.Context, msg TStruct) (b []byte, err error) { + t.Transport.Reset() + + if err = msg.Write(t.Protocol); err != nil { + return + } + + if err = t.Protocol.Flush(ctx); err != nil { + return + } + + if err = t.Transport.Flush(ctx); err != nil { + return + } + + b = append(b, t.Transport.Bytes()...) + return +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/server.go b/vendor/github.com/apache/thrift/lib/go/thrift/server.go new file mode 100644 index 000000000..f813fa353 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/server.go @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +type TServer interface { + ProcessorFactory() TProcessorFactory + ServerTransport() TServerTransport + InputTransportFactory() TTransportFactory + OutputTransportFactory() TTransportFactory + InputProtocolFactory() TProtocolFactory + OutputProtocolFactory() TProtocolFactory + + // Starts the server + Serve() error + // Stops the server. This is optional on a per-implementation basis. Not + // all servers are required to be cleanly stoppable. + Stop() error +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/server_socket.go b/vendor/github.com/apache/thrift/lib/go/thrift/server_socket.go new file mode 100644 index 000000000..80313c4be --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/server_socket.go @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "net" + "sync" + "time" +) + +type TServerSocket struct { + listener net.Listener + addr net.Addr + clientTimeout time.Duration + + // Protects the interrupted value to make it thread safe. + mu sync.RWMutex + interrupted bool +} + +func NewTServerSocket(listenAddr string) (*TServerSocket, error) { + return NewTServerSocketTimeout(listenAddr, 0) +} + +func NewTServerSocketTimeout(listenAddr string, clientTimeout time.Duration) (*TServerSocket, error) { + addr, err := net.ResolveTCPAddr("tcp", listenAddr) + if err != nil { + return nil, err + } + return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil +} + +// Creates a TServerSocket from a net.Addr +func NewTServerSocketFromAddrTimeout(addr net.Addr, clientTimeout time.Duration) *TServerSocket { + return &TServerSocket{addr: addr, clientTimeout: clientTimeout} +} + +func (p *TServerSocket) Listen() error { + p.mu.Lock() + defer p.mu.Unlock() + if p.IsListening() { + return nil + } + l, err := net.Listen(p.addr.Network(), p.addr.String()) + if err != nil { + return err + } + p.listener = l + return nil +} + +func (p *TServerSocket) Accept() (TTransport, error) { + p.mu.RLock() + interrupted := p.interrupted + p.mu.RUnlock() + + if interrupted { + return nil, errTransportInterrupted + } + + listener := p.listener + if listener == nil { + return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") + } + + conn, err := listener.Accept() + if err != nil { + return nil, NewTTransportExceptionFromError(err) + } + return NewTSocketFromConnTimeout(conn, p.clientTimeout), nil +} + +// Checks whether the socket is listening. +func (p *TServerSocket) IsListening() bool { + return p.listener != nil +} + +// Connects the socket, creating a new socket object if necessary. +func (p *TServerSocket) Open() error { + p.mu.Lock() + defer p.mu.Unlock() + if p.IsListening() { + return NewTTransportException(ALREADY_OPEN, "Server socket already open") + } + if l, err := net.Listen(p.addr.Network(), p.addr.String()); err != nil { + return err + } else { + p.listener = l + } + return nil +} + +func (p *TServerSocket) Addr() net.Addr { + if p.listener != nil { + return p.listener.Addr() + } + return p.addr +} + +func (p *TServerSocket) Close() error { + defer func() { + p.listener = nil + }() + if p.IsListening() { + return p.listener.Close() + } + return nil +} + +func (p *TServerSocket) Interrupt() error { + p.mu.Lock() + defer p.mu.Unlock() + p.interrupted = true + p.Close() + + return nil +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/server_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/server_transport.go new file mode 100644 index 000000000..51c40b64a --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/server_transport.go @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Server transport. Object which provides client transports. +type TServerTransport interface { + Listen() error + Accept() (TTransport, error) + Close() error + + // Optional method implementation. This signals to the server transport + // that it should break out of any accept() or listen() that it is currently + // blocked on. This method, if implemented, MUST be thread safe, as it may + // be called from a different thread context than the other TServerTransport + // methods. + Interrupt() error +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/simple_json_protocol.go b/vendor/github.com/apache/thrift/lib/go/thrift/simple_json_protocol.go new file mode 100644 index 000000000..2e8a71112 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/simple_json_protocol.go @@ -0,0 +1,1338 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bufio" + "bytes" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "math" + "strconv" +) + +type _ParseContext int + +const ( + _CONTEXT_IN_TOPLEVEL _ParseContext = 1 + _CONTEXT_IN_LIST_FIRST _ParseContext = 2 + _CONTEXT_IN_LIST _ParseContext = 3 + _CONTEXT_IN_OBJECT_FIRST _ParseContext = 4 + _CONTEXT_IN_OBJECT_NEXT_KEY _ParseContext = 5 + _CONTEXT_IN_OBJECT_NEXT_VALUE _ParseContext = 6 +) + +func (p _ParseContext) String() string { + switch p { + case _CONTEXT_IN_TOPLEVEL: + return "TOPLEVEL" + case _CONTEXT_IN_LIST_FIRST: + return "LIST-FIRST" + case _CONTEXT_IN_LIST: + return "LIST" + case _CONTEXT_IN_OBJECT_FIRST: + return "OBJECT-FIRST" + case _CONTEXT_IN_OBJECT_NEXT_KEY: + return "OBJECT-NEXT-KEY" + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + return "OBJECT-NEXT-VALUE" + } + return "UNKNOWN-PARSE-CONTEXT" +} + +// JSON protocol implementation for thrift. +// +// This protocol produces/consumes a simple output format +// suitable for parsing by scripting languages. It should not be +// confused with the full-featured TJSONProtocol. +// +type TSimpleJSONProtocol struct { + trans TTransport + + parseContextStack []int + dumpContext []int + + writer *bufio.Writer + reader *bufio.Reader +} + +// Constructor +func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol { + v := &TSimpleJSONProtocol{trans: t, + writer: bufio.NewWriter(t), + reader: bufio.NewReader(t), + } + v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) + v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL)) + return v +} + +// Factory +type TSimpleJSONProtocolFactory struct{} + +func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { + return NewTSimpleJSONProtocol(trans) +} + +func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory { + return &TSimpleJSONProtocolFactory{} +} + +var ( + JSON_COMMA []byte + JSON_COLON []byte + JSON_LBRACE []byte + JSON_RBRACE []byte + JSON_LBRACKET []byte + JSON_RBRACKET []byte + JSON_QUOTE byte + JSON_QUOTE_BYTES []byte + JSON_NULL []byte + JSON_TRUE []byte + JSON_FALSE []byte + JSON_INFINITY string + JSON_NEGATIVE_INFINITY string + JSON_NAN string + JSON_INFINITY_BYTES []byte + JSON_NEGATIVE_INFINITY_BYTES []byte + JSON_NAN_BYTES []byte + json_nonbase_map_elem_bytes []byte +) + +func init() { + JSON_COMMA = []byte{','} + JSON_COLON = []byte{':'} + JSON_LBRACE = []byte{'{'} + JSON_RBRACE = []byte{'}'} + JSON_LBRACKET = []byte{'['} + JSON_RBRACKET = []byte{']'} + JSON_QUOTE = '"' + JSON_QUOTE_BYTES = []byte{'"'} + JSON_NULL = []byte{'n', 'u', 'l', 'l'} + JSON_TRUE = []byte{'t', 'r', 'u', 'e'} + JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'} + JSON_INFINITY = "Infinity" + JSON_NEGATIVE_INFINITY = "-Infinity" + JSON_NAN = "NaN" + JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'} + JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'} + JSON_NAN_BYTES = []byte{'N', 'a', 'N'} + json_nonbase_map_elem_bytes = []byte{']', ',', '['} +} + +func jsonQuote(s string) string { + b, _ := json.Marshal(s) + s1 := string(b) + return s1 +} + +func jsonUnquote(s string) (string, bool) { + s1 := new(string) + err := json.Unmarshal([]byte(s), s1) + return *s1, err == nil +} + +func mismatch(expected, actual string) error { + return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual) +} + +func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { + p.resetContextStack() // THRIFT-3735 + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteString(name); e != nil { + return e + } + if e := p.WriteByte(int8(typeId)); e != nil { + return e + } + if e := p.WriteI32(seqId); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) WriteMessageEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteStructBegin(name string) error { + if e := p.OutputObjectBegin(); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) WriteStructEnd() error { + return p.OutputObjectEnd() +} + +func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + if e := p.WriteString(name); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) WriteFieldEnd() error { + //return p.OutputListEnd() + return nil +} + +func (p *TSimpleJSONProtocol) WriteFieldStop() error { return nil } + +func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteByte(int8(keyType)); e != nil { + return e + } + if e := p.WriteByte(int8(valueType)); e != nil { + return e + } + return p.WriteI32(int32(size)) +} + +func (p *TSimpleJSONProtocol) WriteMapEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) error { + return p.OutputElemListBegin(elemType, size) +} + +func (p *TSimpleJSONProtocol) WriteListEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) error { + return p.OutputElemListBegin(elemType, size) +} + +func (p *TSimpleJSONProtocol) WriteSetEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteBool(b bool) error { + return p.OutputBool(b) +} + +func (p *TSimpleJSONProtocol) WriteByte(b int8) error { + return p.WriteI32(int32(b)) +} + +func (p *TSimpleJSONProtocol) WriteI16(v int16) error { + return p.WriteI32(int32(v)) +} + +func (p *TSimpleJSONProtocol) WriteI32(v int32) error { + return p.OutputI64(int64(v)) +} + +func (p *TSimpleJSONProtocol) WriteI64(v int64) error { + return p.OutputI64(int64(v)) +} + +func (p *TSimpleJSONProtocol) WriteDouble(v float64) error { + return p.OutputF64(v) +} + +func (p *TSimpleJSONProtocol) WriteString(v string) error { + return p.OutputString(v) +} + +func (p *TSimpleJSONProtocol) WriteBinary(v []byte) error { + // JSON library only takes in a string, + // not an arbitrary byte array, to ensure bytes are transmitted + // efficiently we must convert this into a valid JSON string + // therefore we use base64 encoding to avoid excessive escaping/quoting + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_QUOTE_BYTES); e != nil { + return NewTProtocolException(e) + } + writer := base64.NewEncoder(base64.StdEncoding, p.writer) + if _, e := writer.Write(v); e != nil { + p.writer.Reset(p.trans) // THRIFT-3735 + return NewTProtocolException(e) + } + if e := writer.Close(); e != nil { + return NewTProtocolException(e) + } + if _, e := p.write(JSON_QUOTE_BYTES); e != nil { + return NewTProtocolException(e) + } + return p.OutputPostValue() +} + +// Reading methods. +func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + p.resetContextStack() // THRIFT-3735 + if isNull, err := p.ParseListBegin(); isNull || err != nil { + return name, typeId, seqId, err + } + if name, err = p.ReadString(); err != nil { + return name, typeId, seqId, err + } + bTypeId, err := p.ReadByte() + typeId = TMessageType(bTypeId) + if err != nil { + return name, typeId, seqId, err + } + if seqId, err = p.ReadI32(); err != nil { + return name, typeId, seqId, err + } + return name, typeId, seqId, nil +} + +func (p *TSimpleJSONProtocol) ReadMessageEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err error) { + _, err = p.ParseObjectStart() + return "", err +} + +func (p *TSimpleJSONProtocol) ReadStructEnd() error { + return p.ParseObjectEnd() +} + +func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, error) { + if err := p.ParsePreValue(); err != nil { + return "", STOP, 0, err + } + b, _ := p.reader.Peek(1) + if len(b) > 0 { + switch b[0] { + case JSON_RBRACE[0]: + return "", STOP, 0, nil + case JSON_QUOTE: + p.reader.ReadByte() + name, err := p.ParseStringBody() + // simplejson is not meant to be read back into thrift + // - see http://wiki.apache.org/thrift/ThriftUsageJava + // - use JSON instead + if err != nil { + return name, STOP, 0, err + } + return name, STOP, -1, p.ParsePostValue() + /* + if err = p.ParsePostValue(); err != nil { + return name, STOP, 0, err + } + if isNull, err := p.ParseListBegin(); isNull || err != nil { + return name, STOP, 0, err + } + bType, err := p.ReadByte() + thetype := TType(bType) + if err != nil { + return name, thetype, 0, err + } + id, err := p.ReadI16() + return name, thetype, id, err + */ + } + e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b)) + return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return "", STOP, 0, NewTProtocolException(io.EOF) +} + +func (p *TSimpleJSONProtocol) ReadFieldEnd() error { + return nil + //return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, VOID, 0, e + } + + // read keyType + bKeyType, e := p.ReadByte() + keyType = TType(bKeyType) + if e != nil { + return keyType, valueType, size, e + } + + // read valueType + bValueType, e := p.ReadByte() + valueType = TType(bValueType) + if e != nil { + return keyType, valueType, size, e + } + + // read size + iSize, err := p.ReadI64() + size = int(iSize) + return keyType, valueType, size, err +} + +func (p *TSimpleJSONProtocol) ReadMapEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e error) { + return p.ParseElemListBegin() +} + +func (p *TSimpleJSONProtocol) ReadListEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) { + return p.ParseElemListBegin() +} + +func (p *TSimpleJSONProtocol) ReadSetEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadBool() (bool, error) { + var value bool + + if err := p.ParsePreValue(); err != nil { + return value, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 { + switch f[0] { + case JSON_TRUE[0]: + b := make([]byte, len(JSON_TRUE)) + _, err := p.reader.Read(b) + if err != nil { + return false, NewTProtocolException(err) + } + if string(b) == string(JSON_TRUE) { + value = true + } else { + e := fmt.Errorf("Expected \"true\" but found: %s", string(b)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + break + case JSON_FALSE[0]: + b := make([]byte, len(JSON_FALSE)) + _, err := p.reader.Read(b) + if err != nil { + return false, NewTProtocolException(err) + } + if string(b) == string(JSON_FALSE) { + value = false + } else { + e := fmt.Errorf("Expected \"false\" but found: %s", string(b)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + break + case JSON_NULL[0]: + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return false, NewTProtocolException(err) + } + if string(b) == string(JSON_NULL) { + value = false + } else { + e := fmt.Errorf("Expected \"null\" but found: %s", string(b)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + default: + e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(f)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + return value, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ReadByte() (int8, error) { + v, err := p.ReadI64() + return int8(v), err +} + +func (p *TSimpleJSONProtocol) ReadI16() (int16, error) { + v, err := p.ReadI64() + return int16(v), err +} + +func (p *TSimpleJSONProtocol) ReadI32() (int32, error) { + v, err := p.ReadI64() + return int32(v), err +} + +func (p *TSimpleJSONProtocol) ReadI64() (int64, error) { + v, _, err := p.ParseI64() + return v, err +} + +func (p *TSimpleJSONProtocol) ReadDouble() (float64, error) { + v, _, err := p.ParseF64() + return v, err +} + +func (p *TSimpleJSONProtocol) ReadString() (string, error) { + var v string + if err := p.ParsePreValue(); err != nil { + return v, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 && f[0] == JSON_QUOTE { + p.reader.ReadByte() + value, err := p.ParseStringBody() + v = value + if err != nil { + return v, err + } + } else if len(f) > 0 && f[0] == JSON_NULL[0] { + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return v, NewTProtocolException(err) + } + if string(b) != string(JSON_NULL) { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } else { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return v, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) { + var v []byte + if err := p.ParsePreValue(); err != nil { + return nil, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 && f[0] == JSON_QUOTE { + p.reader.ReadByte() + value, err := p.ParseBase64EncodedBody() + v = value + if err != nil { + return v, err + } + } else if len(f) > 0 && f[0] == JSON_NULL[0] { + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return v, NewTProtocolException(err) + } + if string(b) != string(JSON_NULL) { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } else { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + + return v, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) { + return NewTProtocolException(p.writer.Flush()) +} + +func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TSimpleJSONProtocol) Transport() TTransport { + return p.trans +} + +func (p *TSimpleJSONProtocol) OutputPreValue() error { + cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1]) + switch cxt { + case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY: + if _, e := p.write(JSON_COMMA); e != nil { + return NewTProtocolException(e) + } + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + if _, e := p.write(JSON_COLON); e != nil { + return NewTProtocolException(e) + } + break + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputPostValue() error { + cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1]) + switch cxt { + case _CONTEXT_IN_LIST_FIRST: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST)) + break + case _CONTEXT_IN_OBJECT_FIRST: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) + break + case _CONTEXT_IN_OBJECT_NEXT_KEY: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_KEY)) + break + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputBool(value bool) error { + if e := p.OutputPreValue(); e != nil { + return e + } + var v string + if value { + v = string(JSON_TRUE) + } else { + v = string(JSON_FALSE) + } + switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + v = jsonQuote(v) + default: + } + if e := p.OutputStringData(v); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputNull() error { + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_NULL); e != nil { + return NewTProtocolException(e) + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputF64(value float64) error { + if e := p.OutputPreValue(); e != nil { + return e + } + var v string + if math.IsNaN(value) { + v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE) + } else if math.IsInf(value, 1) { + v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE) + } else if math.IsInf(value, -1) { + v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE) + } else { + v = strconv.FormatFloat(value, 'g', -1, 64) + switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + v = string(JSON_QUOTE) + v + string(JSON_QUOTE) + default: + } + } + if e := p.OutputStringData(v); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputI64(value int64) error { + if e := p.OutputPreValue(); e != nil { + return e + } + v := strconv.FormatInt(value, 10) + switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + v = jsonQuote(v) + default: + } + if e := p.OutputStringData(v); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputString(s string) error { + if e := p.OutputPreValue(); e != nil { + return e + } + if e := p.OutputStringData(jsonQuote(s)); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputStringData(s string) error { + _, e := p.write([]byte(s)) + return NewTProtocolException(e) +} + +func (p *TSimpleJSONProtocol) OutputObjectBegin() error { + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_LBRACE); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_FIRST)) + return nil +} + +func (p *TSimpleJSONProtocol) OutputObjectEnd() error { + if _, e := p.write(JSON_RBRACE); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + if e := p.OutputPostValue(); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputListBegin() error { + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_LBRACKET); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST_FIRST)) + return nil +} + +func (p *TSimpleJSONProtocol) OutputListEnd() error { + if _, e := p.write(JSON_RBRACKET); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + if e := p.OutputPostValue(); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteByte(int8(elemType)); e != nil { + return e + } + if e := p.WriteI64(int64(size)); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) ParsePreValue() error { + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + b, _ := p.reader.Peek(1) + switch cxt { + case _CONTEXT_IN_LIST: + if len(b) > 0 { + switch b[0] { + case JSON_RBRACKET[0]: + return nil + case JSON_COMMA[0]: + p.reader.ReadByte() + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + return nil + default: + e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b)) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + break + case _CONTEXT_IN_OBJECT_NEXT_KEY: + if len(b) > 0 { + switch b[0] { + case JSON_RBRACE[0]: + return nil + case JSON_COMMA[0]: + p.reader.ReadByte() + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + return nil + default: + e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b)) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + if len(b) > 0 { + switch b[0] { + case JSON_COLON[0]: + p.reader.ReadByte() + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + return nil + default: + e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b)) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + break + } + return nil +} + +func (p *TSimpleJSONProtocol) ParsePostValue() error { + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + switch cxt { + case _CONTEXT_IN_LIST_FIRST: + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST)) + break + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_KEY)) + break + } + return nil +} + +func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error { + for { + b, _ := p.reader.Peek(1) + if len(b) < 1 { + return nil + } + switch b[0] { + case ' ', '\r', '\n', '\t': + p.reader.ReadByte() + continue + default: + break + } + break + } + return nil +} + +func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { + line, err := p.reader.ReadString(JSON_QUOTE) + if err != nil { + return "", NewTProtocolException(err) + } + l := len(line) + // count number of escapes to see if we need to keep going + i := 1 + for ; i < l; i++ { + if line[l-i-1] != '\\' { + break + } + } + if i&0x01 == 1 { + v, ok := jsonUnquote(string(JSON_QUOTE) + line) + if !ok { + return "", NewTProtocolException(err) + } + return v, nil + } + s, err := p.ParseQuotedStringBody() + if err != nil { + return "", NewTProtocolException(err) + } + str := string(JSON_QUOTE) + line + s + v, ok := jsonUnquote(str) + if !ok { + e := fmt.Errorf("Unable to parse as JSON string %s", str) + return "", NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return v, nil +} + +func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) { + line, err := p.reader.ReadString(JSON_QUOTE) + if err != nil { + return "", NewTProtocolException(err) + } + l := len(line) + // count number of escapes to see if we need to keep going + i := 1 + for ; i < l; i++ { + if line[l-i-1] != '\\' { + break + } + } + if i&0x01 == 1 { + return line, nil + } + s, err := p.ParseQuotedStringBody() + if err != nil { + return "", NewTProtocolException(err) + } + v := line + s + return v, nil +} + +func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) { + line, err := p.reader.ReadBytes(JSON_QUOTE) + if err != nil { + return line, NewTProtocolException(err) + } + line2 := line[0 : len(line)-1] + l := len(line2) + if (l % 4) != 0 { + pad := 4 - (l % 4) + fill := [...]byte{'=', '=', '='} + line2 = append(line2, fill[:pad]...) + l = len(line2) + } + output := make([]byte, base64.StdEncoding.DecodedLen(l)) + n, err := base64.StdEncoding.Decode(output, line2) + return output[0:n], NewTProtocolException(err) +} + +func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) { + if err := p.ParsePreValue(); err != nil { + return 0, false, err + } + var value int64 + var isnull bool + if p.safePeekContains(JSON_NULL) { + p.reader.Read(make([]byte, len(JSON_NULL))) + isnull = true + } else { + num, err := p.readNumeric() + isnull = (num == nil) + if !isnull { + value = num.Int64() + } + if err != nil { + return value, isnull, err + } + } + return value, isnull, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) { + if err := p.ParsePreValue(); err != nil { + return 0, false, err + } + var value float64 + var isnull bool + if p.safePeekContains(JSON_NULL) { + p.reader.Read(make([]byte, len(JSON_NULL))) + isnull = true + } else { + num, err := p.readNumeric() + isnull = (num == nil) + if !isnull { + value = num.Float64() + } + if err != nil { + return value, isnull, err + } + } + return value, isnull, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) { + if err := p.ParsePreValue(); err != nil { + return false, err + } + var b []byte + b, err := p.reader.Peek(1) + if err != nil { + return false, err + } + if len(b) > 0 && b[0] == JSON_LBRACE[0] { + p.reader.ReadByte() + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_FIRST)) + return false, nil + } else if p.safePeekContains(JSON_NULL) { + return true, nil + } + e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b)) + return false, NewTProtocolExceptionWithType(INVALID_DATA, e) +} + +func (p *TSimpleJSONProtocol) ParseObjectEnd() error { + if isNull, err := p.readIfNull(); isNull || err != nil { + return err + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + if (cxt != _CONTEXT_IN_OBJECT_FIRST) && (cxt != _CONTEXT_IN_OBJECT_NEXT_KEY) { + e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context (%d)", cxt) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + line, err := p.reader.ReadString(JSON_RBRACE[0]) + if err != nil { + return NewTProtocolException(err) + } + for _, char := range line { + switch char { + default: + e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + case ' ', '\n', '\r', '\t', '}': + break + } + } + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + return p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) { + if e := p.ParsePreValue(); e != nil { + return false, e + } + var b []byte + b, err = p.reader.Peek(1) + if err != nil { + return false, err + } + if len(b) >= 1 && b[0] == JSON_LBRACKET[0] { + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST_FIRST)) + p.reader.ReadByte() + isNull = false + } else if p.safePeekContains(JSON_NULL) { + isNull = true + } else { + err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b) + } + return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err) +} + +func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, 0, e + } + bElemType, err := p.ReadByte() + elemType = TType(bElemType) + if err != nil { + return elemType, size, err + } + nSize, err2 := p.ReadI64() + size = int(nSize) + return elemType, size, err2 +} + +func (p *TSimpleJSONProtocol) ParseListEnd() error { + if isNull, err := p.readIfNull(); isNull || err != nil { + return err + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + if cxt != _CONTEXT_IN_LIST { + e := fmt.Errorf("Expected to be in the List Context, but not in List Context (%d)", cxt) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + line, err := p.reader.ReadString(JSON_RBRACKET[0]) + if err != nil { + return NewTProtocolException(err) + } + for _, char := range line { + switch char { + default: + e := fmt.Errorf("Expecting end of list \"]\", but found: \"%v\"", line) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]): + break + } + } + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + if _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) == _CONTEXT_IN_TOPLEVEL { + return nil + } + return p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) { + e := p.readNonSignificantWhitespace() + if e != nil { + return nil, VOID, NewTProtocolException(e) + } + b, e := p.reader.Peek(1) + if len(b) > 0 { + c := b[0] + switch c { + case JSON_NULL[0]: + buf := make([]byte, len(JSON_NULL)) + _, e := p.reader.Read(buf) + if e != nil { + return nil, VOID, NewTProtocolException(e) + } + if string(JSON_NULL) != string(buf) { + e = mismatch(string(JSON_NULL), string(buf)) + return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return nil, VOID, nil + case JSON_QUOTE: + p.reader.ReadByte() + v, e := p.ParseStringBody() + if e != nil { + return v, UTF8, NewTProtocolException(e) + } + if v == JSON_INFINITY { + return INFINITY, DOUBLE, nil + } else if v == JSON_NEGATIVE_INFINITY { + return NEGATIVE_INFINITY, DOUBLE, nil + } else if v == JSON_NAN { + return NAN, DOUBLE, nil + } + return v, UTF8, nil + case JSON_TRUE[0]: + buf := make([]byte, len(JSON_TRUE)) + _, e := p.reader.Read(buf) + if e != nil { + return true, BOOL, NewTProtocolException(e) + } + if string(JSON_TRUE) != string(buf) { + e := mismatch(string(JSON_TRUE), string(buf)) + return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return true, BOOL, nil + case JSON_FALSE[0]: + buf := make([]byte, len(JSON_FALSE)) + _, e := p.reader.Read(buf) + if e != nil { + return false, BOOL, NewTProtocolException(e) + } + if string(JSON_FALSE) != string(buf) { + e := mismatch(string(JSON_FALSE), string(buf)) + return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return false, BOOL, nil + case JSON_LBRACKET[0]: + _, e := p.reader.ReadByte() + return make([]interface{}, 0), LIST, NewTProtocolException(e) + case JSON_LBRACE[0]: + _, e := p.reader.ReadByte() + return make(map[string]interface{}), STRUCT, NewTProtocolException(e) + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]: + // assume numeric + v, e := p.readNumeric() + return v, DOUBLE, e + default: + e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c)) + return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + e = fmt.Errorf("Cannot read a single element while parsing JSON.") + return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e) + +} + +func (p *TSimpleJSONProtocol) readIfNull() (bool, error) { + cont := true + for cont { + b, _ := p.reader.Peek(1) + if len(b) < 1 { + return false, nil + } + switch b[0] { + default: + return false, nil + case JSON_NULL[0]: + cont = false + break + case ' ', '\n', '\r', '\t': + p.reader.ReadByte() + break + } + } + if p.safePeekContains(JSON_NULL) { + p.reader.Read(make([]byte, len(JSON_NULL))) + return true, nil + } + return false, nil +} + +func (p *TSimpleJSONProtocol) readQuoteIfNext() { + b, _ := p.reader.Peek(1) + if len(b) > 0 && b[0] == JSON_QUOTE { + p.reader.ReadByte() + } +} + +func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { + isNull, err := p.readIfNull() + if isNull || err != nil { + return NUMERIC_NULL, err + } + hasDecimalPoint := false + nextCanBeSign := true + hasE := false + MAX_LEN := 40 + buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN)) + continueFor := true + inQuotes := false + for continueFor { + c, err := p.reader.ReadByte() + if err != nil { + if err == io.EOF { + break + } + return NUMERIC_NULL, NewTProtocolException(err) + } + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + buf.WriteByte(c) + nextCanBeSign = false + case '.': + if hasDecimalPoint { + e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String()) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if hasE { + e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String()) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + buf.WriteByte(c) + hasDecimalPoint, nextCanBeSign = true, false + case 'e', 'E': + if hasE { + e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + buf.WriteByte(c) + hasE, nextCanBeSign = true, true + case '-', '+': + if !nextCanBeSign { + e := fmt.Errorf("Negative sign within number") + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + buf.WriteByte(c) + nextCanBeSign = false + case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]: + p.reader.UnreadByte() + continueFor = false + case JSON_NAN[0]: + if buf.Len() == 0 { + buffer := make([]byte, len(JSON_NAN)) + buffer[0] = c + _, e := p.reader.Read(buffer[1:]) + if e != nil { + return NUMERIC_NULL, NewTProtocolException(e) + } + if JSON_NAN != string(buffer) { + e := mismatch(JSON_NAN, string(buffer)) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if inQuotes { + p.readQuoteIfNext() + } + return NAN, nil + } else { + e := fmt.Errorf("Unable to parse number starting with character '%c'", c) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + case JSON_INFINITY[0]: + if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') { + buffer := make([]byte, len(JSON_INFINITY)) + buffer[0] = c + _, e := p.reader.Read(buffer[1:]) + if e != nil { + return NUMERIC_NULL, NewTProtocolException(e) + } + if JSON_INFINITY != string(buffer) { + e := mismatch(JSON_INFINITY, string(buffer)) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if inQuotes { + p.readQuoteIfNext() + } + return INFINITY, nil + } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] { + buffer := make([]byte, len(JSON_NEGATIVE_INFINITY)) + buffer[0] = JSON_NEGATIVE_INFINITY[0] + buffer[1] = c + _, e := p.reader.Read(buffer[2:]) + if e != nil { + return NUMERIC_NULL, NewTProtocolException(e) + } + if JSON_NEGATIVE_INFINITY != string(buffer) { + e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer)) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if inQuotes { + p.readQuoteIfNext() + } + return NEGATIVE_INFINITY, nil + } else { + e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String()) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + case JSON_QUOTE: + if !inQuotes { + inQuotes = true + } else { + break + } + default: + e := fmt.Errorf("Unable to parse number starting with character '%c'", c) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + if buf.Len() == 0 { + e := fmt.Errorf("Unable to parse number from empty string ''") + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return NewNumericFromJSONString(buf.String(), false), nil +} + +// Safely peeks into the buffer, reading only what is necessary +func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool { + for i := 0; i < len(b); i++ { + a, _ := p.reader.Peek(i + 1) + if len(a) == 0 || a[i] != b[i] { + return false + } + } + return true +} + +// Reset the context stack to its initial state. +func (p *TSimpleJSONProtocol) resetContextStack() { + p.parseContextStack = []int{int(_CONTEXT_IN_TOPLEVEL)} + p.dumpContext = []int{int(_CONTEXT_IN_TOPLEVEL)} +} + +func (p *TSimpleJSONProtocol) write(b []byte) (int, error) { + n, err := p.writer.Write(b) + if err != nil { + p.writer.Reset(p.trans) // THRIFT-3735 + } + return n, err +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/simple_server.go b/vendor/github.com/apache/thrift/lib/go/thrift/simple_server.go new file mode 100644 index 000000000..603580251 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/simple_server.go @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "log" + "runtime/debug" + "sync" + "sync/atomic" +) + +/* + * This is not a typical TSimpleServer as it is not blocked after accept a socket. + * It is more like a TThreadedServer that can handle different connections in different goroutines. + * This will work if golang user implements a conn-pool like thing in client side. + */ +type TSimpleServer struct { + closed int32 + wg sync.WaitGroup + mu sync.Mutex + + processorFactory TProcessorFactory + serverTransport TServerTransport + inputTransportFactory TTransportFactory + outputTransportFactory TTransportFactory + inputProtocolFactory TProtocolFactory + outputProtocolFactory TProtocolFactory +} + +func NewTSimpleServer2(processor TProcessor, serverTransport TServerTransport) *TSimpleServer { + return NewTSimpleServerFactory2(NewTProcessorFactory(processor), serverTransport) +} + +func NewTSimpleServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer { + return NewTSimpleServerFactory4(NewTProcessorFactory(processor), + serverTransport, + transportFactory, + protocolFactory, + ) +} + +func NewTSimpleServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer { + return NewTSimpleServerFactory6(NewTProcessorFactory(processor), + serverTransport, + inputTransportFactory, + outputTransportFactory, + inputProtocolFactory, + outputProtocolFactory, + ) +} + +func NewTSimpleServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TSimpleServer { + return NewTSimpleServerFactory6(processorFactory, + serverTransport, + NewTTransportFactory(), + NewTTransportFactory(), + NewTBinaryProtocolFactoryDefault(), + NewTBinaryProtocolFactoryDefault(), + ) +} + +func NewTSimpleServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer { + return NewTSimpleServerFactory6(processorFactory, + serverTransport, + transportFactory, + transportFactory, + protocolFactory, + protocolFactory, + ) +} + +func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer { + return &TSimpleServer{ + processorFactory: processorFactory, + serverTransport: serverTransport, + inputTransportFactory: inputTransportFactory, + outputTransportFactory: outputTransportFactory, + inputProtocolFactory: inputProtocolFactory, + outputProtocolFactory: outputProtocolFactory, + } +} + +func (p *TSimpleServer) ProcessorFactory() TProcessorFactory { + return p.processorFactory +} + +func (p *TSimpleServer) ServerTransport() TServerTransport { + return p.serverTransport +} + +func (p *TSimpleServer) InputTransportFactory() TTransportFactory { + return p.inputTransportFactory +} + +func (p *TSimpleServer) OutputTransportFactory() TTransportFactory { + return p.outputTransportFactory +} + +func (p *TSimpleServer) InputProtocolFactory() TProtocolFactory { + return p.inputProtocolFactory +} + +func (p *TSimpleServer) OutputProtocolFactory() TProtocolFactory { + return p.outputProtocolFactory +} + +func (p *TSimpleServer) Listen() error { + return p.serverTransport.Listen() +} + +func (p *TSimpleServer) innerAccept() (int32, error) { + client, err := p.serverTransport.Accept() + p.mu.Lock() + defer p.mu.Unlock() + closed := atomic.LoadInt32(&p.closed) + if closed != 0 { + return closed, nil + } + if err != nil { + return 0, err + } + if client != nil { + p.wg.Add(1) + go func() { + defer p.wg.Done() + if err := p.processRequests(client); err != nil { + log.Println("error processing request:", err) + } + }() + } + return 0, nil +} + +func (p *TSimpleServer) AcceptLoop() error { + for { + closed, err := p.innerAccept() + if err != nil { + return err + } + if closed != 0 { + return nil + } + } +} + +func (p *TSimpleServer) Serve() error { + err := p.Listen() + if err != nil { + return err + } + p.AcceptLoop() + return nil +} + +func (p *TSimpleServer) Stop() error { + p.mu.Lock() + defer p.mu.Unlock() + if atomic.LoadInt32(&p.closed) != 0 { + return nil + } + atomic.StoreInt32(&p.closed, 1) + p.serverTransport.Interrupt() + p.wg.Wait() + return nil +} + +func (p *TSimpleServer) processRequests(client TTransport) error { + processor := p.processorFactory.GetProcessor(client) + inputTransport, err := p.inputTransportFactory.GetTransport(client) + if err != nil { + return err + } + outputTransport, err := p.outputTransportFactory.GetTransport(client) + if err != nil { + return err + } + inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport) + outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport) + defer func() { + if e := recover(); e != nil { + log.Printf("panic in processor: %s: %s", e, debug.Stack()) + } + }() + + if inputTransport != nil { + defer inputTransport.Close() + } + if outputTransport != nil { + defer outputTransport.Close() + } + for { + if atomic.LoadInt32(&p.closed) != 0 { + return nil + } + + ok, err := processor.Process(defaultCtx, inputProtocol, outputProtocol) + if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE { + return nil + } else if err != nil { + return err + } + if err, ok := err.(TApplicationException); ok && err.TypeId() == UNKNOWN_METHOD { + continue + } + if !ok { + break + } + } + return nil +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/socket.go b/vendor/github.com/apache/thrift/lib/go/thrift/socket.go new file mode 100644 index 000000000..885427965 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/socket.go @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "net" + "time" +) + +type TSocket struct { + conn net.Conn + addr net.Addr + timeout time.Duration +} + +// NewTSocket creates a net.Conn-backed TTransport, given a host and port +// +// Example: +// trans, err := thrift.NewTSocket("localhost:9090") +func NewTSocket(hostPort string) (*TSocket, error) { + return NewTSocketTimeout(hostPort, 0) +} + +// NewTSocketTimeout creates a net.Conn-backed TTransport, given a host and port +// it also accepts a timeout as a time.Duration +func NewTSocketTimeout(hostPort string, timeout time.Duration) (*TSocket, error) { + //conn, err := net.DialTimeout(network, address, timeout) + addr, err := net.ResolveTCPAddr("tcp", hostPort) + if err != nil { + return nil, err + } + return NewTSocketFromAddrTimeout(addr, timeout), nil +} + +// Creates a TSocket from a net.Addr +func NewTSocketFromAddrTimeout(addr net.Addr, timeout time.Duration) *TSocket { + return &TSocket{addr: addr, timeout: timeout} +} + +// Creates a TSocket from an existing net.Conn +func NewTSocketFromConnTimeout(conn net.Conn, timeout time.Duration) *TSocket { + return &TSocket{conn: conn, addr: conn.RemoteAddr(), timeout: timeout} +} + +// Sets the socket timeout +func (p *TSocket) SetTimeout(timeout time.Duration) error { + p.timeout = timeout + return nil +} + +func (p *TSocket) pushDeadline(read, write bool) { + var t time.Time + if p.timeout > 0 { + t = time.Now().Add(time.Duration(p.timeout)) + } + if read && write { + p.conn.SetDeadline(t) + } else if read { + p.conn.SetReadDeadline(t) + } else if write { + p.conn.SetWriteDeadline(t) + } +} + +// Connects the socket, creating a new socket object if necessary. +func (p *TSocket) Open() error { + if p.IsOpen() { + return NewTTransportException(ALREADY_OPEN, "Socket already connected.") + } + if p.addr == nil { + return NewTTransportException(NOT_OPEN, "Cannot open nil address.") + } + if len(p.addr.Network()) == 0 { + return NewTTransportException(NOT_OPEN, "Cannot open bad network name.") + } + if len(p.addr.String()) == 0 { + return NewTTransportException(NOT_OPEN, "Cannot open bad address.") + } + var err error + if p.conn, err = net.DialTimeout(p.addr.Network(), p.addr.String(), p.timeout); err != nil { + return NewTTransportException(NOT_OPEN, err.Error()) + } + return nil +} + +// Retrieve the underlying net.Conn +func (p *TSocket) Conn() net.Conn { + return p.conn +} + +// Returns true if the connection is open +func (p *TSocket) IsOpen() bool { + if p.conn == nil { + return false + } + return true +} + +// Closes the socket. +func (p *TSocket) Close() error { + // Close the socket + if p.conn != nil { + err := p.conn.Close() + if err != nil { + return err + } + p.conn = nil + } + return nil +} + +//Returns the remote address of the socket. +func (p *TSocket) Addr() net.Addr { + return p.addr +} + +func (p *TSocket) Read(buf []byte) (int, error) { + if !p.IsOpen() { + return 0, NewTTransportException(NOT_OPEN, "Connection not open") + } + p.pushDeadline(true, false) + n, err := p.conn.Read(buf) + return n, NewTTransportExceptionFromError(err) +} + +func (p *TSocket) Write(buf []byte) (int, error) { + if !p.IsOpen() { + return 0, NewTTransportException(NOT_OPEN, "Connection not open") + } + p.pushDeadline(false, true) + return p.conn.Write(buf) +} + +func (p *TSocket) Flush(ctx context.Context) error { + return nil +} + +func (p *TSocket) Interrupt() error { + if !p.IsOpen() { + return nil + } + return p.conn.Close() +} + +func (p *TSocket) RemainingBytes() (num_bytes uint64) { + const maxSize = ^uint64(0) + return maxSize // the thruth is, we just don't know unless framed is used +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/ssl_server_socket.go b/vendor/github.com/apache/thrift/lib/go/thrift/ssl_server_socket.go new file mode 100644 index 000000000..907afca32 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/ssl_server_socket.go @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "crypto/tls" + "net" + "time" +) + +type TSSLServerSocket struct { + listener net.Listener + addr net.Addr + clientTimeout time.Duration + interrupted bool + cfg *tls.Config +} + +func NewTSSLServerSocket(listenAddr string, cfg *tls.Config) (*TSSLServerSocket, error) { + return NewTSSLServerSocketTimeout(listenAddr, cfg, 0) +} + +func NewTSSLServerSocketTimeout(listenAddr string, cfg *tls.Config, clientTimeout time.Duration) (*TSSLServerSocket, error) { + if cfg.MinVersion == 0 { + cfg.MinVersion = tls.VersionTLS10 + } + addr, err := net.ResolveTCPAddr("tcp", listenAddr) + if err != nil { + return nil, err + } + return &TSSLServerSocket{addr: addr, clientTimeout: clientTimeout, cfg: cfg}, nil +} + +func (p *TSSLServerSocket) Listen() error { + if p.IsListening() { + return nil + } + l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg) + if err != nil { + return err + } + p.listener = l + return nil +} + +func (p *TSSLServerSocket) Accept() (TTransport, error) { + if p.interrupted { + return nil, errTransportInterrupted + } + if p.listener == nil { + return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") + } + conn, err := p.listener.Accept() + if err != nil { + return nil, NewTTransportExceptionFromError(err) + } + return NewTSSLSocketFromConnTimeout(conn, p.cfg, p.clientTimeout), nil +} + +// Checks whether the socket is listening. +func (p *TSSLServerSocket) IsListening() bool { + return p.listener != nil +} + +// Connects the socket, creating a new socket object if necessary. +func (p *TSSLServerSocket) Open() error { + if p.IsListening() { + return NewTTransportException(ALREADY_OPEN, "Server socket already open") + } + if l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg); err != nil { + return err + } else { + p.listener = l + } + return nil +} + +func (p *TSSLServerSocket) Addr() net.Addr { + return p.addr +} + +func (p *TSSLServerSocket) Close() error { + defer func() { + p.listener = nil + }() + if p.IsListening() { + return p.listener.Close() + } + return nil +} + +func (p *TSSLServerSocket) Interrupt() error { + p.interrupted = true + return nil +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/ssl_socket.go b/vendor/github.com/apache/thrift/lib/go/thrift/ssl_socket.go new file mode 100644 index 000000000..ba6337726 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/ssl_socket.go @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "crypto/tls" + "net" + "time" +) + +type TSSLSocket struct { + conn net.Conn + // hostPort contains host:port (e.g. "asdf.com:12345"). The field is + // only valid if addr is nil. + hostPort string + // addr is nil when hostPort is not "", and is only used when the + // TSSLSocket is constructed from a net.Addr. + addr net.Addr + timeout time.Duration + cfg *tls.Config +} + +// NewTSSLSocket creates a net.Conn-backed TTransport, given a host and port and tls Configuration +// +// Example: +// trans, err := thrift.NewTSSLSocket("localhost:9090", nil) +func NewTSSLSocket(hostPort string, cfg *tls.Config) (*TSSLSocket, error) { + return NewTSSLSocketTimeout(hostPort, cfg, 0) +} + +// NewTSSLSocketTimeout creates a net.Conn-backed TTransport, given a host and port +// it also accepts a tls Configuration and a timeout as a time.Duration +func NewTSSLSocketTimeout(hostPort string, cfg *tls.Config, timeout time.Duration) (*TSSLSocket, error) { + if cfg.MinVersion == 0 { + cfg.MinVersion = tls.VersionTLS10 + } + return &TSSLSocket{hostPort: hostPort, timeout: timeout, cfg: cfg}, nil +} + +// Creates a TSSLSocket from a net.Addr +func NewTSSLSocketFromAddrTimeout(addr net.Addr, cfg *tls.Config, timeout time.Duration) *TSSLSocket { + return &TSSLSocket{addr: addr, timeout: timeout, cfg: cfg} +} + +// Creates a TSSLSocket from an existing net.Conn +func NewTSSLSocketFromConnTimeout(conn net.Conn, cfg *tls.Config, timeout time.Duration) *TSSLSocket { + return &TSSLSocket{conn: conn, addr: conn.RemoteAddr(), timeout: timeout, cfg: cfg} +} + +// Sets the socket timeout +func (p *TSSLSocket) SetTimeout(timeout time.Duration) error { + p.timeout = timeout + return nil +} + +func (p *TSSLSocket) pushDeadline(read, write bool) { + var t time.Time + if p.timeout > 0 { + t = time.Now().Add(time.Duration(p.timeout)) + } + if read && write { + p.conn.SetDeadline(t) + } else if read { + p.conn.SetReadDeadline(t) + } else if write { + p.conn.SetWriteDeadline(t) + } +} + +// Connects the socket, creating a new socket object if necessary. +func (p *TSSLSocket) Open() error { + var err error + // If we have a hostname, we need to pass the hostname to tls.Dial for + // certificate hostname checks. + if p.hostPort != "" { + if p.conn, err = tls.DialWithDialer(&net.Dialer{ + Timeout: p.timeout}, "tcp", p.hostPort, p.cfg); err != nil { + return NewTTransportException(NOT_OPEN, err.Error()) + } + } else { + if p.IsOpen() { + return NewTTransportException(ALREADY_OPEN, "Socket already connected.") + } + if p.addr == nil { + return NewTTransportException(NOT_OPEN, "Cannot open nil address.") + } + if len(p.addr.Network()) == 0 { + return NewTTransportException(NOT_OPEN, "Cannot open bad network name.") + } + if len(p.addr.String()) == 0 { + return NewTTransportException(NOT_OPEN, "Cannot open bad address.") + } + if p.conn, err = tls.DialWithDialer(&net.Dialer{ + Timeout: p.timeout}, p.addr.Network(), p.addr.String(), p.cfg); err != nil { + return NewTTransportException(NOT_OPEN, err.Error()) + } + } + return nil +} + +// Retrieve the underlying net.Conn +func (p *TSSLSocket) Conn() net.Conn { + return p.conn +} + +// Returns true if the connection is open +func (p *TSSLSocket) IsOpen() bool { + if p.conn == nil { + return false + } + return true +} + +// Closes the socket. +func (p *TSSLSocket) Close() error { + // Close the socket + if p.conn != nil { + err := p.conn.Close() + if err != nil { + return err + } + p.conn = nil + } + return nil +} + +func (p *TSSLSocket) Read(buf []byte) (int, error) { + if !p.IsOpen() { + return 0, NewTTransportException(NOT_OPEN, "Connection not open") + } + p.pushDeadline(true, false) + n, err := p.conn.Read(buf) + return n, NewTTransportExceptionFromError(err) +} + +func (p *TSSLSocket) Write(buf []byte) (int, error) { + if !p.IsOpen() { + return 0, NewTTransportException(NOT_OPEN, "Connection not open") + } + p.pushDeadline(false, true) + return p.conn.Write(buf) +} + +func (p *TSSLSocket) Flush(ctx context.Context) error { + return nil +} + +func (p *TSSLSocket) Interrupt() error { + if !p.IsOpen() { + return nil + } + return p.conn.Close() +} + +func (p *TSSLSocket) RemainingBytes() (num_bytes uint64) { + const maxSize = ^uint64(0) + return maxSize // the thruth is, we just don't know unless framed is used +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/transport.go new file mode 100644 index 000000000..ba2738a8d --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/transport.go @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "context" + "errors" + "io" +) + +var errTransportInterrupted = errors.New("Transport Interrupted") + +type Flusher interface { + Flush() (err error) +} + +type ContextFlusher interface { + Flush(ctx context.Context) (err error) +} + +type ReadSizeProvider interface { + RemainingBytes() (num_bytes uint64) +} + +// Encapsulates the I/O layer +type TTransport interface { + io.ReadWriteCloser + ContextFlusher + ReadSizeProvider + + // Opens the transport for communication + Open() error + + // Returns true if the transport is open + IsOpen() bool +} + +type stringWriter interface { + WriteString(s string) (n int, err error) +} + +// This is "enchanced" transport with extra capabilities. You need to use one of these +// to construct protocol. +// Notably, TSocket does not implement this interface, and it is always a mistake to use +// TSocket directly in protocol. +type TRichTransport interface { + io.ReadWriter + io.ByteReader + io.ByteWriter + stringWriter + ContextFlusher + ReadSizeProvider +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/transport_exception.go b/vendor/github.com/apache/thrift/lib/go/thrift/transport_exception.go new file mode 100644 index 000000000..9505b4461 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/transport_exception.go @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "errors" + "io" +) + +type timeoutable interface { + Timeout() bool +} + +// Thrift Transport exception +type TTransportException interface { + TException + TypeId() int + Err() error +} + +const ( + UNKNOWN_TRANSPORT_EXCEPTION = 0 + NOT_OPEN = 1 + ALREADY_OPEN = 2 + TIMED_OUT = 3 + END_OF_FILE = 4 +) + +type tTransportException struct { + typeId int + err error +} + +func (p *tTransportException) TypeId() int { + return p.typeId +} + +func (p *tTransportException) Error() string { + return p.err.Error() +} + +func (p *tTransportException) Err() error { + return p.err +} + +func NewTTransportException(t int, e string) TTransportException { + return &tTransportException{typeId: t, err: errors.New(e)} +} + +func NewTTransportExceptionFromError(e error) TTransportException { + if e == nil { + return nil + } + + if t, ok := e.(TTransportException); ok { + return t + } + + switch v := e.(type) { + case TTransportException: + return v + case timeoutable: + if v.Timeout() { + return &tTransportException{typeId: TIMED_OUT, err: e} + } + } + + if e == io.EOF { + return &tTransportException{typeId: END_OF_FILE, err: e} + } + + return &tTransportException{typeId: UNKNOWN_TRANSPORT_EXCEPTION, err: e} +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/transport_factory.go b/vendor/github.com/apache/thrift/lib/go/thrift/transport_factory.go new file mode 100644 index 000000000..c80580794 --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/transport_factory.go @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Factory class used to create wrapped instance of Transports. +// This is used primarily in servers, which get Transports from +// a ServerTransport and then may want to mutate them (i.e. create +// a BufferedTransport from the underlying base transport) +type TTransportFactory interface { + GetTransport(trans TTransport) (TTransport, error) +} + +type tTransportFactory struct{} + +// Return a wrapped instance of the base Transport. +func (p *tTransportFactory) GetTransport(trans TTransport) (TTransport, error) { + return trans, nil +} + +func NewTTransportFactory() TTransportFactory { + return &tTransportFactory{} +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/type.go b/vendor/github.com/apache/thrift/lib/go/thrift/type.go new file mode 100644 index 000000000..4292ffcad --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/type.go @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Type constants in the Thrift protocol +type TType byte + +const ( + STOP = 0 + VOID = 1 + BOOL = 2 + BYTE = 3 + I08 = 3 + DOUBLE = 4 + I16 = 6 + I32 = 8 + I64 = 10 + STRING = 11 + UTF7 = 11 + STRUCT = 12 + MAP = 13 + SET = 14 + LIST = 15 + UTF8 = 16 + UTF16 = 17 + //BINARY = 18 wrong and unusued +) + +var typeNames = map[int]string{ + STOP: "STOP", + VOID: "VOID", + BOOL: "BOOL", + BYTE: "BYTE", + DOUBLE: "DOUBLE", + I16: "I16", + I32: "I32", + I64: "I64", + STRING: "STRING", + STRUCT: "STRUCT", + MAP: "MAP", + SET: "SET", + LIST: "LIST", + UTF8: "UTF8", + UTF16: "UTF16", +} + +func (p TType) String() string { + if s, ok := typeNames[int(p)]; ok { + return s + } + return "Unknown" +} diff --git a/vendor/github.com/apache/thrift/lib/go/thrift/zlib_transport.go b/vendor/github.com/apache/thrift/lib/go/thrift/zlib_transport.go new file mode 100644 index 000000000..f3d42673a --- /dev/null +++ b/vendor/github.com/apache/thrift/lib/go/thrift/zlib_transport.go @@ -0,0 +1,132 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you 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 thrift + +import ( + "compress/zlib" + "context" + "io" + "log" +) + +// TZlibTransportFactory is a factory for TZlibTransport instances +type TZlibTransportFactory struct { + level int + factory TTransportFactory +} + +// TZlibTransport is a TTransport implementation that makes use of zlib compression. +type TZlibTransport struct { + reader io.ReadCloser + transport TTransport + writer *zlib.Writer +} + +// GetTransport constructs a new instance of NewTZlibTransport +func (p *TZlibTransportFactory) GetTransport(trans TTransport) (TTransport, error) { + if p.factory != nil { + // wrap other factory + var err error + trans, err = p.factory.GetTransport(trans) + if err != nil { + return nil, err + } + } + return NewTZlibTransport(trans, p.level) +} + +// NewTZlibTransportFactory constructs a new instance of NewTZlibTransportFactory +func NewTZlibTransportFactory(level int) *TZlibTransportFactory { + return &TZlibTransportFactory{level: level, factory: nil} +} + +// NewTZlibTransportFactory constructs a new instance of TZlibTransportFactory +// as a wrapper over existing transport factory +func NewTZlibTransportFactoryWithFactory(level int, factory TTransportFactory) *TZlibTransportFactory { + return &TZlibTransportFactory{level: level, factory: factory} +} + +// NewTZlibTransport constructs a new instance of TZlibTransport +func NewTZlibTransport(trans TTransport, level int) (*TZlibTransport, error) { + w, err := zlib.NewWriterLevel(trans, level) + if err != nil { + log.Println(err) + return nil, err + } + + return &TZlibTransport{ + writer: w, + transport: trans, + }, nil +} + +// Close closes the reader and writer (flushing any unwritten data) and closes +// the underlying transport. +func (z *TZlibTransport) Close() error { + if z.reader != nil { + if err := z.reader.Close(); err != nil { + return err + } + } + if err := z.writer.Close(); err != nil { + return err + } + return z.transport.Close() +} + +// Flush flushes the writer and its underlying transport. +func (z *TZlibTransport) Flush(ctx context.Context) error { + if err := z.writer.Flush(); err != nil { + return err + } + return z.transport.Flush(ctx) +} + +// IsOpen returns true if the transport is open +func (z *TZlibTransport) IsOpen() bool { + return z.transport.IsOpen() +} + +// Open opens the transport for communication +func (z *TZlibTransport) Open() error { + return z.transport.Open() +} + +func (z *TZlibTransport) Read(p []byte) (int, error) { + if z.reader == nil { + r, err := zlib.NewReader(z.transport) + if err != nil { + return 0, NewTTransportExceptionFromError(err) + } + z.reader = r + } + + return z.reader.Read(p) +} + +// RemainingBytes returns the size in bytes of the data that is still to be +// read. +func (z *TZlibTransport) RemainingBytes() uint64 { + return z.transport.RemainingBytes() +} + +func (z *TZlibTransport) Write(p []byte) (int, error) { + return z.writer.Write(p) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/aws/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go new file mode 100644 index 000000000..44aa125a1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go @@ -0,0 +1,86 @@ +// Package arn provides a parser for interacting with Amazon Resource Names. +package arn + +import ( + "errors" + "strings" +) + +const ( + arnDelimiter = ":" + arnSections = 6 + arnPrefix = "arn:" + + // zero-indexed + sectionPartition = 1 + sectionService = 2 + sectionRegion = 3 + sectionAccountID = 4 + sectionResource = 5 + + // errors + invalidPrefix = "arn: invalid prefix" + invalidSections = "arn: not enough sections" +) + +// ARN captures the individual fields of an Amazon Resource Name. +// See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more information. +type ARN struct { + // The partition that the resource is in. For standard AWS regions, the partition is "aws". If you have resources in + // other partitions, the partition is "aws-partitionname". For example, the partition for resources in the China + // (Beijing) region is "aws-cn". + Partition string + + // The service namespace that identifies the AWS product (for example, Amazon S3, IAM, or Amazon RDS). For a list of + // namespaces, see + // http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces. + Service string + + // The region the resource resides in. Note that the ARNs for some resources do not require a region, so this + // component might be omitted. + Region string + + // The ID of the AWS account that owns the resource, without the hyphens. For example, 123456789012. Note that the + // ARNs for some resources don't require an account number, so this component might be omitted. + AccountID string + + // The content of this part of the ARN varies by service. It often includes an indicator of the type of resource — + // for example, an IAM user or Amazon RDS database - followed by a slash (/) or a colon (:), followed by the + // resource name itself. Some services allows paths for resource names, as described in + // http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-paths. + Resource string +} + +// Parse parses an ARN into its constituent parts. +// +// Some example ARNs: +// arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment +// arn:aws:iam::123456789012:user/David +// arn:aws:rds:eu-west-1:123456789012:db:mysql-db +// arn:aws:s3:::my_corporate_bucket/exampleobject.png +func Parse(arn string) (ARN, error) { + if !strings.HasPrefix(arn, arnPrefix) { + return ARN{}, errors.New(invalidPrefix) + } + sections := strings.SplitN(arn, arnDelimiter, arnSections) + if len(sections) != arnSections { + return ARN{}, errors.New(invalidSections) + } + return ARN{ + Partition: sections[sectionPartition], + Service: sections[sectionService], + Region: sections[sectionRegion], + AccountID: sections[sectionAccountID], + Resource: sections[sectionResource], + }, nil +} + +// String returns the canonical representation of the ARN +func (arn ARN) String() string { + return arnPrefix + + arn.Partition + arnDelimiter + + arn.Service + arnDelimiter + + arn.Region + arnDelimiter + + arn.AccountID + arnDelimiter + + arn.Resource +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/error.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/error.go new file mode 100644 index 000000000..56fdfc2bf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/error.go @@ -0,0 +1,145 @@ +// Package awserr represents API error interface accessors for the SDK. +package awserr + +// An Error wraps lower level errors with code, message and an original error. +// The underlying concrete error type may also satisfy other interfaces which +// can be to used to obtain more specific information about the error. +// +// Calling Error() or String() will always include the full information about +// an error based on its underlying type. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Get error details +// log.Println("Error:", awsErr.Code(), awsErr.Message()) +// +// // Prints out full error message, including original error if there was one. +// log.Println("Error:", awsErr.Error()) +// +// // Get original error +// if origErr := awsErr.OrigErr(); origErr != nil { +// // operate on original error. +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type Error interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErr() error +} + +// 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 occurred in the batch. +// +// Deprecated: Replaced with BatchedErrors. Only defined for backwards +// compatibility. +type BatchError interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// 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 occurred in the batch. +// +// Replaces BatchError +type BatchedErrors interface { + // Satisfy the base Error interface. + Error + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// New returns an Error object described by the code, message, and origErr. +// +// If origErr satisfies the Error interface it will not be wrapped within a new +// Error object and will instead be returned. +func New(code, message string, origErr error) Error { + var errs []error + if origErr != nil { + errs = append(errs, origErr) + } + return newBaseError(code, message, errs) +} + +// NewBatchError returns an BatchedErrors with a collection of errors as an +// array of errors. +func NewBatchError(code, message string, errs []error) BatchedErrors { + return newBaseError(code, message, errs) +} + +// A RequestFailure is an interface to extract request failure information from +// an Error such as the request ID of the failed request returned by a service. +// RequestFailures may not always have a requestID value if the request failed +// prior to reaching the service such as a connection error. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if reqerr, ok := err.(RequestFailure); ok { +// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID()) +// } else { +// log.Println("Error:", err.Error()) +// } +// } +// +// Combined with awserr.Error: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Generic AWS Error with Code, Message, and original error (if any) +// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) +// +// if reqErr, ok := err.(awserr.RequestFailure); ok { +// // A service error occurred +// fmt.Println(reqErr.StatusCode(), reqErr.RequestID()) +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type RequestFailure interface { + Error + + // The status code of the HTTP response. + StatusCode() int + + // The request ID returned by the service for a request failure. This will + // be empty if no request ID is available such as the request failed due + // to a connection error. + RequestID() string +} + +// NewRequestFailure returns a new request error wrapper for the given Error +// provided. +func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure { + return newRequestError(err, statusCode, reqID) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/types.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/types.go new file mode 100644 index 000000000..0202a008f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/awserr/types.go @@ -0,0 +1,194 @@ +package awserr + +import "fmt" + +// SprintError returns a string of the formatted error code. +// +// Both extra and origErr are optional. If they are included their lines +// will be added, but if they are not included their lines will be ignored. +func SprintError(code, message, extra string, origErr error) string { + msg := fmt.Sprintf("%s: %s", code, message) + if extra != "" { + msg = fmt.Sprintf("%s\n\t%s", msg, extra) + } + if origErr != nil { + msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error()) + } + return msg +} + +// A baseError wraps the code and message which defines an error. It also +// can be used to wrap an original error object. +// +// Should be used as the root for errors satisfying the awserr.Error. Also +// for any error which does not fit into a specific error wrapper type. +type baseError struct { + // Classification of error + code string + + // Detailed information about error + message string + + // Optional original error this error is based off of. Allows building + // chained errors. + errs []error +} + +// newBaseError returns an error object for the code, message, and errors. +// +// code is a short no whitespace phrase depicting the classification of +// the error that is being created. +// +// message is the free flow string containing detailed information about the +// error. +// +// origErrs is the error objects which will be nested under the new errors to +// be returned. +func newBaseError(code, message string, origErrs []error) *baseError { + b := &baseError{ + code: code, + message: message, + errs: origErrs, + } + + return b +} + +// Error returns the string representation of the error. +// +// See ErrorWithExtra for formatting. +// +// Satisfies the error interface. +func (b baseError) Error() string { + size := len(b.errs) + if size > 0 { + return SprintError(b.code, b.message, "", errorList(b.errs)) + } + + return SprintError(b.code, b.message, "", nil) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (b baseError) String() string { + return b.Error() +} + +// Code returns the short phrase depicting the classification of the error. +func (b baseError) Code() string { + return b.code +} + +// Message returns the error details message. +func (b baseError) Message() string { + return b.message +} + +// OrigErr returns the original error if one was set. Nil is returned if no +// error was set. This only returns the first element in the list. If the full +// list is needed, use BatchedErrors. +func (b baseError) OrigErr() error { + switch len(b.errs) { + case 0: + return nil + case 1: + return b.errs[0] + default: + if err, ok := b.errs[0].(Error); ok { + return NewBatchError(err.Code(), err.Message(), b.errs[1:]) + } + return NewBatchError("BatchedErrors", + "multiple errors occurred", b.errs) + } +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (b baseError) OrigErrs() []error { + return b.errs +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError Error + +// A requestError wraps a request or service error. +// +// Composed of baseError for code, message, and original error. +type requestError struct { + awsError + statusCode int + requestID string +} + +// newRequestError returns a wrapped error with additional information for +// request status code, and service requestID. +// +// Should be used to wrap all request which involve service requests. Even if +// the request failed without a service response, but had an HTTP status code +// that may be meaningful. +// +// Also wraps original errors via the baseError. +func newRequestError(err Error, statusCode int, requestID string) *requestError { + return &requestError{ + awsError: err, + statusCode: statusCode, + requestID: requestID, + } +} + +// Error returns the string representation of the error. +// Satisfies the error interface. +func (r requestError) Error() string { + extra := fmt.Sprintf("status code: %d, request id: %s", + r.statusCode, r.requestID) + return SprintError(r.Code(), r.Message(), extra, r.OrigErr()) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (r requestError) String() string { + return r.Error() +} + +// StatusCode returns the wrapped status code for the error +func (r requestError) StatusCode() int { + return r.statusCode +} + +// RequestID returns the wrapped requestID +func (r requestError) RequestID() string { + return r.requestID +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (r requestError) OrigErrs() []error { + if b, ok := r.awsError.(BatchedErrors); ok { + return b.OrigErrs() + } + return []error{r.OrigErr()} +} + +// An error list that satisfies the golang interface +type errorList []error + +// Error returns the string representation of the error. +// +// Satisfies the error interface. +func (e errorList) Error() string { + msg := "" + // How do we want to handle the array size being zero + if size := len(e); size > 0 { + for i := 0; i < size; i++ { + msg += fmt.Sprintf("%s", e[i].Error()) + // We check the next index to see if it is within the slice. + // If it is, then we append a newline. We do this, because unit tests + // could be broken with the additional '\n' + if i+1 < size { + msg += "\n" + } + } + } + return msg +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/chain_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/chain_provider.go new file mode 100644 index 000000000..c78dfac68 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/chain_provider.go @@ -0,0 +1,75 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// A ChainProvider will search for a provider which returns credentials +// and cache that provider until Retrieve is called again. +// +// The ChainProvider provides a way of chaining multiple providers together +// which will pick the first available using priority order of the Providers +// in the list. +// +// If none of the Providers retrieve valid credentials Credentials, ChainProvider's +// Retrieve() will return the error ErrNoValidProvidersFoundInChain. +// +// If a CredentialsProvider is found which returns valid credentials Credentials ChainProvider +// will cache that CredentialsProvider for all calls to IsExpired(), until Retrieve is +// called again. +// +// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. +// In this example EnvProvider will first check if any credentials are available +// via the environment variables. If there are none ChainProvider will check +// the next CredentialsProvider in the list, EC2RoleProvider in this case. If EC2RoleProvider +// does not return any credentials ChainProvider will return the error +// ErrNoValidProvidersFoundInChain +// +// creds := aws.NewChainCredentials( +// []aws.CredentialsProvider{ +// &credentials.EnvProvider{}, +// &ec2rolecreds.EC2RoleProvider{ +// Client: ec2metadata.New(cfg), +// }, +// }) +// +// // Usage of ChainCredentials with aws.Config +// cfg := cfg.Copy() +// cfg.Credentials = creds +// svc := ec2.New(cfg) +// +type ChainProvider struct { + SafeCredentialsProvider + + Providers []CredentialsProvider +} + +// NewChainProvider returns a pointer to a new ChainProvider value wrapping +// a chain of credentials providers. +func NewChainProvider(providers []CredentialsProvider) *ChainProvider { + p := &ChainProvider{ + Providers: append([]CredentialsProvider{}, providers...), + } + p.RetrieveFn = p.retrieveFn + + return p +} + +// Retrieve returns the credentials value or error if no provider returned +// without error. +// +// If a provider is found it will be cached and any calls to IsExpired() +// will return the expired state of the cached provider. +func (c *ChainProvider) retrieveFn() (Credentials, error) { + var errs []error + for _, p := range c.Providers { + creds, err := p.Retrieve() + if err == nil { + return creds, nil + } + errs = append(errs, err) + } + + return Credentials{}, + awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/client.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/client.go new file mode 100644 index 000000000..f5b63bdeb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/client.go @@ -0,0 +1,85 @@ +package aws + +import ( + "net/http" +) + +// Metadata wraps immutable data from the Client structure. +type Metadata struct { + ServiceName string + APIVersion string + + Endpoint string + SigningName string + SigningRegion string + + JSONVersion string + TargetPrefix string +} + +// A Client implements the base client request and response handling +// used by all service clients. +type Client struct { + Metadata Metadata + + Config Config + + Region string + Credentials CredentialsProvider + EndpointResolver EndpointResolver + Handlers Handlers + Retryer Retryer + + // TODO replace with value not pointer + LogLevel LogLevel + Logger Logger + + HTTPClient *http.Client +} + +// NewClient will return a pointer to a new initialized service client. +func NewClient(cfg Config, metadata Metadata) *Client { + svc := &Client{ + Metadata: metadata, + + // TODO remove config when request reqfactored + Config: cfg, + + Region: cfg.Region, + Credentials: cfg.Credentials, + EndpointResolver: cfg.EndpointResolver, + Handlers: cfg.Handlers.Copy(), + Retryer: cfg.Retryer, + + LogLevel: cfg.LogLevel, + Logger: cfg.Logger, + } + + retryer := cfg.Retryer + if retryer == nil { + // TODO need better way of specifing default num retries + retryer = DefaultRetryer{NumMaxRetries: 3} + } + svc.Retryer = retryer + + svc.AddDebugHandlers() + + return svc +} + +// NewRequest returns a new Request pointer for the service API +// operation and parameters. +func (c *Client) NewRequest(operation *Operation, params interface{}, data interface{}) *Request { + return New(c.Config, c.Metadata, c.Handlers, c.Retryer, operation, params, data) +} + +// AddDebugHandlers injects debug logging handlers into the service to log request +// debug information. +func (c *Client) AddDebugHandlers() { + if !c.Config.LogLevel.AtLeast(LogDebug) { + return + } + + c.Handlers.Send.PushFrontNamed(NamedHandler{Name: "awssdk.client.LogRequest", Fn: logRequest}) + c.Handlers.Send.PushBackNamed(NamedHandler{Name: "awssdk.client.LogResponse", Fn: logResponse}) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/client_logger.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/client_logger.go new file mode 100644 index 000000000..f3e2e86a0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/client_logger.go @@ -0,0 +1,105 @@ +package aws + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http/httputil" +) + +const logReqMsg = `DEBUG: Request %s/%s Details: +---[ REQUEST POST-SIGN ]----------------------------- +%s +-----------------------------------------------------` + +const logReqErrMsg = `DEBUG ERROR: Request %s/%s: +---[ REQUEST DUMP ERROR ]----------------------------- +%s +------------------------------------------------------` + +type logWriter struct { + // Logger is what we will use to log the payload of a response. + Logger Logger + // buf stores the contents of what has been read + buf *bytes.Buffer +} + +func (logger *logWriter) Write(b []byte) (int, error) { + return logger.buf.Write(b) +} + +type teeReaderCloser struct { + // io.Reader will be a tee reader that is used during logging. + // This structure will read from a body and write the contents to a logger. + io.Reader + // Source is used just to close when we are done reading. + Source io.ReadCloser +} + +func (reader *teeReaderCloser) Close() error { + return reader.Source.Close() +} + +func logRequest(r *Request) { + logBody := r.Config.LogLevel.Matches(LogDebugWithHTTPBody) + dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.Metadata.ServiceName, r.Operation.Name, err)) + return + } + + if logBody { + // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's + // Body as a NoOpCloser and will not be reset after read by the HTTP + // client reader. + r.ResetBody() + } + + r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.Metadata.ServiceName, r.Operation.Name, string(dumpedBody))) +} + +const logRespMsg = `DEBUG: Response %s/%s Details: +---[ RESPONSE ]-------------------------------------- +%s +-----------------------------------------------------` + +const logRespErrMsg = `DEBUG ERROR: Response %s/%s: +---[ RESPONSE DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + +func logResponse(r *Request) { + lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)} + r.HTTPResponse.Body = &teeReaderCloser{ + Reader: io.TeeReader(r.HTTPResponse.Body, lw), + Source: r.HTTPResponse.Body, + } + + handlerFn := func(req *Request) { + body, err := httputil.DumpResponse(req.HTTPResponse, false) + if err != nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, req.Metadata.ServiceName, req.Operation.Name, err)) + return + } + + b, err := ioutil.ReadAll(lw.buf) + if err != nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, req.Metadata.ServiceName, req.Operation.Name, err)) + return + } + lw.Logger.Log(fmt.Sprintf(logRespMsg, req.Metadata.ServiceName, req.Operation.Name, string(body))) + if req.Config.LogLevel.Matches(LogDebugWithHTTPBody) { + lw.Logger.Log(string(b)) + } + } + + const handlerName = "awsdk.client.LogResponse.ResponseBody" + + r.Handlers.Unmarshal.SetBackNamed(NamedHandler{ + Name: handlerName, Fn: handlerFn, + }) + r.Handlers.UnmarshalError.SetBackNamed(NamedHandler{ + Name: handlerName, Fn: handlerFn, + }) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go new file mode 100644 index 000000000..460541500 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go @@ -0,0 +1,98 @@ +package aws + +import ( + "net/http" +) + +// A Config provides service configuration for service clients. +type Config struct { + // The region to send requests to. This parameter is required and must + // be configured globally or on a per-client basis unless otherwise + // noted. A full list of regions is found in the "Regions and Endpoints" + // document. + // + // See http://docs.aws.amazon.com/general/latest/gr/rande.html for + // information on AWS regions. + Region string + + // 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 CredentialsProvider + + // The resolver to use for looking up endpoints for AWS service clients + // to use based on region. + EndpointResolver EndpointResolver + + // The HTTP client to use when sending requests. Defaults to + // `http.DefaultClient`. + HTTPClient *http.Client + + // TODO document + Handlers Handlers + + // 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 client.DefaultRetryer will be used. + // + // When both Retryer and MaxRetries are non-nil, the former is used and + // the latter ignored. + // + // To set the Retryer field in a type-safe manner and with chaining, use + // the request.WithRetryer helper function: + // + // cfg := request.WithRetryer(aws.NewConfig(), myRetryer) + Retryer Retryer + + // An integer value representing the logging level. The default log level + // is zero (LogOff), which represents no logging. To enable logging set + // to a LogLevel Value. + LogLevel LogLevel + + // The logger writer interface to write logging messages to. Defaults to + // standard out. + Logger Logger + + // EnforceShouldRetryCheck is used in the AfterRetryHandler to always call + // ShouldRetry regardless of whether or not if request.Retryable is set. + // This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck + // is not set, then ShouldRetry will only be called if request.Retryable is nil. + // Proper handling of the request.Retryable field is important when setting this field. + // + // TODO this config field is depercated and needs removed. + EnforceShouldRetryCheck bool + + // DisableRestProtocolURICleaning will not clean the URL path when making + // rest protocol requests. Will default to false. This would only be used + // for empty directory names in s3 requests. + // + // Example: + // cfg, err := external.LoadDefaultAWSConfig() + // cfg.DisableRestProtocolURICleaning = true + // + // svc := s3.New(cfg) + // out, err := svc.GetObject(&s3.GetObjectInput { + // Bucket: aws.String("bucketname"), + // Key: aws.String("//foo//bar//moo"), + // }) + // + // TODO need better way of representing support for this concept. Not on Config. + DisableRestProtocolURICleaning bool +} + +// NewConfig returns a new Config pointer that can be chained with builder +// methods to set multiple configuration values inline without using pointers. +func NewConfig() *Config { + return &Config{} +} + +// Copy will return a shallow copy of the Config object. If any additional +// configurations are provided they will be merged into the new config returned. +func (c Config) Copy() Config { + cp := c + cp.Handlers = cp.Handlers.Copy() + + return cp +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error.go new file mode 100644 index 000000000..5fe8be630 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error.go @@ -0,0 +1,19 @@ +// +build !appengine,!plan9 + +package aws + +import ( + "net" + "os" + "syscall" +) + +func isErrConnectionReset(err error) bool { + if opErr, ok := err.(*net.OpError); ok { + if sysErr, ok := opErr.Err.(*os.SyscallError); ok { + return sysErr.Err == syscall.ECONNRESET + } + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error_other.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error_other.go new file mode 100644 index 000000000..ca8422eff --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/connection_reset_error_other.go @@ -0,0 +1,11 @@ +// +build appengine plan9 + +package aws + +import ( + "strings" +) + +func isErrConnectionReset(err error) bool { + return strings.Contains(err.Error(), "connection reset") +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/context.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/context.go new file mode 100644 index 000000000..79f426853 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/context.go @@ -0,0 +1,71 @@ +package aws + +import ( + "time" +) + +// Context is an copy of the Go v1.7 stdlib's context.Context interface. +// It is represented as a SDK interface to enable you to use the "WithContext" +// API methods with Go v1.6 and a Context type such as golang.org/x/net/context. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + Value(key interface{}) interface{} +} + +// BackgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func BackgroundContext() Context { + return backgroundCtx +} + +// SleepWithContext will wait for the timer duration to expire, or the context +// is canceled. Which ever happens first. If the context is canceled the Context's +// error will be returned. +// +// Expects Context to always return a non-nil error if the Done channel is closed. +func SleepWithContext(ctx Context, dur time.Duration) error { + t := time.NewTimer(dur) + defer t.Stop() + + select { + case <-t.C: + break + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_6.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_6.go new file mode 100644 index 000000000..8fdda5303 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_6.go @@ -0,0 +1,41 @@ +// +build !go1.7 + +package aws + +import "time" + +// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to +// provide a 1.6 and 1.5 safe version of context that is compatible with Go +// 1.7's Context. +// +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case backgroundCtx: + return "aws.BackgroundContext" + } + return "unknown empty Context" +} + +var ( + backgroundCtx = new(emptyCtx) +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_7.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_7.go new file mode 100644 index 000000000..064f75c92 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/context_1_7.go @@ -0,0 +1,9 @@ +// +build go1.7 + +package aws + +import "context" + +var ( + backgroundCtx = context.Background() +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/convert_types.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/convert_types.go new file mode 100644 index 000000000..ff5d58e06 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/convert_types.go @@ -0,0 +1,387 @@ +package aws + +import "time" + +// String returns a pointer to the string value passed in. +func String(v string) *string { + return &v +} + +// StringValue returns the value of the string pointer passed in or +// "" if the pointer is nil. +func StringValue(v *string) string { + if v != nil { + return *v + } + return "" +} + +// StringSlice converts a slice of string values into a slice of +// string pointers +func StringSlice(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringValueSlice converts a slice of string pointers into a slice of +// string values +func StringValueSlice(src []*string) []string { + dst := make([]string, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// StringMap converts a string map of string values into a string +// map of string pointers +func StringMap(src map[string]string) map[string]*string { + dst := make(map[string]*string) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// StringValueMap converts a string map of string pointers into a string +// map of string values +func StringValueMap(src map[string]*string) map[string]string { + dst := make(map[string]string) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Bool returns a pointer to the bool value passed in. +func Bool(v bool) *bool { + return &v +} + +// BoolValue returns the value of the bool pointer passed in or +// false if the pointer is nil. +func BoolValue(v *bool) bool { + if v != nil { + return *v + } + return false +} + +// BoolSlice converts a slice of bool values into a slice of +// bool pointers +func BoolSlice(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolValueSlice converts a slice of bool pointers into a slice of +// bool values +func BoolValueSlice(src []*bool) []bool { + dst := make([]bool, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// BoolMap converts a string map of bool values into a string +// map of bool pointers +func BoolMap(src map[string]bool) map[string]*bool { + dst := make(map[string]*bool) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// BoolValueMap converts a string map of bool pointers into a string +// map of bool values +func BoolValueMap(src map[string]*bool) map[string]bool { + dst := make(map[string]bool) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int returns a pointer to the int value passed in. +func Int(v int) *int { + return &v +} + +// IntValue returns the value of the int pointer passed in or +// 0 if the pointer is nil. +func IntValue(v *int) int { + if v != nil { + return *v + } + return 0 +} + +// IntSlice converts a slice of int values into a slice of +// int pointers +func IntSlice(src []int) []*int { + dst := make([]*int, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// IntValueSlice converts a slice of int pointers into a slice of +// int values +func IntValueSlice(src []*int) []int { + dst := make([]int, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// IntMap converts a string map of int values into a string +// map of int pointers +func IntMap(src map[string]int) map[string]*int { + dst := make(map[string]*int) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// IntValueMap converts a string map of int pointers into a string +// map of int values +func IntValueMap(src map[string]*int) map[string]int { + dst := make(map[string]int) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int64 returns a pointer to the int64 value passed in. +func Int64(v int64) *int64 { + return &v +} + +// Int64Value returns the value of the int64 pointer passed in or +// 0 if the pointer is nil. +func Int64Value(v *int64) int64 { + if v != nil { + return *v + } + return 0 +} + +// Int64Slice converts a slice of int64 values into a slice of +// int64 pointers +func Int64Slice(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64ValueSlice converts a slice of int64 pointers into a slice of +// int64 values +func Int64ValueSlice(src []*int64) []int64 { + dst := make([]int64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int64Map converts a string map of int64 values into a string +// map of int64 pointers +func Int64Map(src map[string]int64) map[string]*int64 { + dst := make(map[string]*int64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int64ValueMap converts a string map of int64 pointers into a string +// map of int64 values +func Int64ValueMap(src map[string]*int64) map[string]int64 { + dst := make(map[string]int64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float64 returns a pointer to the float64 value passed in. +func Float64(v float64) *float64 { + return &v +} + +// Float64Value returns the value of the float64 pointer passed in or +// 0 if the pointer is nil. +func Float64Value(v *float64) float64 { + if v != nil { + return *v + } + return 0 +} + +// Float64Slice converts a slice of float64 values into a slice of +// float64 pointers +func Float64Slice(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64ValueSlice converts a slice of float64 pointers into a slice of +// float64 values +func Float64ValueSlice(src []*float64) []float64 { + dst := make([]float64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float64Map converts a string map of float64 values into a string +// map of float64 pointers +func Float64Map(src map[string]float64) map[string]*float64 { + dst := make(map[string]*float64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float64ValueMap converts a string map of float64 pointers into a string +// map of float64 values +func Float64ValueMap(src map[string]*float64) map[string]float64 { + dst := make(map[string]float64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Time returns a pointer to the time.Time value passed in. +func Time(v time.Time) *time.Time { + return &v +} + +// TimeValue returns the value of the time.Time pointer passed in or +// time.Time{} if the pointer is nil. +func TimeValue(v *time.Time) time.Time { + if v != nil { + return *v + } + return time.Time{} +} + +// SecondsTimeValue converts an int64 pointer to a time.Time value +// representing seconds since Epoch or time.Time{} if the pointer is nil. +func SecondsTimeValue(v *int64) time.Time { + if v != nil { + return time.Unix((*v / 1000), 0) + } + return time.Time{} +} + +// MillisecondsTimeValue converts an int64 pointer to a time.Time value +// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil. +func MillisecondsTimeValue(v *int64) time.Time { + if v != nil { + return time.Unix(0, (*v * 1000000)) + } + return time.Time{} +} + +// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC". +// The result is undefined if the Unix time cannot be represented by an int64. +// Which includes calling TimeUnixMilli on a zero Time is undefined. +// +// This utility is useful for service API's such as CloudWatch Logs which require +// their unix time values to be in milliseconds. +// +// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information. +func TimeUnixMilli(t time.Time) int64 { + return t.UnixNano() / int64(time.Millisecond/time.Nanosecond) +} + +// TimeSlice converts a slice of time.Time values into a slice of +// time.Time pointers +func TimeSlice(src []time.Time) []*time.Time { + dst := make([]*time.Time, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// TimeValueSlice converts a slice of time.Time pointers into a slice of +// time.Time values +func TimeValueSlice(src []*time.Time) []time.Time { + dst := make([]time.Time, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// TimeMap converts a string map of time.Time values into a string +// map of time.Time pointers +func TimeMap(src map[string]time.Time) map[string]*time.Time { + dst := make(map[string]*time.Time) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// TimeValueMap converts a string map of time.Time pointers into a string +// map of time.Time values +func TimeValueMap(src map[string]*time.Time) map[string]time.Time { + dst := make(map[string]time.Time) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go new file mode 100644 index 000000000..db93f59d0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go @@ -0,0 +1,138 @@ +package aws + +import ( + "math" + "sync" + "sync/atomic" + "time" + + "github.com/aws/aws-sdk-go-v2/internal/sdk" +) + +// NeverExpire is the time identifier used when a credential provider's +// credentials will not expire. This is used in cases where a non-expiring +// provider type cannot be used. +var NeverExpire = time.Unix(math.MaxInt64, 0) + +// AnonymousCredentials is an empty CredentialProvider that can be used as +// dummy placeholder credentials for requests that do not need signed. +// +// This credentials can be used to configure a service to not sign requests +// when making service API calls. For example, when accessing public +// s3 buckets. +// +// s3Cfg := cfg.Copy() +// s3cfg.Credentials = AnonymousCredentials +// +// svc := s3.New(s3Cfg) +var AnonymousCredentials = StaticCredentialsProvider{ + Value: Credentials{Source: "AnonymousCredentials"}, +} + +// An Expiration provides wrapper around time with expiration related methods. +type Expiration time.Time + +// Expired returns if the time has expired. + +// A Credentials is the AWS credentials value for individual credential fields. +type Credentials struct { + // AWS Access key ID + AccessKeyID string + + // AWS Secret Access Key + SecretAccessKey string + + // AWS Session Token + SessionToken string + + // Source of the credentials + Source string + + // Time the credentials will expire. + CanExpire bool + Expires time.Time +} + +// Expired returns if the credetials have expired. +func (v Credentials) Expired() bool { + if v.CanExpire { + return !v.Expires.After(sdk.NowTime()) + } + + return false +} + +// HasKeys returns if the credentials keys are set. +func (v Credentials) HasKeys() bool { + return len(v.AccessKeyID) > 0 && len(v.SecretAccessKey) > 0 +} + +// A CredentialsProvider is the interface for any component which will provide credentials +// Credentials. A CredentialsProvider is required to manage its own Expired state, and what to +// be expired means. +// +// The CredentialsProvider should not need to implement its own mutexes, because +// that will be managed by CredentialsLoader. +type CredentialsProvider interface { + // Retrieve returns nil if it successfully retrieved the value. + // Error is returned if the value were not obtainable, or empty. + Retrieve() (Credentials, error) + + // TODO should Retrieve take a context? +} + +// SafeCredentialsProvider provides caching and concurrency safe credentials +// retrieval via the RetrieveFn. +type SafeCredentialsProvider struct { + RetrieveFn func() (Credentials, error) + + creds atomic.Value + m sync.Mutex +} + +// Retrieve returns the credentials. If the credentials have already been +// retrieved, and not expired the cached credentials will be returned. If the +// credentails have not been retrieved yet, or expired RetrieveFn will be called. +// +// Retruns and error if RetrieveFn returns an error. +func (p *SafeCredentialsProvider) Retrieve() (Credentials, error) { + if creds := p.getCreds(); creds != nil { + return *creds, nil + } + + p.m.Lock() + defer p.m.Unlock() + + // Make sure another goroutine didn't already update the credentials. + if creds := p.getCreds(); creds != nil { + return *creds, nil + } + + creds, err := p.RetrieveFn() + if err != nil { + return Credentials{}, err + } + p.creds.Store(&creds) + + return creds, nil +} + +func (p *SafeCredentialsProvider) getCreds() *Credentials { + v := p.creds.Load() + if v == nil { + return nil + } + + c := v.(*Credentials) + if c != nil && c.HasKeys() && !c.Expired() { + return c + } + + return nil +} + +// Invalidate will invalidate the cached credentials. The next call to Retrieve +// will cause RetrieveFn to be called. +func (p *SafeCredentialsProvider) Invalidate() { + p.creds.Store((*Credentials)(nil)) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/default_retryer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/default_retryer.go new file mode 100644 index 000000000..a08af806d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/default_retryer.go @@ -0,0 +1,136 @@ +package aws + +import ( + "math/rand" + "strconv" + "sync" + "time" +) + +// DefaultRetryer implements basic retry logic using exponential backoff for +// most services. If you want to implement custom retry logic, implement the +// Retryer interface or create a structure type that composes this +// struct and override the specific methods. For example, to override only +// the MaxRetries method: +// +// type retryer struct { +// client.DefaultRetryer +// } +// +// // This implementation always has 100 max retries +// func (d retryer) MaxRetries() int { return 100 } +type DefaultRetryer struct { + NumMaxRetries int +} + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API +func (d DefaultRetryer) MaxRetries() int { + return d.NumMaxRetries +} + +var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) + +// RetryRules returns the delay duration before retrying this request again +func (d DefaultRetryer) RetryRules(r *Request) time.Duration { + // Set the upper limit of delay in retrying at ~five minutes + minTime := 30 + throttle := d.shouldThrottle(r) + if throttle { + if delay, ok := getRetryDelay(r); ok { + return delay + } + + minTime = 500 + } + + retryCount := r.RetryCount + if retryCount > 13 { + retryCount = 13 + } else if throttle && retryCount > 8 { + retryCount = 8 + } + + delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime) + return time.Duration(delay) * time.Millisecond +} + +// ShouldRetry returns true if the request should be retried. +func (d DefaultRetryer) ShouldRetry(r *Request) bool { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable != nil { + return *r.Retryable + } + + if r.HTTPResponse.StatusCode >= 500 { + return true + } + return r.IsErrorRetryable() || d.shouldThrottle(r) +} + +// ShouldThrottle returns true if the request should be throttled. +func (d DefaultRetryer) shouldThrottle(r *Request) bool { + switch r.HTTPResponse.StatusCode { + case 429: + case 502: + case 503: + case 504: + default: + return r.IsErrorThrottle() + } + + return true +} + +// This will look in the Retry-After header, RFC 7231, for how long +// it will wait before attempting another request +func getRetryDelay(r *Request) (time.Duration, bool) { + if !canUseRetryAfterHeader(r) { + return 0, false + } + + delayStr := r.HTTPResponse.Header.Get("Retry-After") + if len(delayStr) == 0 { + return 0, false + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + return 0, false + } + + return time.Duration(delay) * time.Second, true +} + +// Will look at the status code to see if the retry header pertains to +// the status code. +func canUseRetryAfterHeader(r *Request) bool { + switch r.HTTPResponse.StatusCode { + case 429: + case 503: + default: + return false + } + + return true +} + +// lockedSource is a thread-safe implementation of rand.Source +type lockedSource struct { + lk sync.Mutex + src rand.Source +} + +func (r *lockedSource) Int63() (n int64) { + r.lk.Lock() + n = r.src.Int63() + r.lk.Unlock() + return +} + +func (r *lockedSource) Seed(seed int64) { + r.lk.Lock() + r.src.Seed(seed) + r.lk.Unlock() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go new file mode 100644 index 000000000..fb92d42a9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go @@ -0,0 +1,92 @@ +// Package defaults is a collection of helpers to retrieve the SDK's default +// configuration and handlers. +// +// Generally this package shouldn't be used directly, but external.Config +// instead. This package is useful when you need to reset the defaults +// of a service client to the SDK defaults before setting +// additional parameters. +package defaults + +import ( + "log" + "net/http" + "os" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/endpoints" +) + +// Logger returns a Logger which will write log messages to stdout, and +// use same formatting runes as the stdlib log.Logger +func Logger() aws.Logger { + return &defaultLogger{ + logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +// A defaultLogger provides a minimalistic logger satisfying the Logger interface. +type defaultLogger struct { + logger *log.Logger +} + +// Log logs the parameters to the stdlib logger. See log.Println. +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} + +// Config returns the default configuration without credentials. +// To retrieve a config with credentials also included use +// `defaults.Get().Config` instead. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the configuration of an +// existing service client. +func Config() aws.Config { + return aws.Config{ + EndpointResolver: endpoints.NewDefaultResolver(), + Credentials: aws.AnonymousCredentials, + HTTPClient: HTTPClient(), + Logger: Logger(), + Handlers: Handlers(), + } +} + +// HTTPClient will return a new HTTP Client configured for the SDK. +// +// Does not use http.DefaultClient nor http.DefaultTransport. +func HTTPClient() *http.Client { + return &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + MaxIdleConns: 100, + MaxIdleConnsPerHost: 10, + IdleConnTimeout: 30 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 5 * time.Second, + }, + } +} + +// Handlers returns the default request handlers. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the request handlers of an +// existing service client. +func Handlers() aws.Handlers { + var handlers aws.Handlers + + handlers.Validate.PushBackNamed(ValidateEndpointHandler) + handlers.Validate.PushBackNamed(ValidateParametersHandler) + handlers.Validate.AfterEachFn = aws.HandlerListStopOnError + handlers.Build.PushBackNamed(SDKVersionUserAgentHandler) + handlers.Build.PushBackNamed(AddHostExecEnvUserAgentHander) + handlers.Build.AfterEachFn = aws.HandlerListStopOnError + handlers.Sign.PushBackNamed(BuildContentLengthHandler) + handlers.Send.PushBackNamed(ValidateReqSigHandler) + handlers.Send.PushBackNamed(SendHandler) + handlers.AfterRetry.PushBackNamed(AfterRetryHandler) + handlers.ValidateResponse.PushBackNamed(ValidateResponseHandler) + + return handlers +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/handlers.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/handlers.go new file mode 100644 index 000000000..cebd006ba --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/handlers.go @@ -0,0 +1,229 @@ +package defaults + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "regexp" + "strconv" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/internal/sdk" +) + +// Interface for matching types which also have a Len method. +type lener interface { + Len() int +} + +// BuildContentLengthHandler builds the content length of a request based on the body, +// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable +// to determine request body length and no "Content-Length" was specified it will panic. +// +// The Content-Length will only be added to the request if the length of the body +// is greater than 0. If the body is empty or the current `Content-Length` +// header is <= 0, the header will also be stripped. +var BuildContentLengthHandler = aws.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *aws.Request) { + var length int64 + + if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" { + length, _ = strconv.ParseInt(slength, 10, 64) + } else { + switch body := r.Body.(type) { + case nil: + length = 0 + case lener: + length = int64(body.Len()) + case io.Seeker: + r.BodyStart, _ = body.Seek(0, 1) + end, _ := body.Seek(0, 2) + body.Seek(r.BodyStart, 0) // make sure to seek back to original location + length = end - r.BodyStart + default: + panic("Cannot get length of body, must provide `ContentLength`") + } + } + + if length > 0 { + r.HTTPRequest.ContentLength = length + r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length)) + } else { + r.HTTPRequest.ContentLength = 0 + r.HTTPRequest.Header.Del("Content-Length") + } +}} + +var reStatusCode = regexp.MustCompile(`^(\d{3})`) + +// ValidateReqSigHandler is a request handler to ensure that the request's +// signature doesn't expire before it is sent. This can happen when a request +// is built and signed significantly before it is sent. Or significant delays +// occur when retrying requests that would cause the signature to expire. +var ValidateReqSigHandler = aws.NamedHandler{ + Name: "core.ValidateReqSigHandler", + Fn: func(r *aws.Request) { + // Unsigned requests are not signed + if r.Config.Credentials == aws.AnonymousCredentials { + return + } + + signedTime := r.Time + if !r.LastSignedAt.IsZero() { + signedTime = r.LastSignedAt + } + + // 10 minutes to allow for some clock skew/delays in transmission. + // Would be improved with aws/aws-sdk-go#423 + if signedTime.Add(10 * time.Minute).After(time.Now()) { + return + } + + r.Sign() + }, +} + +// SendHandler is a request handler to send service request using HTTP client. +var SendHandler = aws.NamedHandler{ + Name: "core.SendHandler", + Fn: func(r *aws.Request) { + sender := sendFollowRedirects + if r.DisableFollowRedirects { + sender = sendWithoutFollowRedirects + } + + if aws.NoBody == r.HTTPRequest.Body { + // Strip off the request body if the NoBody reader was used as a + // place holder for a request body. This prevents the SDK from + // making requests with a request body when it would be invalid + // to do so. + // + // Use a shallow copy of the http.Request to ensure the race condition + // of transport on Body will not trigger + reqOrig, reqCopy := r.HTTPRequest, *r.HTTPRequest + reqCopy.Body = nil + r.HTTPRequest = &reqCopy + defer func() { + r.HTTPRequest = reqOrig + }() + } + + var err error + r.HTTPResponse, err = sender(r) + if err != nil { + handleSendError(r, err) + } + }, +} + +func sendFollowRedirects(r *aws.Request) (*http.Response, error) { + return r.Config.HTTPClient.Do(r.HTTPRequest) +} + +func sendWithoutFollowRedirects(r *aws.Request) (*http.Response, error) { + transport := r.Config.HTTPClient.Transport + if transport == nil { + transport = http.DefaultTransport + } + + return transport.RoundTrip(r.HTTPRequest) +} + +func handleSendError(r *aws.Request, err error) { + // Prevent leaking if an HTTPResponse was returned. Clean up + // the body. + if r.HTTPResponse != nil { + r.HTTPResponse.Body.Close() + } + // Capture the case where url.Error is returned for error processing + // response. e.g. 301 without location header comes back as string + // error and r.HTTPResponse is nil. Other URL redirect errors will + // comeback in a similar method. + if e, ok := err.(*url.Error); ok && e.Err != nil { + if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { + code, _ := strconv.ParseInt(s[1], 10, 64) + r.HTTPResponse = &http.Response{ + StatusCode: int(code), + Status: http.StatusText(int(code)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + return + } + } + if r.HTTPResponse == nil { + // Add a dummy request response object to ensure the HTTPResponse + // value is consistent. + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + } + // Catch all other request errors. + r.Error = awserr.New("RequestError", "send request failed", err) + r.Retryable = aws.Bool(true) // network errors are retryable + + // Override the error with a context canceled error, if that was canceled. + ctx := r.Context() + select { + case <-ctx.Done(): + r.Error = awserr.New(aws.ErrCodeRequestCanceled, + "request context canceled", ctx.Err()) + r.Retryable = aws.Bool(false) + default: + } +} + +// ValidateResponseHandler is a request handler to validate service response. +var ValidateResponseHandler = aws.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *aws.Request) { + if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 { + // this may be replaced by an UnmarshalError handler + r.Error = awserr.New("UnknownError", "unknown error", nil) + } +}} + +// AfterRetryHandler performs final checks to determine if the request should +// be retried and how long to delay. +var AfterRetryHandler = aws.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *aws.Request) { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable == nil || r.Config.EnforceShouldRetryCheck { + r.Retryable = aws.Bool(r.ShouldRetry(r)) + } + + if r.WillRetry() { + r.RetryDelay = r.RetryRules(r) + + if err := sdk.SleepWithContext(r.Context(), r.RetryDelay); err != nil { + r.Error = awserr.New(aws.ErrCodeRequestCanceled, + "request context canceled", err) + r.Retryable = aws.Bool(false) + return + } + + // when the expired token exception occurs the credentials + // need to be expired locally so that the next request to + // get credentials will trigger a credentials refresh. + if p, ok := r.Config.Credentials.(sdk.Invalidator); ok && r.IsErrorExpired() { + p.Invalidate() + } + + r.RetryCount++ + r.Error = nil + } +}} + +// ValidateEndpointHandler is a request handler to validate a request had the +// appropriate Region and Endpoint set. Will set r.Error if the endpoint or +// region is not valid. +var ValidateEndpointHandler = aws.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *aws.Request) { + if r.Metadata.SigningRegion == "" && r.Config.Region == "" { + r.Error = aws.ErrMissingRegion + } else if r.Metadata.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +}} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/param_validator.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/param_validator.go new file mode 100644 index 000000000..cbac627a5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/param_validator.go @@ -0,0 +1,19 @@ +package defaults + +import ( + "github.com/aws/aws-sdk-go-v2/aws" +) + +// ValidateParametersHandler is a request handler to validate the input parameters. +// Validating parameters only has meaning if done prior to the request being sent. +var ValidateParametersHandler = aws.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *aws.Request) { + if !r.ParamsFilled() { + return + } + + if v, ok := r.Params.(aws.Validator); ok { + if err := v.Validate(); err != nil { + r.Error = err + } + } +}} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/user_agent_handlers.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/user_agent_handlers.go new file mode 100644 index 000000000..c911f0660 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/user_agent_handlers.go @@ -0,0 +1,36 @@ +package defaults + +import ( + "os" + "runtime" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +// SDKVersionUserAgentHandler is a request handler for adding the SDK Version +// to the user agent. +var SDKVersionUserAgentHandler = aws.NamedHandler{ + Name: "core.SDKVersionUserAgentHandler", + Fn: aws.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion, + runtime.Version(), runtime.GOOS, runtime.GOARCH), +} + +const execEnvVar = `AWS_EXECUTION_ENV` +const execEnvUAKey = `exec_env` + +// AddHostExecEnvUserAgentHander is a request handler appending the SDK's +// execution environment to the user agent. +// +// If the environment variable AWS_EXECUTION_ENV is set, its value will be +// appended to the user agent string. +var AddHostExecEnvUserAgentHander = aws.NamedHandler{ + Name: "core.AddHostExecEnvUserAgentHander", + Fn: func(r *aws.Request) { + v := os.Getenv(execEnvVar) + if len(v) == 0 { + return + } + + aws.AddToUserAgent(r, execEnvUAKey+"/"+v) + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go new file mode 100644 index 000000000..4fcb61618 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go @@ -0,0 +1,56 @@ +// Package aws provides the core SDK's utilities and shared types. Use this package's +// utilities to simplify setting and reading API operations parameters. +// +// Value and Pointer Conversion Utilities +// +// This package includes a helper conversion utility for each scalar type the SDK's +// API use. These utilities make getting a pointer of the scalar, and dereferencing +// a pointer easier. +// +// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value. +// The Pointer to value will safely dereference the pointer and return its value. +// If the pointer was nil, the scalar's zero value will be returned. +// +// The value to pointer functions will be named after the scalar type. So get a +// *string from a string value use the "String" function. This makes it easy to +// to get pointer of a literal string value, because getting the address of a +// literal requires assigning the value to a variable first. +// +// var strPtr *string +// +// // Without the SDK's conversion functions +// str := "my string" +// strPtr = &str +// +// // With the SDK's conversion functions +// strPtr = aws.String("my string") +// +// // Convert *string to string value +// str = aws.StringValue(strPtr) +// +// In addition to scalars the aws package also includes conversion utilities for +// map and slice for commonly types used in API parameters. The map and slice +// conversion functions use similar naming pattern as the scalar conversion +// functions. +// +// var strPtrs []*string +// var strs []string = []string{"Go", "Gophers", "Go"} +// +// // Convert []string to []*string +// strPtrs = aws.StringSlice(strs) +// +// // Convert []*string to []string +// strs = aws.StringValueSlice(strPtrs) +// +// SDK Default HTTP Client +// +// The SDK will use the http.DefaultClient if a HTTP client is not provided to +// the SDK's Session, or service client constructor. This means that if the +// http.DefaultClient is modified by other components of your application the +// modifications will be picked up by the SDK as well. +// +// In some cases this might be intended, but it is a better practice to create +// a custom HTTP Client to share explicitly through your application. You can +// configure the SDK to use the custom HTTP Client by setting the HTTPClient +// value of the SDK's Config type when creating a Session or service client. +package aws diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/api.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/api.go new file mode 100644 index 000000000..3233acd0d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/api.go @@ -0,0 +1,162 @@ +package ec2metadata + +import ( + "encoding/json" + "fmt" + "net/http" + "path" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// GetMetadata uses the path provided to request information from the EC2 +// instance metdata service. The content will be returned as a string, or +// error if the request failed. +func (c *EC2Metadata) GetMetadata(p string) (string, error) { + op := &aws.Operation{ + Name: "GetMetadata", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "meta-data", p), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + + return output.Content, req.Send() +} + +// GetUserData returns the userdata that was configured for the service. If +// there is no user-data setup for the EC2 instance a "NotFoundError" error +// code will be returned. +func (c *EC2Metadata) GetUserData() (string, error) { + op := &aws.Operation{ + Name: "GetUserData", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "user-data"), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + req.Handlers.UnmarshalError.PushBack(func(r *aws.Request) { + if r.HTTPResponse.StatusCode == http.StatusNotFound { + r.Error = awserr.New("NotFoundError", "user-data not found", r.Error) + } + }) + + return output.Content, req.Send() +} + +// GetDynamicData uses the path provided to request information from the EC2 +// instance metadata service for dynamic data. The content will be returned +// as a string, or error if the request failed. +func (c *EC2Metadata) GetDynamicData(p string) (string, error) { + op := &aws.Operation{ + Name: "GetDynamicData", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "dynamic", p), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + + return output.Content, req.Send() +} + +// GetInstanceIdentityDocument retrieves an identity document describing an +// instance. Error is returned if the request fails or is unable to parse +// the response. +func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) { + resp, err := c.GetDynamicData("instance-identity/document") + if err != nil { + return EC2InstanceIdentityDocument{}, + awserr.New("EC2MetadataRequestError", + "failed to get EC2 instance identity document", err) + } + + doc := EC2InstanceIdentityDocument{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil { + return EC2InstanceIdentityDocument{}, + awserr.New("SerializationError", + "failed to decode EC2 instance identity document", err) + } + + return doc, nil +} + +// IAMInfo retrieves IAM info from the metadata API +func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) { + resp, err := c.GetMetadata("iam/info") + if err != nil { + return EC2IAMInfo{}, + awserr.New("EC2MetadataRequestError", + "failed to get EC2 IAM info", err) + } + + info := EC2IAMInfo{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil { + return EC2IAMInfo{}, + awserr.New("SerializationError", + "failed to decode EC2 IAM info", err) + } + + if info.Code != "Success" { + errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code) + return EC2IAMInfo{}, + awserr.New("EC2MetadataError", errMsg, nil) + } + + return info, nil +} + +// Region returns the region the instance is running in. +func (c *EC2Metadata) Region() (string, error) { + resp, err := c.GetMetadata("placement/availability-zone") + if err != nil { + return "", err + } + + // returns region without the suffix. Eg: us-west-2a becomes us-west-2 + return resp[:len(resp)-1], nil +} + +// Available returns if the application has access to the EC2 Metadata service. +// Can be used to determine if application is running within an EC2 Instance and +// the metadata service is available. +func (c *EC2Metadata) Available() bool { + if _, err := c.GetMetadata("instance-id"); err != nil { + return false + } + + return true +} + +// An EC2IAMInfo provides the shape for unmarshaling +// an IAM info from the metadata API +type EC2IAMInfo struct { + Code string + LastUpdated time.Time + InstanceProfileArn string + InstanceProfileID string +} + +// An EC2InstanceIdentityDocument provides the shape for unmarshaling +// an instance identity document +type EC2InstanceIdentityDocument struct { + DevpayProductCodes []string `json:"devpayProductCodes"` + AvailabilityZone string `json:"availabilityZone"` + PrivateIP string `json:"privateIp"` + Version string `json:"version"` + Region string `json:"region"` + InstanceID string `json:"instanceId"` + BillingProducts []string `json:"billingProducts"` + InstanceType string `json:"instanceType"` + AccountID string `json:"accountId"` + PendingTime time.Time `json:"pendingTime"` + ImageID string `json:"imageId"` + KernelID string `json:"kernelId"` + RamdiskID string `json:"ramdiskId"` + Architecture string `json:"architecture"` +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/service.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/service.go new file mode 100644 index 000000000..5c0a7e69c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2metadata/service.go @@ -0,0 +1,110 @@ +// Package ec2metadata provides the client for making API calls to the +// EC2 Metadata service. +// +// This package's client can be disabled completely by setting the environment +// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to +// true instructs the SDK to disable the EC2 Metadata client. The client cannot +// be used while the environemnt variable is set to true, (case insensitive). +package ec2metadata + +import ( + "bytes" + "errors" + "io" + "net/http" + "os" + "strings" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/aws/defaults" +) + +// ServiceName is the name of the service. +const ServiceName = "ec2metadata" +const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED" + +// A EC2Metadata is an EC2 Metadata service Client. +type EC2Metadata struct { + *aws.Client +} + +// New creates a new instance of the EC2Metadata client with a Config. +// This client is safe to use across multiple goroutines. +// +// Example: +// // Create a EC2Metadata client from just a config. +// svc := ec2metadata.New(cfg) +func New(config aws.Config) *EC2Metadata { + svc := &EC2Metadata{ + Client: aws.NewClient( + config, + aws.Metadata{ + ServiceName: ServiceName, + APIVersion: "latest", + }, + ), + } + + svc.Handlers.Unmarshal.PushBack(unmarshalHandler) + svc.Handlers.UnmarshalError.PushBack(unmarshalError) + svc.Handlers.Validate.Clear() + svc.Handlers.Validate.PushBack(validateEndpointHandler) + + // Disable the EC2 Metadata service if the environment variable is set. + // This shortcirctes the service's functionality to always fail to send + // requests. + if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" { + svc.Handlers.Send.SwapNamed(aws.NamedHandler{ + Name: defaults.SendHandler.Name, + Fn: func(r *aws.Request) { + r.Error = awserr.New( + aws.ErrCodeRequestCanceled, + "EC2 IMDS access disabled via "+disableServiceEnvVar+" env var", + nil) + }, + }) + } + + return svc +} + +func httpClientZero(c *http.Client) bool { + return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0) +} + +type metadataOutput struct { + Content string +} + +func unmarshalHandler(r *aws.Request) { + defer r.HTTPResponse.Body.Close() + b := &bytes.Buffer{} + if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { + r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) + return + } + + if data, ok := r.Data.(*metadataOutput); ok { + data.Content = b.String() + } +} + +func unmarshalError(r *aws.Request) { + defer r.HTTPResponse.Body.Close() + b := &bytes.Buffer{} + if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { + r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) + return + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())) +} + +func validateEndpointHandler(r *aws.Request) { + if r.Metadata.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2rolecreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2rolecreds/provider.go new file mode 100644 index 000000000..b8290bf29 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/ec2rolecreds/provider.go @@ -0,0 +1,155 @@ +package ec2rolecreds + +import ( + "bufio" + "encoding/json" + "fmt" + "path" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/aws/ec2metadata" +) + +// ProviderName provides a name of EC2Role provider +const ProviderName = "EC2RoleProvider" + +// A Provider retrieves credentials from the EC2 service, and keeps track if +// those credentials are expired. +// +// The NewProvider function must be used to create the Provider. +// +// p := &ec2rolecreds.NewProvider(ec2metadata.New(cfg)) +// +// // Expire the credentials 10 minutes before IAM states they should. Proactivily +// // refreshing the credentials. +// p.ExpiryWindow = 10 * time.Minute +type Provider struct { + aws.SafeCredentialsProvider + + // Required EC2Metadata client to use when connecting to EC2 metadata service. + Client *ec2metadata.EC2Metadata + + // 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 +} + +// NewProvider returns an initialized Provider value configured to retrieve +// credentials from EC2 Instance Metadata service. +func NewProvider(client *ec2metadata.EC2Metadata) *Provider { + p := &Provider{ + Client: client, + } + p.RetrieveFn = p.retrieveFn + + return p +} + +// Retrieve retrieves credentials from the EC2 service. +// Error will be returned if the request fails, or unable to extract +// the desired credentials. +func (p *Provider) retrieveFn() (aws.Credentials, error) { + credsList, err := requestCredList(p.Client) + if err != nil { + return aws.Credentials{}, err + } + + if len(credsList) == 0 { + return aws.Credentials{}, + awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) + } + credsName := credsList[0] + + roleCreds, err := requestCred(p.Client, credsName) + if err != nil { + return aws.Credentials{}, err + } + + creds := aws.Credentials{ + AccessKeyID: roleCreds.AccessKeyID, + SecretAccessKey: roleCreds.SecretAccessKey, + SessionToken: roleCreds.Token, + Source: ProviderName, + + CanExpire: true, + Expires: roleCreds.Expiration.Add(-p.ExpiryWindow), + } + + return creds, nil +} + +// A ec2RoleCredRespBody provides the shape for unmarshaling credential +// request responses. +type ec2RoleCredRespBody struct { + // Success State + Expiration time.Time + AccessKeyID string + SecretAccessKey string + Token string + + // Error state + Code string + Message string +} + +const iamSecurityCredsPath = "/iam/security-credentials" + +// requestCredList requests a list of credentials from the EC2 service. +// If there are no credentials, or there is an error making or receiving the request +func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) { + resp, err := client.GetMetadata(iamSecurityCredsPath) + if err != nil { + return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err) + } + + credsList := []string{} + s := bufio.NewScanner(strings.NewReader(resp)) + for s.Scan() { + credsList = append(credsList, s.Text()) + } + + if err := s.Err(); err != nil { + return nil, awserr.New("SerializationError", "failed to read EC2 instance role from metadata service", err) + } + + return credsList, nil +} + +// requestCred requests the credentials for a specific credentials from the EC2 service. +// +// If the credentials cannot be found, or there is an error reading the response +// and error will be returned. +func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) { + resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName)) + if err != nil { + return ec2RoleCredRespBody{}, + awserr.New("EC2RoleRequestError", + fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName), + err) + } + + respCreds := ec2RoleCredRespBody{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { + return ec2RoleCredRespBody{}, + awserr.New("SerializationError", + fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName), + err) + } + + if respCreds.Code != "Success" { + // If an error code was returned something failed requesting the role. + return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil) + } + + return respCreds, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpointcreds/provider.go new file mode 100644 index 000000000..dac053477 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpointcreds/provider.go @@ -0,0 +1,167 @@ +// Package endpointcreds provides support for retrieving credentials from an +// arbitrary HTTP endpoint. +// +// The credentials endpoint Provider can receive both static and refreshable +// credentials that will expire. Credentials are static when an "Expiration" +// value is not provided in the endpoint's response. +// +// Static credentials will never expire once they have been retrieved. The format +// of the static credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// } +// +// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration +// value in the response. The format of the refreshable credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// "Token" : "AQoDY....=", +// "Expiration" : "2016-02-25T06:03:31Z" +// } +// +// Errors should be returned in the following format and only returned with 400 +// or 500 HTTP status codes. +// { +// "code": "ErrorCode", +// "message": "Helpful error message." +// } +package endpointcreds + +import ( + "encoding/json" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// ProviderName is the name of the credentials provider. +const ProviderName = `CredentialsEndpointProvider` + +// Provider satisfies the aws.CredentialsProvider interface, and is a client to +// retrieve credentials from an arbitrary endpoint. +type Provider struct { + aws.SafeCredentialsProvider + + // The AWS Client to make HTTP requests to the endpoint with. The endpoint + // the request will be made to is provided by the aws.Config's + // EndpointResolver. + Client *aws.Client + + // 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 +} + +// New returns a credentials Provider for retrieving AWS credentials +// from arbitrary endpoint. +func New(cfg aws.Config) *Provider { + p := &Provider{ + Client: aws.NewClient( + cfg, + aws.Metadata{ + ServiceName: ProviderName, + }, + ), + } + p.RetrieveFn = p.retrieveFn + + p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler) + p.Client.Handlers.UnmarshalError.PushBack(unmarshalError) + p.Client.Handlers.Validate.Clear() + p.Client.Handlers.Validate.PushBack(validateEndpointHandler) + + return p +} + +// Retrieve will attempt to request the credentials from the endpoint the Provider +// was configured for. And error will be returned if the retrieval fails. +func (p *Provider) retrieveFn() (aws.Credentials, error) { + resp, err := p.getCredentials() + if err != nil { + return aws.Credentials{}, + awserr.New("CredentialsEndpointError", "failed to load credentials", err) + } + + creds := aws.Credentials{ + AccessKeyID: resp.AccessKeyID, + SecretAccessKey: resp.SecretAccessKey, + SessionToken: resp.Token, + Source: ProviderName, + } + + if resp.Expiration != nil { + creds.CanExpire = true + creds.Expires = resp.Expiration.Add(-p.ExpiryWindow) + } + + return creds, nil +} + +type getCredentialsOutput struct { + Expiration *time.Time + AccessKeyID string + SecretAccessKey string + Token string +} + +type errorOutput struct { + Code string `json:"code"` + Message string `json:"message"` +} + +func (p *Provider) getCredentials() (*getCredentialsOutput, error) { + op := &aws.Operation{ + Name: "GetCredentials", + HTTPMethod: "GET", + } + + out := &getCredentialsOutput{} + req := p.Client.NewRequest(op, nil, out) + req.HTTPRequest.Header.Set("Accept", "application/json") + + return out, req.Send() +} + +func validateEndpointHandler(r *aws.Request) { + if len(r.Metadata.Endpoint) == 0 { + r.Error = aws.ErrMissingEndpoint + } +} + +func unmarshalHandler(r *aws.Request) { + defer r.HTTPResponse.Body.Close() + + out := r.Data.(*getCredentialsOutput) + if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil { + r.Error = awserr.New("SerializationError", + "failed to decode endpoint credentials", + err, + ) + } +} + +func unmarshalError(r *aws.Request) { + defer r.HTTPResponse.Body.Close() + + var errOut errorOutput + if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil { + r.Error = awserr.New("SerializationError", + "failed to decode endpoint credentials", + err, + ) + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New(errOut.Code, errOut.Message, nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go new file mode 100644 index 000000000..3dad528d4 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go @@ -0,0 +1,52 @@ +package aws + +// EndpointResolver resolves an endpoint for a service endpoint id and region. +type EndpointResolver interface { + ResolveEndpoint(service, region string) (Endpoint, error) +} + +// EndpointResolverFunc is a helper utility that wraps a function so it satisfies the +// Resolver interface. This is useful when you want to add additional endpoint +// resolving logic, or stub out specific endpoints with custom values. +type EndpointResolverFunc func(service, region string) (Endpoint, error) + +// ResolveEndpoint calls EndpointResolverFunc returning the endpoint, or error. +func (fn EndpointResolverFunc) ResolveEndpoint(service, region string) (Endpoint, error) { + return fn(service, region) +} + +// ResolveWithEndpoint allows a static Resolved Endpoint to be used as an endpoint resolver +type ResolveWithEndpoint Endpoint + +// ResolveWithEndpointURL allows a static URL to be used as a endpoint resolver. +func ResolveWithEndpointURL(url string) ResolveWithEndpoint { + return ResolveWithEndpoint(Endpoint{URL: url}) +} + +// ResolveEndpoint returns the static endpoint. +func (v ResolveWithEndpoint) ResolveEndpoint(service, region string) (Endpoint, error) { + e := Endpoint(v) + e.SigningRegion = region + return e, nil +} + +// Endpoint represents the endpoint a service client should make requests to. +type Endpoint struct { + // The URL of the endpoint. + URL string + + // The service name that should be used for signing the requests to the + // endpoint. + SigningName string + + // The region that should be used for signing the request to the endpoint. + SigningRegion string + + // States that the signing name for this endpoint was derived from metadata + // passed in, but was not explicitly modeled. + SigningNameDerived bool + + // The signing method that should be used for signign the requests to the + // endpoint. + SigningMethod string +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/decode.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/decode.go new file mode 100644 index 000000000..535f81bb2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/decode.go @@ -0,0 +1,143 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +type modelDefinition map[string]json.RawMessage + +// A DecodeModelOptions are the options for how the endpoints model definition +// are decoded. +type DecodeModelOptions struct { + SkipCustomizations bool +} + +// Set combines all of the option functions together. +func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) { + for _, fn := range optFns { + fn(d) + } +} + +// DecodeModel unmarshals a Regions and Endpoint model definition file into +// a endpoint Resolver. If the file format is not supported, or an error occurs +// when unmarshaling the model an error will be returned. +// +// Casting the return value of this func to a EnumPartitions will +// allow you to get a list of the partitions in the order the endpoints +// will be resolved in. +// +// resolver, err := endpoints.DecodeModel(reader) +// +// partitions := resolver.Partitions() +// for _, p := range partitions { +// // ... inspect partitions +// } +func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (*Resolver, error) { + var opts DecodeModelOptions + opts.Set(optFns...) + + // Get the version of the partition file to determine what + // unmarshaling model to use. + modelDef := modelDefinition{} + if err := json.NewDecoder(r).Decode(&modelDef); err != nil { + return nil, newDecodeModelError("failed to decode endpoints model", err) + } + + var version string + if b, ok := modelDef["version"]; ok { + version = string(b) + } else { + return nil, newDecodeModelError("endpoints version not found in model", nil) + } + + if version == "3" { + return decodeV3Endpoints(modelDef, opts) + } + + return nil, newDecodeModelError( + fmt.Sprintf("endpoints version %s, not supported", version), nil) +} + +func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (*Resolver, error) { + b, ok := modelDef["partitions"] + if !ok { + return nil, newDecodeModelError("endpoints model missing partitions", nil) + } + + ps := partitions{} + if err := json.Unmarshal(b, &ps); err != nil { + return nil, newDecodeModelError("failed to decode endpoints model", err) + } + + if opts.SkipCustomizations { + return &Resolver{partitions: ps}, nil + } + + // Customization + for i := 0; i < len(ps); i++ { + p := &ps[i] + custAddEC2Metadata(p) + custAddS3DualStack(p) + custSetUnresolveServices(p) + } + + return &Resolver{partitions: ps}, nil +} + +func custAddS3DualStack(p *partition) { + if p.ID != "aws" { + return + } + + s, ok := p.Services["s3"] + if !ok { + return + } + + s.Defaults.HasDualStack = boxedTrue + s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}" + + p.Services["s3"] = s +} + +func custAddEC2Metadata(p *partition) { + p.Services["ec2metadata"] = service{ + IsRegionalized: boxedFalse, + PartitionEndpoint: "aws-global", + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + } +} + +func custSetUnresolveServices(p *partition) { + var ids = map[string]struct{}{ + "data.iot": {}, + "cloudsearchdomain": {}, + } + for id := range ids { + p.Services[id] = service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + } + } +} + +type decodeModelError struct { + awsError +} + +func newDecodeModelError(msg string, err error) decodeModelError { + return decodeModelError{ + awsError: awserr.New("DecodeEndpointsModelError", msg, err), + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/defaults.go new file mode 100644 index 000000000..4930d133e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/defaults.go @@ -0,0 +1,3175 @@ +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. + +package endpoints + +import ( + "regexp" +) + +// Partition identifiers +const ( + AwsPartitionID = "aws" // AWS Standard partition. + AwsCnPartitionID = "aws-cn" // AWS China partition. + AwsUsGovPartitionID = "aws-us-gov" // AWS GovCloud (US) partition. +) + +// AWS Standard partition's regions. +const ( + ApNortheast1RegionID = "ap-northeast-1" // Asia Pacific (Tokyo). + ApNortheast2RegionID = "ap-northeast-2" // Asia Pacific (Seoul). + ApSouth1RegionID = "ap-south-1" // Asia Pacific (Mumbai). + ApSoutheast1RegionID = "ap-southeast-1" // Asia Pacific (Singapore). + ApSoutheast2RegionID = "ap-southeast-2" // Asia Pacific (Sydney). + CaCentral1RegionID = "ca-central-1" // Canada (Central). + EuCentral1RegionID = "eu-central-1" // EU (Frankfurt). + EuWest1RegionID = "eu-west-1" // EU (Ireland). + EuWest2RegionID = "eu-west-2" // EU (London). + EuWest3RegionID = "eu-west-3" // EU (Paris). + SaEast1RegionID = "sa-east-1" // South America (Sao Paulo). + UsEast1RegionID = "us-east-1" // US East (N. Virginia). + UsEast2RegionID = "us-east-2" // US East (Ohio). + UsWest1RegionID = "us-west-1" // US West (N. California). + UsWest2RegionID = "us-west-2" // US West (Oregon). +) + +// AWS China partition's regions. +const ( + CnNorth1RegionID = "cn-north-1" // China (Beijing). + CnNorthwest1RegionID = "cn-northwest-1" // China (Ningxia). +) + +// AWS GovCloud (US) partition's regions. +const ( + UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US). +) + +// Service identifiers +const ( + A4bServiceID = "a4b" // A4b. + AcmServiceID = "acm" // Acm. + AcmPcaServiceID = "acm-pca" // AcmPca. + ApiMediatailorServiceID = "api.mediatailor" // ApiMediatailor. + ApiPricingServiceID = "api.pricing" // ApiPricing. + ApigatewayServiceID = "apigateway" // Apigateway. + ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling. + Appstream2ServiceID = "appstream2" // Appstream2. + AthenaServiceID = "athena" // Athena. + AutoscalingServiceID = "autoscaling" // Autoscaling. + AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans. + BatchServiceID = "batch" // Batch. + BudgetsServiceID = "budgets" // Budgets. + CeServiceID = "ce" // Ce. + Cloud9ServiceID = "cloud9" // Cloud9. + ClouddirectoryServiceID = "clouddirectory" // Clouddirectory. + CloudformationServiceID = "cloudformation" // Cloudformation. + CloudfrontServiceID = "cloudfront" // Cloudfront. + CloudhsmServiceID = "cloudhsm" // Cloudhsm. + Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2. + CloudsearchServiceID = "cloudsearch" // Cloudsearch. + CloudsearchdomainServiceID = "cloudsearchdomain" // Cloudsearchdomain. + CloudtrailServiceID = "cloudtrail" // Cloudtrail. + CodebuildServiceID = "codebuild" // Codebuild. + CodecommitServiceID = "codecommit" // Codecommit. + CodedeployServiceID = "codedeploy" // Codedeploy. + CodepipelineServiceID = "codepipeline" // Codepipeline. + CodestarServiceID = "codestar" // Codestar. + CognitoIdentityServiceID = "cognito-identity" // CognitoIdentity. + CognitoIdpServiceID = "cognito-idp" // CognitoIdp. + CognitoSyncServiceID = "cognito-sync" // CognitoSync. + ComprehendServiceID = "comprehend" // Comprehend. + ConfigServiceID = "config" // Config. + CurServiceID = "cur" // Cur. + DataIotServiceID = "data.iot" // DataIot. + DatapipelineServiceID = "datapipeline" // Datapipeline. + DaxServiceID = "dax" // Dax. + DevicefarmServiceID = "devicefarm" // Devicefarm. + DirectconnectServiceID = "directconnect" // Directconnect. + DiscoveryServiceID = "discovery" // Discovery. + DmsServiceID = "dms" // Dms. + DsServiceID = "ds" // Ds. + DynamodbServiceID = "dynamodb" // Dynamodb. + Ec2ServiceID = "ec2" // Ec2. + Ec2metadataServiceID = "ec2metadata" // Ec2metadata. + EcrServiceID = "ecr" // Ecr. + EcsServiceID = "ecs" // Ecs. + ElasticacheServiceID = "elasticache" // Elasticache. + ElasticbeanstalkServiceID = "elasticbeanstalk" // Elasticbeanstalk. + ElasticfilesystemServiceID = "elasticfilesystem" // Elasticfilesystem. + ElasticloadbalancingServiceID = "elasticloadbalancing" // Elasticloadbalancing. + ElasticmapreduceServiceID = "elasticmapreduce" // Elasticmapreduce. + ElastictranscoderServiceID = "elastictranscoder" // Elastictranscoder. + EmailServiceID = "email" // Email. + EntitlementMarketplaceServiceID = "entitlement.marketplace" // EntitlementMarketplace. + EsServiceID = "es" // Es. + EventsServiceID = "events" // Events. + FirehoseServiceID = "firehose" // Firehose. + FmsServiceID = "fms" // Fms. + GameliftServiceID = "gamelift" // Gamelift. + GlacierServiceID = "glacier" // Glacier. + GlueServiceID = "glue" // Glue. + GreengrassServiceID = "greengrass" // Greengrass. + GuarddutyServiceID = "guardduty" // Guardduty. + HealthServiceID = "health" // Health. + IamServiceID = "iam" // Iam. + ImportexportServiceID = "importexport" // Importexport. + InspectorServiceID = "inspector" // Inspector. + IotServiceID = "iot" // Iot. + KinesisServiceID = "kinesis" // Kinesis. + KinesisanalyticsServiceID = "kinesisanalytics" // Kinesisanalytics. + KinesisvideoServiceID = "kinesisvideo" // Kinesisvideo. + KmsServiceID = "kms" // Kms. + LambdaServiceID = "lambda" // Lambda. + LightsailServiceID = "lightsail" // Lightsail. + LogsServiceID = "logs" // Logs. + MachinelearningServiceID = "machinelearning" // Machinelearning. + MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics. + MediaconvertServiceID = "mediaconvert" // Mediaconvert. + MedialiveServiceID = "medialive" // Medialive. + MediapackageServiceID = "mediapackage" // Mediapackage. + MediastoreServiceID = "mediastore" // Mediastore. + MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace. + MghServiceID = "mgh" // Mgh. + MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics. + ModelsLexServiceID = "models.lex" // ModelsLex. + MonitoringServiceID = "monitoring" // Monitoring. + MturkRequesterServiceID = "mturk-requester" // MturkRequester. + NeptuneServiceID = "neptune" // Neptune. + OpsworksServiceID = "opsworks" // Opsworks. + OpsworksCmServiceID = "opsworks-cm" // OpsworksCm. + OrganizationsServiceID = "organizations" // Organizations. + PinpointServiceID = "pinpoint" // Pinpoint. + PollyServiceID = "polly" // Polly. + RdsServiceID = "rds" // Rds. + RedshiftServiceID = "redshift" // Redshift. + RekognitionServiceID = "rekognition" // Rekognition. + ResourceGroupsServiceID = "resource-groups" // ResourceGroups. + Route53ServiceID = "route53" // Route53. + Route53domainsServiceID = "route53domains" // Route53domains. + RuntimeLexServiceID = "runtime.lex" // RuntimeLex. + RuntimeSagemakerServiceID = "runtime.sagemaker" // RuntimeSagemaker. + S3ServiceID = "s3" // S3. + SagemakerServiceID = "sagemaker" // Sagemaker. + SdbServiceID = "sdb" // Sdb. + SecretsmanagerServiceID = "secretsmanager" // Secretsmanager. + ServerlessrepoServiceID = "serverlessrepo" // Serverlessrepo. + ServicecatalogServiceID = "servicecatalog" // Servicecatalog. + ServicediscoveryServiceID = "servicediscovery" // Servicediscovery. + ShieldServiceID = "shield" // Shield. + SmsServiceID = "sms" // Sms. + SnowballServiceID = "snowball" // Snowball. + SnsServiceID = "sns" // Sns. + SqsServiceID = "sqs" // Sqs. + SsmServiceID = "ssm" // Ssm. + StatesServiceID = "states" // States. + StoragegatewayServiceID = "storagegateway" // Storagegateway. + StreamsDynamodbServiceID = "streams.dynamodb" // StreamsDynamodb. + StsServiceID = "sts" // Sts. + SupportServiceID = "support" // Support. + SwfServiceID = "swf" // Swf. + TaggingServiceID = "tagging" // Tagging. + TranslateServiceID = "translate" // Translate. + WafServiceID = "waf" // Waf. + WafRegionalServiceID = "waf-regional" // WafRegional. + WorkdocsServiceID = "workdocs" // Workdocs. + WorkmailServiceID = "workmail" // Workmail. + WorkspacesServiceID = "workspaces" // Workspaces. + XrayServiceID = "xray" // Xray. +) + +// NewDefaultResolver returns an Endpoint resolver that will be able +// to resolve endpoints for: AWS Standard, AWS China, and AWS GovCloud (US). +// +// Use DefaultPartitions() to get the list of the default partitions. +func NewDefaultResolver() *Resolver { + return &Resolver{ + partitions: defaultPartitions, + } +} + +// DefaultPartitions returns a list of the partitions the SDK is bundled +// with. The available partitions are: AWS Standard, AWS China, and AWS GovCloud (US). +// +// partitions := endpoints.DefaultPartitions +// for _, p := range partitions { +// // ... inspect partitions +// } +func DefaultPartitions() Partitions { + return defaultPartitions.Partitions() +} + +var defaultPartitions = partitions{ + awsPartition, + awscnPartition, + awsusgovPartition, +} + +// AwsPartition returns the Resolver for AWS Standard. +func AwsPartition() Partition { + return awsPartition.Partition() +} + +var awsPartition = partition{ + ID: "aws", + Name: "AWS Standard", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "ap-northeast-1": region{ + Description: "Asia Pacific (Tokyo)", + }, + "ap-northeast-2": region{ + Description: "Asia Pacific (Seoul)", + }, + "ap-south-1": region{ + Description: "Asia Pacific (Mumbai)", + }, + "ap-southeast-1": region{ + Description: "Asia Pacific (Singapore)", + }, + "ap-southeast-2": region{ + Description: "Asia Pacific (Sydney)", + }, + "ca-central-1": region{ + Description: "Canada (Central)", + }, + "eu-central-1": region{ + Description: "EU (Frankfurt)", + }, + "eu-west-1": region{ + Description: "EU (Ireland)", + }, + "eu-west-2": region{ + Description: "EU (London)", + }, + "eu-west-3": region{ + Description: "EU (Paris)", + }, + "sa-east-1": region{ + Description: "South America (Sao Paulo)", + }, + "us-east-1": region{ + Description: "US East (N. Virginia)", + }, + "us-east-2": region{ + Description: "US East (Ohio)", + }, + "us-west-1": region{ + Description: "US West (N. California)", + }, + "us-west-2": region{ + Description: "US West (Oregon)", + }, + }, + Services: services{ + "a4b": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "acm": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "acm-pca": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "api.mediatailor": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + }, + }, + "api.pricing": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "pricing", + }, + }, + Endpoints: endpoints{ + "ap-south-1": endpoint{}, + "us-east-1": endpoint{}, + }, + }, + "apigateway": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "appstream2": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Service: "appstream", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "athena": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "autoscaling-plans": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "autoscaling-plans", + }, + }, + Endpoints: endpoints{ + "ap-southeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "batch": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "budgets": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "budgets.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "ce": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "ce.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "cloud9": service{ + + Endpoints: endpoints{ + "ap-southeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "clouddirectory": service{ + + Endpoints: endpoints{ + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudformation": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudfront": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "cloudfront.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "cloudhsm": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudhsmv2": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudsearch": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudsearchdomain": service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + }, + "cloudtrail": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codebuild": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "codebuild-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "codebuild-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "codebuild-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "codebuild-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "codecommit": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codedeploy": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codepipeline": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codestar": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cognito-identity": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cognito-idp": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cognito-sync": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "comprehend": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "config": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cur": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "data.iot": service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + }, + "datapipeline": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "dax": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "devicefarm": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, + "directconnect": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "discovery": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, + "dms": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ds": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "local": endpoint{ + Hostname: "localhost:8000", + Protocols: []string{"http"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ec2": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ec2metadata": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + }, + "ecr": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ecs": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticache": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticfilesystem": service{ + + Endpoints: endpoints{ + "ap-northeast-2": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticmapreduce": service{ + Defaults: endpoint{ + SSLCommonName: "{region}.{service}.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{ + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elastictranscoder": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "email": service{ + + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "entitlement.marketplace": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "events": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "firehose": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "fms": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "gamelift": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "glacier": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "glue": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "guardduty": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "health": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "iam.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "importexport": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "importexport.amazonaws.com", + SignatureVersions: []string{"v2", "v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + Service: "IngestionService", + }, + }, + }, + }, + "inspector": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "iot": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kinesis": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kinesisanalytics": service{ + + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kinesisvideo": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kms": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "lambda": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "lightsail": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "logs": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "machinelearning": service{ + + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + }, + }, + "marketplacecommerceanalytics": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "mediaconvert": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "medialive": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mediapackage": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mediastore": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "metering.marketplace": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mgh": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, + "mobileanalytics": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "models.lex": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "monitoring": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mturk-requester": service{ + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "sandbox": endpoint{ + Hostname: "mturk-requester-sandbox.us-east-1.amazonaws.com", + }, + "us-east-1": endpoint{}, + }, + }, + "neptune": service{ + + Endpoints: endpoints{ + "eu-west-1": endpoint{ + Hostname: "rds.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + "us-east-1": endpoint{ + Hostname: "rds.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{ + Hostname: "rds.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-2": endpoint{ + Hostname: "rds.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "opsworks": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "opsworks-cm": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "organizations": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "organizations.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "pinpoint": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "mobiletargeting", + }, + }, + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "polly": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "rds": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + SSLCommonName: "{service}.{dnsSuffix}", + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "redshift": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "rekognition": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "resource-groups": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "route53.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "route53domains": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "runtime.lex": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "runtime.sagemaker": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "s3": service{ + PartitionEndpoint: "us-east-1", + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + + HasDualStack: boxedTrue, + DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}", + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Hostname: "s3.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{ + Hostname: "s3.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "ap-southeast-2": endpoint{ + Hostname: "s3.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{ + Hostname: "s3.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "s3-external-1": endpoint{ + Hostname: "s3-external-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "sa-east-1": endpoint{ + Hostname: "s3.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "us-east-1": endpoint{ + Hostname: "s3.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{ + Hostname: "s3.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "us-west-2": endpoint{ + Hostname: "s3.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + }, + }, + "sagemaker": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "sdb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"v2"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + Hostname: "sdb.amazonaws.com", + }, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "secretsmanager": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "serverlessrepo": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Protocols: []string{"https"}, + }, + "ap-northeast-2": endpoint{ + Protocols: []string{"https"}, + }, + "ap-south-1": endpoint{ + Protocols: []string{"https"}, + }, + "ap-southeast-1": endpoint{ + Protocols: []string{"https"}, + }, + "ap-southeast-2": endpoint{ + Protocols: []string{"https"}, + }, + "ca-central-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-central-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-west-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-west-2": endpoint{ + Protocols: []string{"https"}, + }, + "sa-east-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-east-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-east-2": endpoint{ + Protocols: []string{"https"}, + }, + "us-west-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-west-2": endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "servicecatalog": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "servicediscovery": service{ + + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "shield": service{ + IsRegionalized: boxedFalse, + Defaults: endpoint{ + SSLCommonName: "Shield.us-east-1.amazonaws.com", + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "snowball": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "sns": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "sqs": service{ + Defaults: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "fips-us-east-1": endpoint{}, + "fips-us-east-2": endpoint{}, + "fips-us-west-1": endpoint{}, + "fips-us-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + SSLCommonName: "queue.{dnsSuffix}", + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ssm": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "states": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "storagegateway": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "local": endpoint{ + Hostname: "localhost:8000", + Protocols: []string{"http"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "sts": service{ + PartitionEndpoint: "aws-global", + Defaults: endpoint{ + Hostname: "sts.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{ + Hostname: "sts.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "aws-global": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "sts-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "sts-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "sts-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "sts-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "support": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "swf": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "tagging": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "translate": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "waf": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "waf.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "waf-regional": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "workdocs": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "workmail": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "workspaces": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "xray": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + }, +} + +// AwsCnPartition returns the Resolver for AWS China. +func AwsCnPartition() Partition { + return awscnPartition.Partition() +} + +var awscnPartition = partition{ + ID: "aws-cn", + Name: "AWS China", + DNSSuffix: "amazonaws.com.cn", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^cn\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "cn-north-1": region{ + Description: "China (Beijing)", + }, + "cn-northwest-1": region{ + Description: "China (Ningxia)", + }, + }, + Services: services{ + "apigateway": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cloudformation": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cloudsearchdomain": service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + }, + "cloudtrail": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "codedeploy": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cognito-identity": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "config": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "data.iot": service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + }, + "directconnect": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ec2": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ec2metadata": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + }, + "ecr": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ecs": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticache": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticmapreduce": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "cn-northwest-1": endpoint{}, + }, + }, + "events": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "glacier": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-cn-global": endpoint{ + Hostname: "iam.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + }, + }, + "iot": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "kinesis": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "lambda": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "logs": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "monitoring": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "rds": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "redshift": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "s3": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "snowball": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "sns": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "sqs": service{ + Defaults: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ssm": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "storagegateway": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "sts": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "swf": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "tagging": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + }, +} + +// AwsUsGovPartition returns the Resolver for AWS GovCloud (US). +func AwsUsGovPartition() Partition { + return awsusgovPartition.Partition() +} + +var awsusgovPartition = partition{ + ID: "aws-us-gov", + Name: "AWS GovCloud (US)", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^us\\-gov\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "us-gov-west-1": region{ + Description: "AWS GovCloud (US)", + }, + }, + Services: services{ + "acm": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "apigateway": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "autoscaling": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "cloudformation": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "cloudhsm": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "cloudhsmv2": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "cloudsearchdomain": service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + }, + "cloudtrail": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "codedeploy": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "config": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "data.iot": service{ + Defaults: endpoint{ + Unresolveable: boxedTrue, + }, + }, + "directconnect": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "dms": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "dynamodb": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "ec2": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "ec2metadata": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + }, + "ecr": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "ecs": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "elasticache": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "elasticloadbalancing": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "elasticmapreduce": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "events": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "glacier": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-us-gov-global": endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "kinesis": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "kms": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "lambda": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "logs": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "metering.marketplace": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "monitoring": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "polly": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "rds": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "redshift": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "rekognition": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "s3": service{ + Defaults: endpoint{ + SignatureVersions: []string{"s3", "s3v4"}, + }, + Endpoints: endpoints{ + "fips-us-gov-west-1": endpoint{ + Hostname: "s3-fips-us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "s3.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "snowball": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "sns": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "sqs": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + }, + "ssm": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "storagegateway": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "sts": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "swf": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "tagging": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/doc.go new file mode 100644 index 000000000..faf8723fe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/doc.go @@ -0,0 +1,69 @@ +// Package endpoints provides the types and functionality for defining regions +// and endpoints, as well as querying those definitions. +// +// The SDK's Regions and Endpoints metadata is code generated into the endpoints +// package, and is accessible via the DefaultResolver function. This function +// returns a endpoint Resolver will search the metadata and build an associated +// endpoint if one is found. The default resolver will search all partitions +// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and +// AWS GovCloud (US) (aws-us-gov). +// . +// +// Enumerating Regions and Endpoint Metadata +// +// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface +// will allow you to get access to the list of underlying Partitions with the +// Partitions method. This is helpful if you want to limit the SDK's endpoint +// resolving to a single partition, or enumerate regions, services, and endpoints +// in the partition. +// +// resolver := endpoints.NewDefaultResolver() +// partitions := resolver.Partitions() +// +// for _, p := range partitions { +// fmt.Println("Regions for", p.ID()) +// for id, _ := range p.Regions() { +// fmt.Println("*", id) +// } +// +// fmt.Println("Services for", p.ID()) +// for id, _ := range p.Services() { +// fmt.Println("*", id) +// } +// } +// +// Using Custom Endpoints +// +// The endpoints package also gives you the ability to use your own logic how +// endpoints are resolved. This is a great way to define a custom endpoint +// for select services, without passing that logic down through your code. +// +// If a type implements the Resolver interface it can be used to resolve +// endpoints. To use this with the SDK's Session and Config set the value +// of the type to the EndpointsResolver field of aws.Config when initializing +// the service client. +// +// In addition the ResolverFunc is a wrapper for a func matching the signature +// of Resolver.ResolveEndpoint, converting it to a type that satisfies the +// Resolver interface. +// +// +// defaultResolver := endpoints.NewDefaultResolver() +// myCustomResolver := func(service, region string) (aws.Endpoint, error) { +// if service == endpoints.S3ServiceID { +// return aws.Endpoint{ +// URL: "s3.custom.endpoint.com", +// SigningRegion: "custom-signing-region", +// }, nil +// } +// +// return defaultResolver.ResolveEndpoint(service, region) +// } +// +// cfg, err := external.LoadDefaultAWSConfig() +// if err != nil { +// panic(err) +// } +// cfg.Region = "us-west-2" +// cfg.EndpointResolver = aws.EndpointResolverFunc(myCustomResolver) +package endpoints diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/endpoints.go new file mode 100644 index 000000000..194b57b6f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/endpoints.go @@ -0,0 +1,344 @@ +package endpoints + +import ( + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// ResolveOptions provide the configuration needed to direct how the +// endpoints will be resolved. +type ResolveOptions struct { + // DisableSSL forces the endpoint to be resolved as HTTP. + // instead of HTTPS if the service supports it. + DisableSSL bool + + // Sets the resolver to resolve the endpoint as a dualstack endpoint + // for the service. If dualstack support for a service is not known and + // StrictMatching is not enabled a dualstack endpoint for the service will + // be returned. This endpoint may not be valid. If StrictMatching is + // enabled only services that are known to support dualstack will return + // dualstack endpoints. + UseDualStack bool + + // Enables strict matching of services and regions resolved endpoints. + // If the partition doesn't enumerate the exact service and region an + // error will be returned. This option will prevent returning endpoints + // that look valid, but may not resolve to any real endpoint. + StrictMatching bool +} + +// A Resolver provides endpoint resolution based on modeled endpoint data. +type Resolver struct { + ResolveOptions + + partitions partitions +} + +// ResolveEndpoint attempts to resolve an endpoint againsted the modeled endpoint +// data. If an endpoint is found it will be returned. An error will be returned +// otherwise. +// +// Searches through the partitions in the order they are defined. +func (r *Resolver) ResolveEndpoint(service, region string) (aws.Endpoint, error) { + return r.partitions.EndpointFor(service, region, r.ResolveOptions) +} + +// Partitions returns the partitions that make up the resolver. +func (r *Resolver) Partitions() Partitions { + return r.partitions.Partitions() +} + +// Partitions is a slice of paritions describing regions and endpoints +type Partitions []Partition + +// ForRegion returns the first partition which includes the region +// passed in. This includes both known regions and regions which match +// a pattern supported by the partition which may include regions that are +// not explicitly known by the partition. Use the Regions method of the +// returned Partition if explicit support is needed. +func (ps Partitions) ForRegion(id string) (Partition, bool) { + for _, p := range ps { + if _, ok := p.p.Regions[id]; ok || p.p.RegionRegex.MatchString(id) { + return p, true + } + } + + return Partition{}, false +} + +// ForPartition returns the parition with the matching ID passed in. +func (ps Partitions) ForPartition(id string) (Partition, bool) { + for _, p := range ps { + if p.ID() == id { + return p, true + } + } + + return Partition{}, false +} + +// A Partition provides the ability to enumerate the partition's regions +// and services. +type Partition struct { + id string + p *partition +} + +// ID returns the identifier of the partition. +func (p Partition) ID() string { return p.id } + +// Endpoint attempts to resolve the endpoint based on service and region. +// See Options for information on configuring how the endpoint is resolved. +// +// If the service cannot be found in the metadata the endpoint will be resolved +// based on the parition's endpoint pattern, and service endpoint prefix. +// +// When resolving endpoints you can choose to enable StrictMatching. This will +// require the provided service and region to be known by the partition. +// If the endpoint cannot be strictly resolved an error will be returned. This +// mode is useful to ensure the endpoint resolved is valid. Without +// StrictMatching enabled the endpoint returned my look valid but may not work. +// StrictMatching requires the SDK to be updated if you want to take advantage +// of new regions and services expansions. +// +// Errors that can be returned. +// * UnknownServiceError +// * UnknownEndpointError +func (p Partition) Endpoint(service, region string, opts ResolveOptions) (aws.Endpoint, error) { + return p.p.EndpointFor(service, region, opts) +} + +// Regions returns a map of Regions indexed by their ID. This is useful for +// enumerating over the regions in a partition. +func (p Partition) Regions() map[string]Region { + rs := map[string]Region{} + for id := range p.p.Regions { + rs[id] = Region{ + id: id, + p: p.p, + } + } + + return rs +} + +// RegionsForService returns the map of regions for the service id specified. +// false is returned if the service is not found in the partition. +func (p Partition) RegionsForService(id string) (map[string]Region, bool) { + if _, ok := p.p.Services[id]; !ok { + return nil, false + } + + s := Service{ + id: id, + p: p.p, + } + return s.Regions(), true +} + +// Services returns a map of Service indexed by their ID. This is useful for +// enumerating over the services in a partition. +func (p Partition) Services() map[string]Service { + ss := map[string]Service{} + for id := range p.p.Services { + ss[id] = Service{ + id: id, + p: p.p, + } + } + + return ss +} + +// Resolver returns an endpoint resolver for the partitions. Use this to satisfy +// the SDK's EndpointResolver. +func (p Partition) Resolver() *Resolver { + return &Resolver{ + partitions: partitions{*p.p}, + } +} + +// A Region provides information about a region, and ability to resolve an +// endpoint from the context of a region, given a service. +type Region struct { + id, desc string + p *partition +} + +// ID returns the region's identifier. +func (r Region) ID() string { return r.id } + +// Endpoint resolves an endpoint from the context of the region given +// a service. See Partition.EndpointFor for usage and errors that can be returned. +func (r Region) Endpoint(service string, opts ResolveOptions) (aws.Endpoint, error) { + return r.p.EndpointFor(service, r.id, opts) +} + +// Services returns a list of all services that are known to be in this region. +func (r Region) Services() map[string]Service { + ss := map[string]Service{} + for id, s := range r.p.Services { + if _, ok := s.Endpoints[r.id]; ok { + ss[id] = Service{ + id: id, + p: r.p, + } + } + } + + return ss +} + +// A Service provides information about a service, and ability to resolve an +// endpoint from the context of a service, given a region. +type Service struct { + id string + p *partition +} + +// ID returns the identifier for the service. +func (s Service) ID() string { return s.id } + +// Endpoint resolves an endpoint from the context of a service given +// a region. See Partition.EndpointFor for usage and errors that can be returned. +func (s Service) Endpoint(region string, opts ResolveOptions) (aws.Endpoint, error) { + return s.p.EndpointFor(s.id, region, opts) +} + +// Regions returns a map of Regions that the service is present in. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Regions() map[string]Region { + rs := map[string]Region{} + for id := range s.p.Services[s.id].Endpoints { + if _, ok := s.p.Regions[id]; ok { + rs[id] = Region{ + id: id, + p: s.p, + } + } + } + + return rs +} + +// Endpoints returns a map of Endpoints indexed by their ID for all known +// endpoints for a service. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Endpoints() map[string]Endpoint { + es := map[string]Endpoint{} + for id := range s.p.Services[s.id].Endpoints { + es[id] = Endpoint{ + id: id, + serviceID: s.id, + p: s.p, + } + } + + return es +} + +// A Endpoint provides information about endpoints, and provides the ability +// to resolve that endpoint for the service, and the region the endpoint +// represents. +type Endpoint struct { + id string + serviceID string + p *partition +} + +// ID returns the identifier for an endpoint. +func (e Endpoint) ID() string { return e.id } + +// ServiceID returns the identifier the endpoint belongs to. +func (e Endpoint) ServiceID() string { return e.serviceID } + +// Resolve resolves an endpoint from the context of a service and +// region the endpoint represents. See Partition.EndpointFor for usage and +// errors that can be returned. +func (e Endpoint) Resolve(opts ResolveOptions) (aws.Endpoint, error) { + return e.p.EndpointFor(e.serviceID, e.id, opts) +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError awserr.Error + +// A UnknownServiceError is returned when the service does not resolve to an +// endpoint. Includes a list of all known services for the partition. Returned +// when a partition does not support the service. +type UnknownServiceError struct { + awsError + Partition string + Service string + Known []string +} + +// NewUnknownServiceError builds and returns UnknownServiceError. +func NewUnknownServiceError(p, s string, known []string) UnknownServiceError { + return UnknownServiceError{ + awsError: awserr.New("UnknownServiceError", + "could not resolve endpoint for unknown service", nil), + Partition: p, + Service: s, + Known: known, + } +} + +// String returns the string representation of the error. +func (e UnknownServiceError) Error() string { + extra := fmt.Sprintf("partition: %q, service: %q", + e.Partition, e.Service) + if len(e.Known) > 0 { + extra += fmt.Sprintf(", known: %v", e.Known) + } + return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +func (e UnknownServiceError) String() string { + return e.Error() +} + +// A UnknownEndpointError is returned when in StrictMatching mode and the +// service is valid, but the region does not resolve to an endpoint. Includes +// a list of all known endpoints for the service. +type UnknownEndpointError struct { + awsError + Partition string + Service string + Region string + Known []string +} + +// NewUnknownEndpointError builds and returns UnknownEndpointError. +func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError { + return UnknownEndpointError{ + awsError: awserr.New("UnknownEndpointError", + "could not resolve endpoint", nil), + Partition: p, + Service: s, + Region: r, + Known: known, + } +} + +// String returns the string representation of the error. +func (e UnknownEndpointError) Error() string { + extra := fmt.Sprintf("partition: %q, service: %q, region: %q", + e.Partition, e.Service, e.Region) + if len(e.Known) > 0 { + extra += fmt.Sprintf(", known: %v", e.Known) + } + return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +func (e UnknownEndpointError) String() string { + return e.Error() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model.go new file mode 100644 index 000000000..d3bcbb807 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model.go @@ -0,0 +1,313 @@ +package endpoints + +import ( + "fmt" + "regexp" + "strconv" + "strings" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +type partitions []partition + +func (ps partitions) EndpointFor(service, region string, opts ResolveOptions) (aws.Endpoint, error) { + for i := 0; i < len(ps); i++ { + if !ps[i].canResolveEndpoint(service, region, opts.StrictMatching) { + continue + } + + return ps[i].EndpointFor(service, region, opts) + } + + // If loose matching fallback to first partition format to use + // when resolving the endpoint. + if !opts.StrictMatching && len(ps) > 0 { + return ps[0].EndpointFor(service, region, opts) + } + + return aws.Endpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{}) +} + +// Partitions satisfies the EnumPartitions interface and returns a list +// of Partitions representing each partition represented in the SDK's +// endpoints model. +func (ps partitions) Partitions() Partitions { + parts := make(Partitions, 0, len(ps)) + for i := 0; i < len(ps); i++ { + parts = append(parts, ps[i].Partition()) + } + + return parts +} + +type partition struct { + ID string `json:"partition"` + Name string `json:"partitionName"` + DNSSuffix string `json:"dnsSuffix"` + RegionRegex regionRegex `json:"regionRegex"` + Defaults endpoint `json:"defaults"` + Regions regions `json:"regions"` + Services services `json:"services"` +} + +func (p partition) Partition() Partition { + return Partition{ + id: p.ID, + p: &p, + } +} + +func (p partition) canResolveEndpoint(service, region string, strictMatch bool) bool { + s, hasService := p.Services[service] + _, hasEndpoint := s.Endpoints[region] + + if hasEndpoint && hasService { + return true + } + + if strictMatch { + return false + } + + return p.RegionRegex.MatchString(region) +} + +func (p partition) EndpointFor(service, region string, opts ResolveOptions) (resolved aws.Endpoint, err error) { + s, hasService := p.Services[service] + if !hasService && opts.StrictMatching { + // Only return error if the resolver will not fallback to creating + // endpoint based on service endpoint ID passed in. + return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services)) + } + + e, hasEndpoint := s.endpointForRegion(region) + if !hasEndpoint && opts.StrictMatching { + return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints)) + } + + defs := []endpoint{p.Defaults, s.Defaults} + return e.resolve(service, region, p.DNSSuffix, defs, opts), nil +} + +func serviceList(ss services) []string { + list := make([]string, 0, len(ss)) + for k := range ss { + list = append(list, k) + } + return list +} +func endpointList(es endpoints) []string { + list := make([]string, 0, len(es)) + for k := range es { + list = append(list, k) + } + return list +} + +type regionRegex struct { + *regexp.Regexp +} + +func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) { + // Strip leading and trailing quotes + regex, err := strconv.Unquote(string(b)) + if err != nil { + return fmt.Errorf("unable to strip quotes from regex, %v", err) + } + + rr.Regexp, err = regexp.Compile(regex) + if err != nil { + return fmt.Errorf("unable to unmarshal region regex, %v", err) + } + return nil +} + +type regions map[string]region + +type region struct { + Description string `json:"description"` +} + +type services map[string]service + +type service struct { + PartitionEndpoint string `json:"partitionEndpoint"` + IsRegionalized boxedBool `json:"isRegionalized,omitempty"` + Defaults endpoint `json:"defaults"` + Endpoints endpoints `json:"endpoints"` +} + +func (s *service) endpointForRegion(region string) (endpoint, bool) { + if s.IsRegionalized == boxedFalse { + return s.Endpoints[s.PartitionEndpoint], region == s.PartitionEndpoint + } + + if e, ok := s.Endpoints[region]; ok { + return e, true + } + + // Unable to find any matching endpoint, return + // blank that will be used for generic endpoint creation. + return endpoint{}, false +} + +type endpoints map[string]endpoint + +type endpoint struct { + // True if the endpoint cannot be resolved for this partition/region/service + Unresolveable boxedBool `json:"-"` + + Hostname string `json:"hostname"` + Protocols []string `json:"protocols"` + CredentialScope credentialScope `json:"credentialScope"` + + // Custom fields not modeled + HasDualStack boxedBool `json:"-"` + DualStackHostname string `json:"-"` + + // Signature Version not used + SignatureVersions []string `json:"signatureVersions"` + + // SSLCommonName not used. + SSLCommonName string `json:"sslCommonName"` +} + +const ( + defaultProtocol = "https" + defaultSigner = "v4" +) + +var ( + protocolPriority = []string{"https", "http"} + signerPriority = []string{"v4", "v2"} +) + +func getByPriority(s []string, p []string, def string) string { + if len(s) == 0 { + return def + } + + for i := 0; i < len(p); i++ { + for j := 0; j < len(s); j++ { + if s[j] == p[i] { + return s[j] + } + } + } + + return s[0] +} + +func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts ResolveOptions) aws.Endpoint { + var merged endpoint + for _, def := range defs { + merged.mergeIn(def) + } + merged.mergeIn(e) + e = merged + + var u string + if e.Unresolveable != boxedTrue { + // Only attempt to resolve the endpoint if it can be resolved. + hostname := e.Hostname + + // Offset the hostname for dualstack if enabled + if opts.UseDualStack && e.HasDualStack == boxedTrue { + hostname = e.DualStackHostname + } + + u = strings.Replace(hostname, "{service}", service, 1) + u = strings.Replace(u, "{region}", region, 1) + u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1) + + scheme := getEndpointScheme(e.Protocols, opts.DisableSSL) + u = fmt.Sprintf("%s://%s", scheme, u) + } + + signingRegion := e.CredentialScope.Region + if len(signingRegion) == 0 { + signingRegion = region + } + + signingName := e.CredentialScope.Service + var signingNameDerived bool + if len(signingName) == 0 { + signingName = service + signingNameDerived = true + } + + return aws.Endpoint{ + URL: u, + SigningRegion: signingRegion, + SigningName: signingName, + SigningNameDerived: signingNameDerived, + SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner), + } +} + +func getEndpointScheme(protocols []string, disableSSL bool) string { + if disableSSL { + return "http" + } + + return getByPriority(protocols, protocolPriority, defaultProtocol) +} + +func (e *endpoint) mergeIn(other endpoint) { + if other.Unresolveable != boxedBoolUnset { + e.Unresolveable = other.Unresolveable + } + if len(other.Hostname) > 0 { + e.Hostname = other.Hostname + } + if len(other.Protocols) > 0 { + e.Protocols = other.Protocols + } + if len(other.SignatureVersions) > 0 { + e.SignatureVersions = other.SignatureVersions + } + if len(other.CredentialScope.Region) > 0 { + e.CredentialScope.Region = other.CredentialScope.Region + } + if len(other.CredentialScope.Service) > 0 { + e.CredentialScope.Service = other.CredentialScope.Service + } + if len(other.SSLCommonName) > 0 { + e.SSLCommonName = other.SSLCommonName + } + if other.HasDualStack != boxedBoolUnset { + e.HasDualStack = other.HasDualStack + } + if len(other.DualStackHostname) > 0 { + e.DualStackHostname = other.DualStackHostname + } +} + +type credentialScope struct { + Region string `json:"region"` + Service string `json:"service"` +} + +type boxedBool int + +func (b *boxedBool) UnmarshalJSON(buf []byte) error { + v, err := strconv.ParseBool(string(buf)) + if err != nil { + return err + } + + if v { + *b = boxedTrue + } else { + *b = boxedFalse + } + + return nil +} + +const ( + boxedBoolUnset boxedBool = iota + boxedFalse + boxedTrue +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model_codegen.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model_codegen.go new file mode 100644 index 000000000..033afb26a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints/v3model_codegen.go @@ -0,0 +1,330 @@ +// +build codegen + +package endpoints + +import ( + "fmt" + "io" + "reflect" + "strings" + "text/template" + "unicode" +) + +// A CodeGenOptions are the options for code generating the endpoints into +// Go code from the endpoints model definition. +type CodeGenOptions struct { + // Options for how the model will be decoded. + DecodeModelOptions DecodeModelOptions +} + +// Set combines all of the option functions together +func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) { + for _, fn := range optFns { + fn(d) + } +} + +// CodeGenModel given a endpoints model file will decode it and attempt to +// generate Go code from the model definition. Error will be returned if +// the code is unable to be generated, or decoded. +func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error { + var opts CodeGenOptions + opts.Set(optFns...) + + resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) { + *d = opts.DecodeModelOptions + }) + if err != nil { + return err + } + + tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl)) + if err := tmpl.ExecuteTemplate(outFile, "defaults", resolver.partitions); err != nil { + return fmt.Errorf("failed to execute template, %v", err) + } + + return nil +} + +func toSymbol(v string) string { + out := []rune{} + for _, c := range strings.Title(v) { + if !(unicode.IsNumber(c) || unicode.IsLetter(c)) { + continue + } + + out = append(out, c) + } + + return string(out) +} + +func quoteString(v string) string { + return fmt.Sprintf("%q", v) +} + +func regionConstName(p, r string) string { + return toSymbol(p) + toSymbol(r) +} + +func partitionGetter(id string) string { + return fmt.Sprintf("%sPartition", toSymbol(id)) +} + +func partitionVarName(id string) string { + return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id))) +} + +func listPartitionNames(ps partitions) string { + names := []string{} + switch len(ps) { + case 1: + return ps[0].Name + case 2: + return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name) + default: + for i, p := range ps { + if i == len(ps)-1 { + names = append(names, "and "+p.Name) + } else { + names = append(names, p.Name) + } + } + return strings.Join(names, ", ") + } +} + +func boxedBoolIfSet(msg string, v boxedBool) string { + switch v { + case boxedTrue: + return fmt.Sprintf(msg, "boxedTrue") + case boxedFalse: + return fmt.Sprintf(msg, "boxedFalse") + default: + return "" + } +} + +func stringIfSet(msg, v string) string { + if len(v) == 0 { + return "" + } + + return fmt.Sprintf(msg, v) +} + +func stringSliceIfSet(msg string, vs []string) string { + if len(vs) == 0 { + return "" + } + + names := []string{} + for _, v := range vs { + names = append(names, `"`+v+`"`) + } + + return fmt.Sprintf(msg, strings.Join(names, ",")) +} + +func endpointIsSet(v endpoint) bool { + return !reflect.DeepEqual(v, endpoint{}) +} + +func serviceSet(ps partitions) map[string]struct{} { + set := map[string]struct{}{} + for _, p := range ps { + for id := range p.Services { + set[id] = struct{}{} + } + } + + return set +} + +var funcMap = template.FuncMap{ + "ToSymbol": toSymbol, + "QuoteString": quoteString, + "RegionConst": regionConstName, + "PartitionGetter": partitionGetter, + "PartitionVarName": partitionVarName, + "ListPartitionNames": listPartitionNames, + "BoxedBoolIfSet": boxedBoolIfSet, + "StringIfSet": stringIfSet, + "StringSliceIfSet": stringSliceIfSet, + "EndpointIsSet": endpointIsSet, + "ServicesSet": serviceSet, +} + +const v3Tmpl = ` +{{ define "defaults" -}} +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. + +package endpoints + +import ( + "regexp" +) + + {{ template "partition consts" . }} + + {{ range $_, $partition := . }} + {{ template "partition region consts" $partition }} + {{ end }} + + {{ template "service consts" . }} + + {{ template "endpoint resolvers" . }} +{{- end }} + +{{ define "partition consts" }} + // Partition identifiers + const ( + {{ range $_, $p := . -}} + {{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition. + {{ end -}} + ) +{{- end }} + +{{ define "partition region consts" }} + // {{ .Name }} partition's regions. + const ( + {{ range $id, $region := .Regions -}} + {{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}. + {{ end -}} + ) +{{- end }} + +{{ define "service consts" }} + // Service identifiers + const ( + {{ $serviceSet := ServicesSet . -}} + {{ range $id, $_ := $serviceSet -}} + {{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}. + {{ end -}} + ) +{{- end }} + +{{ define "endpoint resolvers" }} + // NewDefaultResolver returns an Endpoint resolver that will be able + // to resolve endpoints for: {{ ListPartitionNames . }}. + // + // Use DefaultPartitions() to get the list of the default partitions. + func NewDefaultResolver() *Resolver { + return &Resolver{ + partitions: defaultPartitions, + } + } + + // DefaultPartitions returns a list of the partitions the SDK is bundled + // with. The available partitions are: {{ ListPartitionNames . }}. + // + // partitions := endpoints.DefaultPartitions + // for _, p := range partitions { + // // ... inspect partitions + // } + func DefaultPartitions() Partitions { + return defaultPartitions.Partitions() + } + + var defaultPartitions = partitions{ + {{ range $_, $partition := . -}} + {{ PartitionVarName $partition.ID }}, + {{ end }} + } + + {{ range $_, $partition := . -}} + {{ $name := PartitionGetter $partition.ID -}} + // {{ $name }} returns the Resolver for {{ $partition.Name }}. + func {{ $name }}() Partition { + return {{ PartitionVarName $partition.ID }}.Partition() + } + var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }} + {{ end }} +{{ end }} + +{{ define "gocode Partition" -}} +partition{ + {{ StringIfSet "ID: %q,\n" .ID -}} + {{ StringIfSet "Name: %q,\n" .Name -}} + {{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}} + RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }}, + {{ if EndpointIsSet .Defaults -}} + Defaults: {{ template "gocode Endpoint" .Defaults }}, + {{- end }} + Regions: {{ template "gocode Regions" .Regions }}, + Services: {{ template "gocode Services" .Services }}, +} +{{- end }} + +{{ define "gocode RegionRegex" -}} +regionRegex{ + Regexp: func() *regexp.Regexp{ + reg, _ := regexp.Compile({{ QuoteString .Regexp.String }}) + return reg + }(), +} +{{- end }} + +{{ define "gocode Regions" -}} +regions{ + {{ range $id, $region := . -}} + "{{ $id }}": {{ template "gocode Region" $region }}, + {{ end -}} +} +{{- end }} + +{{ define "gocode Region" -}} +region{ + {{ StringIfSet "Description: %q,\n" .Description -}} +} +{{- end }} + +{{ define "gocode Services" -}} +services{ + {{ range $id, $service := . -}} + "{{ $id }}": {{ template "gocode Service" $service }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Service" -}} +service{ + {{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}} + {{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}} + {{ if EndpointIsSet .Defaults -}} + Defaults: {{ template "gocode Endpoint" .Defaults -}}, + {{- end }} + {{ if .Endpoints -}} + Endpoints: {{ template "gocode Endpoints" .Endpoints }}, + {{- end }} +} +{{- end }} + +{{ define "gocode Endpoints" -}} +endpoints{ + {{ range $id, $endpoint := . -}} + "{{ $id }}": {{ template "gocode Endpoint" $endpoint }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Endpoint" -}} +endpoint{ + {{ BoxedBoolIfSet "Unresolveable: %s,\n" .Unresolveable -}} + {{ StringIfSet "Hostname: %q,\n" .Hostname -}} + {{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}} + {{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}} + {{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}} + {{ if or .CredentialScope.Region .CredentialScope.Service -}} + CredentialScope: credentialScope{ + {{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}} + {{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}} + }, + {{- end }} + {{ BoxedBoolIfSet "HasDualStack: %s,\n" .HasDualStack -}} + {{ StringIfSet "DualStackHostname: %q,\n" .DualStackHostname -}} + +} +{{- end }} +` diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go new file mode 100644 index 000000000..c5671378e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go @@ -0,0 +1,17 @@ +package aws + +import "github.com/aws/aws-sdk-go-v2/aws/awserr" + +var ( + // ErrMissingRegion is an error that is returned if region configuration is + // not found. + // + // @readonly + ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) + + // ErrMissingEndpoint is an error that is returned if an endpoint cannot be + // resolved for a service. + // + // @readonly + ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/config.go new file mode 100644 index 000000000..5753b432d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/config.go @@ -0,0 +1,132 @@ +package external + +import ( + "github.com/aws/aws-sdk-go-v2/aws" +) + +// DefaultConfigLoaders are a slice of functions that will read external configuration +// sources for configuration values. These values are read by the AWSConfigResolvers +// using interfaces to extract specific information from the external configuration. +var DefaultConfigLoaders = []ConfigLoader{ + LoadEnvConfig, + LoadSharedConfigIgnoreNotExist, +} + +// DefaultAWSConfigResolvers are a slice of functions that will resolve external +// configuration values into AWS configuration values. +// +// This will setup the AWS configuration's Region, +var DefaultAWSConfigResolvers = []AWSConfigResolver{ + ResolveDefaultAWSConfig, + ResolveCustomCABundle, + + ResolveRegion, + + ResolveFallbackEC2Credentials, // Initial defauilt credentails provider. + ResolveCredentialsValue, + ResolveEndpointCredentials, + ResolveContainerEndpointPathCredentials, // TODO is this order right? + ResolveAssumeRoleCredentials, +} + +// A Config represents a generic configuration value or set of values. This type +// will be used by the AWSConfigResolvers to extract +// +// General the Config type will use type assertion against the Provider interfaces +// to extract specific data from the Config. +type Config interface{} + +// A ConfigLoader is used to load external configuration data and returns it as +// a generic Config type. +// +// The loader should return an error if it fails to load the external configuration +// or the configuration data is malformed, or required components missing. +type ConfigLoader func(Configs) (Config, error) + +// An AWSConfigResolver will extract configuration data from the Configs slice +// using the provider interfaces to extract specific functionality. The extracted +// configuration values will be written to the AWS Config value. +// +// The resolver should return an error if it it fails to extract the data, the +// data is malformed, or incomplete. +type AWSConfigResolver func(cfg *aws.Config, configs Configs) error + +// Configs is a slice of Config values. These values will be used by the +// AWSConfigResolvers to extract external configuration values to populate the +// AWS Config type. +// +// Use AppendFromLoaders to add additional external Config values that are +// loaded from external sources. +// +// Use ResolveAWSConfig after external Config values have been added or loaded +// to extract the loaded configuration values into the AWS Config. +type Configs []Config + +// AppendFromLoaders iterates over the slice of loaders passed in calling each +// loader function in order. The external config value returned by the loader +// will be added to the returned Configs slice. +// +// If a loader returns an error this method will stop iterating and return +// that error. +func (cs Configs) AppendFromLoaders(loaders []ConfigLoader) (Configs, error) { + for _, fn := range loaders { + cfg, err := fn(cs) + if err != nil { + return nil, err + } + + cs = append(cs, cfg) + } + + return cs, nil +} + +// ResolveAWSConfig returns a AWS configuration populated with values by calling +// the resolvers slice passed in. Each resolver is called in order. Any resolver +// may overwrite the AWs Configuration value of a previous resolver. +// +// If an resolver returns an error this method will return that error, and stop +// iterating over the resolvers. +func (cs Configs) ResolveAWSConfig(resolvers []AWSConfigResolver) (aws.Config, error) { + var cfg aws.Config + + for _, fn := range resolvers { + if err := fn(&cfg, cs); err != nil { + // TODO provide better error? + return aws.Config{}, err + } + } + + return cfg, nil +} + +// LoadDefaultAWSConfig reads the SDK's default external configurations, and +// populates an AWS Config with the values from the external configurations. +// +// An optional variadic set of additional Config values can be provided as input +// that will be prepended to the Configs slice. Use this to add custom configuration. +// The custom configurations must satisfy the respective providers for their data +// or the custom data will be ignored by the resolvers and config loaders. +// +// cfg, err := external.LoadDefaultAWSConfig( +// WithSharedConfigProfile("test-profile"), +// ) +// if err != nil { +// panic(fmt.Sprintf("failed loading config, %v", err)) +// } +// +// +// The default configuration sources are: +// * Environment Variables +// * Shared Configuration and Shared Credentials files. +func LoadDefaultAWSConfig(configs ...Config) (aws.Config, error) { + var cfgs Configs + cfgs = append(cfgs, configs...) + + cfgs, err := cfgs.AppendFromLoaders(DefaultConfigLoaders) + if err != nil { + return aws.Config{}, err + } + + return cfgs.ResolveAWSConfig(DefaultAWSConfigResolvers) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/env_config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/env_config.go new file mode 100644 index 000000000..902252c46 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/env_config.go @@ -0,0 +1,236 @@ +package external + +import ( + "io/ioutil" + "os" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +// CredentialsSourceName provides a name of the provider when config is +// loaded from environment. +const CredentialsSourceName = "EnvConfigCredentials" + +// Environment variables that will be read for configuration values. +const ( + AWSAccessKeyIDEnvVar = "AWS_ACCESS_KEY_ID" + AWSAccessKeyEnvVar = "AWS_ACCESS_KEY" + + AWSSecreteAccessKeyEnvVar = "AWS_SECRET_ACCESS_KEY" + AWSSecreteKeyEnvVar = "AWS_SECRET_KEY" + + AWSSessionTokenEnvVar = "AWS_SESSION_TOKEN" + + AWSCredentialsEndpointEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" + + // TODO shorter name? + AWSContainerCredentialsEndpointPathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" + + AWSRegionEnvVar = "AWS_REGION" + AWSDefaultRegionEnvVar = "AWS_DEFAULT_REGION" + + AWSProfileEnvVar = "AWS_PROFILE" + AWSDefaultProfileEnvVar = "AWS_DEFAULT_PROFILE" + + AWSSharedCredentialsFileEnvVar = "AWS_SHARED_CREDENTIALS_FILE" + + AWSConfigFileEnvVar = "AWS_CONFIG_FILE" + + AWSCustomCABundleEnvVar = "AWS_CA_BUNDLE" +) + +var ( + credAccessEnvKeys = []string{ + AWSAccessKeyIDEnvVar, + AWSAccessKeyEnvVar, + } + credSecretEnvKeys = []string{ + AWSSecreteAccessKeyEnvVar, + AWSSecreteKeyEnvVar, + } + regionEnvKeys = []string{ + AWSRegionEnvVar, + AWSDefaultRegionEnvVar, + } + profileEnvKeys = []string{ + AWSProfileEnvVar, + AWSDefaultProfileEnvVar, + } +) + +// 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 + Credentials aws.Credentials + + // TODO doc + CredentialsEndpoint string + + // TODO doc, shorter name? + ContainerCredentialsEndpointPath string + + // 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-west-2 + // AWS_DEFAULT_REGION=us-west-2 + 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=my_profile + SharedConfigProfile string + + // 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 + + // Sets the path to a custom Credentials Authroity (CA) Bundle PEM file + // that the SDK will use instead of the system's root CA bundle. + // Only use this if you want to configure the SDK to use a custom set + // of CAs. + // + // Enabling this option will attempt to merge the Transport + // into the SDK's HTTP client. If the client's Transport is + // not a http.Transport an error will be returned. If the + // Transport's TLS config is set this option will cause the + // SDK to overwrite the Transport's TLS config's RootCAs value. + // + // Setting a custom HTTPClient in the aws.Config options will override this setting. + // To use this option and custom HTTP client, the HTTP client needs to be provided + // when creating the config. Not the service client. + // + // AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + CustomCABundle string +} + +// LoadEnvConfig reads configuration values from the OS's environment variables. +// Returning the a Config typed EnvConfig to satisfy the ConfigLoader func type. +func LoadEnvConfig(cfgs Configs) (Config, error) { + return NewEnvConfig() +} + +// NewEnvConfig retrieves the SDK's environment configuration. +// See `EnvConfig` for the values that will be retrieved. +func NewEnvConfig() (EnvConfig, error) { + var cfg EnvConfig + + creds := aws.Credentials{ + Source: CredentialsSourceName, + } + setFromEnvVal(&creds.AccessKeyID, credAccessEnvKeys) + setFromEnvVal(&creds.SecretAccessKey, credSecretEnvKeys) + if creds.HasKeys() { + creds.SessionToken = os.Getenv(AWSSessionTokenEnvVar) + cfg.Credentials = creds + } + + cfg.CredentialsEndpoint = os.Getenv(AWSCredentialsEndpointEnvVar) + cfg.ContainerCredentialsEndpointPath = os.Getenv(AWSContainerCredentialsEndpointPathEnvVar) + + setFromEnvVal(&cfg.Region, regionEnvKeys) + setFromEnvVal(&cfg.SharedConfigProfile, profileEnvKeys) + + cfg.SharedCredentialsFile = os.Getenv(AWSSharedCredentialsFileEnvVar) + cfg.SharedConfigFile = os.Getenv(AWSConfigFileEnvVar) + + cfg.CustomCABundle = os.Getenv(AWSCustomCABundleEnvVar) + + return cfg, nil +} + +// GetRegion returns the AWS Region if set in the environment. Returns an empty +// string if not set. +func (c EnvConfig) GetRegion() (string, error) { + return c.Region, nil +} + +// GetCredentialsValue returns the AWS Credentials if both AccessKey and ScreteAccessKey +// are set in the environment. Returns a zero value Credentials if not set. +func (c EnvConfig) GetCredentialsValue() (aws.Credentials, error) { + return c.Credentials, nil +} + +// GetSharedConfigProfile returns the shared config profile if set in the +// environment. Returns an empty string if not set. +func (c EnvConfig) GetSharedConfigProfile() (string, error) { + return c.SharedConfigProfile, nil +} + +// GetCredentialsEndpoint returns the credentials endpoint string if set. +func (c EnvConfig) GetCredentialsEndpoint() (string, error) { + return c.CredentialsEndpoint, nil +} + +// GetContainerCredentialsEndpointPath returns the container credentails endpoint +// path string if set. +func (c EnvConfig) GetContainerCredentialsEndpointPath() (string, error) { + return c.ContainerCredentialsEndpointPath, nil +} + +// GetSharedConfigFiles returns a slice of filenames set in the environment. +// +// Will return the filenames in the order of: +// * Shared Credentials +// * Shared Config +func (c EnvConfig) GetSharedConfigFiles() ([]string, error) { + files := make([]string, 0, 2) + if v := c.SharedCredentialsFile; len(v) > 0 { + files = append(files, v) + } + if v := c.SharedConfigFile; len(v) > 0 { + files = append(files, v) + } + + return files, nil +} + +// GetCustomCABundle returns the custom CA bundle's PEM bytes if the file was +func (c EnvConfig) GetCustomCABundle() ([]byte, error) { + if len(c.CustomCABundle) == 0 { + return nil, nil + } + + return ioutil.ReadFile(c.CustomCABundle) +} + +func setFromEnvVal(dst *string, keys []string) { + for _, k := range keys { + if v := os.Getenv(k); len(v) > 0 { + *dst = v + break + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/http_client.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/http_client.go new file mode 100644 index 000000000..71e9830b0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/http_client.go @@ -0,0 +1,42 @@ +package external + +import ( + "crypto/tls" + "crypto/x509" + "net/http" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +func addHTTPClientCABundle(client *http.Client, pemCerts []byte) error { + var t *http.Transport + + switch v := client.Transport.(type) { + case *http.Transport: + t = v + default: + if client.Transport != nil { + return awserr.New("LoadCustomCABundleError", + "unable to set custom CA bundle trasnsport must be http.Transport type", nil) + } + } + + if t == nil { + t = &http.Transport{} + } + if t.TLSClientConfig == nil { + t.TLSClientConfig = &tls.Config{} + } + if t.TLSClientConfig.RootCAs == nil { + t.TLSClientConfig.RootCAs = x509.NewCertPool() + } + + if !t.TLSClientConfig.RootCAs.AppendCertsFromPEM(pemCerts) { + return awserr.New("LoadCustomCABundleError", + "failed to load custom CA bundle PEM file", nil) + } + + client.Transport = t + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/local.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/local.go new file mode 100644 index 000000000..a555f42c0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/local.go @@ -0,0 +1,49 @@ +package external + +import ( + "fmt" + "net" + "net/url" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +var lookupHostFn = net.LookupHost + +func isLoopbackHost(host string) (bool, error) { + ip := net.ParseIP(host) + if ip != nil { + return ip.IsLoopback(), nil + } + + // Host is not an ip, perform lookup + addrs, err := lookupHostFn(host) + if err != nil { + return false, err + } + for _, addr := range addrs { + if !net.ParseIP(addr).IsLoopback() { + return false, nil + } + } + + return true, nil +} + +func validateLocalURL(v string) error { + u, err := url.Parse(v) + if err != nil { + return err + } + + host := aws.URLHostname(u) + if len(host) == 0 { + return fmt.Errorf("unable to parse host from local HTTP cred provider URL") + } else if isLoopback, err := isLoopbackHost(host); err != nil { + return fmt.Errorf("failed to resolve host %q, %v", host, err) + } else if !isLoopback { + return fmt.Errorf("invalid endpoint host, %q, only host resolving to loopback addresses are allowed", host) + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/provider.go new file mode 100644 index 000000000..54fe93243 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/provider.go @@ -0,0 +1,325 @@ +package external + +import ( + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/ec2metadata" +) + +// SharedConfigProfileProvider provides access to the shared config profile +// name external configuration value. +type SharedConfigProfileProvider interface { + GetSharedConfigProfile() (string, error) +} + +// WithSharedConfigProfile wraps a strings to satisfy the SharedConfigProfileProvider +// interface so a slice of custom shared config files ared used when loading the +// SharedConfig. +type WithSharedConfigProfile string + +// GetSharedConfigProfile returns the shared config profile. +func (c WithSharedConfigProfile) GetSharedConfigProfile() (string, error) { + return string(c), nil +} + +// GetSharedConfigProfile searchds the Configs for a SharedConfigProfileProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetSharedConfigProfile(configs Configs) (string, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(SharedConfigProfileProvider); ok { + v, err := p.GetSharedConfigProfile() + if err != nil { + return "", false, err + } + if len(v) > 0 { + return v, true, nil + } + } + } + + return "", false, nil +} + +// SharedConfigFilesProvider provides access to the shared config filesnames +// external configuration value. +type SharedConfigFilesProvider interface { + GetSharedConfigFiles() ([]string, error) +} + +// WithSharedConfigFiles wraps a slice of strings to satisfy the +// SharedConfigFilesProvider interface so a slice of custom shared config files +// ared used when loading the SharedConfig. +type WithSharedConfigFiles []string + +// GetSharedConfigFiles returns the slice of shared config files. +func (c WithSharedConfigFiles) GetSharedConfigFiles() ([]string, error) { + return []string(c), nil +} + +// GetSharedConfigFiles searchds the Configs for a SharedConfigFilesProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetSharedConfigFiles(configs Configs) ([]string, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(SharedConfigFilesProvider); ok { + v, err := p.GetSharedConfigFiles() + if err != nil { + return nil, false, err + } + if len(v) > 0 { + return v, true, nil + } + } + } + + return nil, false, nil +} + +// CustomCABundleProvider provides access to the custom CA bundle PEM bytes. +type CustomCABundleProvider interface { + GetCustomCABundle() ([]byte, error) +} + +// WithCustomCABundle provides wrapping of a region string to satisfy the +// CustomCABundleProvider interface. +type WithCustomCABundle []byte + +// GetCustomCABundle returns the CA bundle PEM bytes. +func (v WithCustomCABundle) GetCustomCABundle() ([]byte, error) { + return []byte(v), nil +} + +// GetCustomCABundle searchds the Configs for a CustomCABundleProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetCustomCABundle(configs Configs) ([]byte, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(CustomCABundleProvider); ok { + v, err := p.GetCustomCABundle() + if err != nil { + return nil, false, err + } + if len(v) > 0 { + return v, true, nil + } + } + } + + return nil, false, nil +} + +// RegionProvider provides access to the region external configuration value. +type RegionProvider interface { + GetRegion() (string, error) +} + +// WithRegion provides wrapping of a region string to satisfy the RegionProvider +// interface. +type WithRegion string + +// GetRegion returns the region string. +func (v WithRegion) GetRegion() (string, error) { + return string(v), nil +} + +// GetRegion searchds the Configs for a RegionProvider and returns the value +// if found. Returns an error if a provider fails before a value is found. +func GetRegion(configs Configs) (string, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(RegionProvider); ok { + v, err := p.GetRegion() + if err != nil { + return "", false, err + } + if len(v) > 0 { + return v, true, nil + } + } + } + + return "", false, nil +} + +// CredentialsValueProvider provides access to the credentials external +// configuration value. +type CredentialsValueProvider interface { + GetCredentialsValue() (aws.Credentials, error) +} + +// WithCredentialsValue provides wrapping of a credentials Value to satisfy the +// CredentialsValueProvider interface. +type WithCredentialsValue aws.Credentials + +// GetCredentialsValue returns the credentials value. +func (v WithCredentialsValue) GetCredentialsValue() (aws.Credentials, error) { + return aws.Credentials(v), nil +} + +// GetCredentialsValue searchds the Configs for a CredentialsValueProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetCredentialsValue(configs Configs) (aws.Credentials, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(CredentialsValueProvider); ok { + v, err := p.GetCredentialsValue() + if err != nil { + return aws.Credentials{}, false, err + } + if v.HasKeys() { + return v, true, nil + } + } + } + + return aws.Credentials{}, false, nil +} + +// CredentialsEndpointProvider provides access to the credentials endpoint +// external configuration value. +type CredentialsEndpointProvider interface { + GetCredentialsEndpoint() (string, error) +} + +// WithCredentialsEndpoint provides wrapping of a string to satisfy the +// CredentialsEndpointProvider interface. +type WithCredentialsEndpoint string + +// GetCredentialsEndpoint returns the endpoint. +func (p WithCredentialsEndpoint) GetCredentialsEndpoint() (string, error) { + return string(p), nil +} + +// GetCredentialsEndpoint searchds the Configs for a CredentialsEndpointProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetCredentialsEndpoint(configs Configs) (string, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(CredentialsEndpointProvider); ok { + v, err := p.GetCredentialsEndpoint() + if err != nil { + return "", false, err + } + if len(v) > 0 { + return v, true, nil + } + } + } + + return "", false, nil +} + +// ContainerCredentialsEndpointPathProvider provides access to the credentials endpoint path +// external configuration value. +type ContainerCredentialsEndpointPathProvider interface { + GetContainerCredentialsEndpointPath() (string, error) +} + +// WithContainerCredentialsEndpointPath provides wrapping of a string to satisfy the +// ContainerCredentialsEndpointPathProvider interface. +type WithContainerCredentialsEndpointPath string + +// GetContainerCredentialsEndpointPath returns the endpoint path. +func (p WithContainerCredentialsEndpointPath) GetContainerCredentialsEndpointPath() (string, error) { + return string(p), nil +} + +// GetContainerCredentialsEndpointPath searchds the Configs for a +// ContainerCredentialsEndpointPathProvider and returns the value if found. +// Returns an error if a provider fails before a +// value is found. +func GetContainerCredentialsEndpointPath(configs Configs) (string, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(ContainerCredentialsEndpointPathProvider); ok { + v, err := p.GetContainerCredentialsEndpointPath() + if err != nil { + return "", false, err + } + if len(v) > 0 { + return v, true, nil + } + } + } + + return "", false, nil +} + +// AssumeRoleConfigProvider provides access to the assume role config +// external configuration value. +type AssumeRoleConfigProvider interface { + GetAssumeRoleConfig() (AssumeRoleConfig, error) +} + +// WithAssumeRoleConfig provides wrapping of a string to satisfy the +// AssumeRoleConfigProvider interface. +type WithAssumeRoleConfig AssumeRoleConfig + +// GetAssumeRoleConfig returns the AssumeRoleConfig. +func (p WithAssumeRoleConfig) GetAssumeRoleConfig() (AssumeRoleConfig, error) { + return AssumeRoleConfig(p), nil +} + +// GetAssumeRoleConfig searchds the Configs for a AssumeRoleConfigProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetAssumeRoleConfig(configs Configs) (AssumeRoleConfig, bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(AssumeRoleConfigProvider); ok { + v, err := p.GetAssumeRoleConfig() + if err != nil { + return AssumeRoleConfig{}, false, err + } + if len(v.RoleARN) > 0 && v.Source != nil { + return v, true, nil + } + } + } + + return AssumeRoleConfig{}, false, nil +} + +// MFATokenFuncProvider provides access to the MFA token function needed for +// Assume Role with MFA. +type MFATokenFuncProvider interface { + GetMFATokenFunc() (func() (string, error), error) +} + +// WithMFATokenFunc provides wrapping of a string to satisfy the +// MFATokenFuncProvider interface. +type WithMFATokenFunc func() (string, error) + +// GetMFATokenFunc returns the MFA Token function. +func (p WithMFATokenFunc) GetMFATokenFunc() (func() (string, error), error) { + return p, nil +} + +// GetMFATokenFunc searchds the Configs for a MFATokenFuncProvider +// and returns the value if found. Returns an error if a provider fails before a +// value is found. +func GetMFATokenFunc(configs Configs) (func() (string, error), bool, error) { + for _, cfg := range configs { + if p, ok := cfg.(MFATokenFuncProvider); ok { + v, err := p.GetMFATokenFunc() + if err != nil { + return nil, false, err + } + if v != nil { + return v, true, nil + } + } + } + + return nil, false, nil +} + +// WithEC2MetadataRegion provides a RegionProvider that retrieves the region +// from the EC2 Metadata service. +// +// TODO add this provider to the default config loading? +type WithEC2MetadataRegion struct { + Client *ec2metadata.EC2Metadata +} + +// GetRegion attempts to retreive the region from EC2 Metadata service. +func (p WithEC2MetadataRegion) GetRegion() (string, error) { + return p.Client.Region() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/resolve.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/resolve.go new file mode 100644 index 000000000..9eff51adc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/resolve.go @@ -0,0 +1,216 @@ +package external + +import ( + "fmt" + "net/http" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/defaults" + "github.com/aws/aws-sdk-go-v2/aws/ec2metadata" + "github.com/aws/aws-sdk-go-v2/aws/ec2rolecreds" + "github.com/aws/aws-sdk-go-v2/aws/endpointcreds" + "github.com/aws/aws-sdk-go-v2/aws/stscreds" + "github.com/aws/aws-sdk-go-v2/service/sts" +) + +// ResolveDefaultAWSConfig will write default configuration values into the cfg +// value. It will write the default values, overwriting any previous value. +// +// This should be used as the first resolver in the slice of resolvers when +// resolving external configuration. +func ResolveDefaultAWSConfig(cfg *aws.Config, configs Configs) error { + *cfg = defaults.Config() + return nil +} + +// ResolveCustomCABundle extracts the first instance of a custom CA bundle filename +// from the external configurations. It will update the HTTP Client's builder +// to be configured with the custom CA bundle. +// +// Config provider used: +// * CustomCABundleProvider +func ResolveCustomCABundle(cfg *aws.Config, configs Configs) error { + v, found, err := GetCustomCABundle(configs) + if err != nil { + // TODO error handling, What is the best way to handle this? + // capture previous errors continue. error out if all errors + return err + } + if !found { + return nil + } + + return addHTTPClientCABundle(cfg.HTTPClient, v) +} + +// ResolveRegion extracts the first instance of a Region from the Configs slice. +// +// Config providers used: +// * RegionProvider +func ResolveRegion(cfg *aws.Config, configs Configs) error { + v, found, err := GetRegion(configs) + if err != nil { + // TODO error handling, What is the best way to handle this? + // capture previous errors continue. error out if all errors + return err + } + if !found { + return nil + } + + cfg.Region = v + return nil +} + +// ResolveCredentialsValue extracts the first instance of Credentials from the +// config slices. +// +// Config providers used: +// * CredentialsValueProvider +func ResolveCredentialsValue(cfg *aws.Config, configs Configs) error { + v, found, err := GetCredentialsValue(configs) + if err != nil { + // TODO error handling, What is the best way to handle this? + // capture previous errors continue. error out if all errors + return err + } + if !found { + return nil + } + + cfg.Credentials = aws.StaticCredentialsProvider{Value: v} + + return nil +} + +// ResolveEndpointCredentials will extract the credentials endpoint from the config +// slice. Using the endpoint, provided, to create a endpoint credential provider. +// +// Config providers used: +// * CredentialsEndpointProvider +func ResolveEndpointCredentials(cfg *aws.Config, configs Configs) error { + v, found, err := GetCredentialsEndpoint(configs) + if err != nil { + // TODO error handling, What is the best way to handle this? + // capture previous errors continue. error out if all errors + return err + } + if !found { + return nil + } + + if err := validateLocalURL(v); err != nil { + return err + } + + cfgCp := cfg.Copy() + cfgCp.EndpointResolver = aws.ResolveWithEndpointURL(v) + + provider := endpointcreds.New(cfgCp) + provider.ExpiryWindow = 5 * time.Minute + + cfg.Credentials = provider + + return nil +} + +const containerCredentialsEndpoint = "http://169.254.170.2" + +// ResolveContainerEndpointPathCredentials will extract the container credentials +// endpoint from the config slice. Using the endpoint provided, to create a +// endpoint credential provider. +// +// Config providers used: +// * ContainerCredentialsEndpointPathProvider +func ResolveContainerEndpointPathCredentials(cfg *aws.Config, configs Configs) error { + v, found, err := GetContainerCredentialsEndpointPath(configs) + if err != nil { + // TODO error handling, What is the best way to handle this? + // capture previous errors continue. error out if all errors + return err + } + if !found { + return nil + } + + cfgCp := cfg.Copy() + + v = containerCredentialsEndpoint + v + cfgCp.EndpointResolver = aws.ResolveWithEndpointURL(v) + + provider := endpointcreds.New(cfgCp) + provider.ExpiryWindow = 5 * time.Minute + + cfg.Credentials = provider + + return nil +} + +// ResolveAssumeRoleCredentials extracts the assume role configuration from +// the external configurations. +// +// Config providers used: +func ResolveAssumeRoleCredentials(cfg *aws.Config, configs Configs) error { + v, found, err := GetAssumeRoleConfig(configs) + if err != nil { + // TODO error handling, What is the best way to handle this? + // capture previous errors continue. error out if all errors + return err + } + if !found { + return nil + } + + cfgCp := cfg.Copy() + // TODO support additional credential providers that are already set? + cfgCp.Credentials = aws.StaticCredentialsProvider{Value: v.Source.Credentials} + + provider := stscreds.NewAssumeRoleProvider( + sts.New(cfgCp), v.RoleARN, + ) + provider.RoleSessionName = v.RoleSessionName + + if id := v.ExternalID; len(id) > 0 { + provider.ExternalID = aws.String(id) + } + if len(v.MFASerial) > 0 { + tp, foundTP, err := GetMFATokenFunc(configs) + if err != nil { + return err + } + if !foundTP { + return fmt.Errorf("token provider required for AssumeRole with MFA") + } + provider.SerialNumber = aws.String(v.MFASerial) + provider.TokenProvider = tp + } + + cfg.Credentials = provider + + return nil +} + +// ResolveFallbackEC2Credentials will configure the AWS config credentials to +// use EC2 Instance Role always. +func ResolveFallbackEC2Credentials(cfg *aws.Config, configs Configs) error { + cfgCp := cfg.Copy() + cfgCp.HTTPClient = shallowCopyHTTPClient(cfgCp.HTTPClient) + cfgCp.HTTPClient.Timeout = 5 * time.Second + + provider := ec2rolecreds.NewProvider(ec2metadata.New(cfgCp)) + provider.ExpiryWindow = 5 * time.Minute + + cfg.Credentials = provider + + return nil +} + +func shallowCopyHTTPClient(client *http.Client) *http.Client { + return &http.Client{ + Transport: client.Transport, + CheckRedirect: client.CheckRedirect, + Jar: client.Jar, + Timeout: client.Timeout, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/external/shared_config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/shared_config.go new file mode 100644 index 000000000..30c1da4c9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/external/shared_config.go @@ -0,0 +1,430 @@ +package external + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "runtime" + + "github.com/aws/aws-sdk-go-v2/aws" + "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. +var DefaultSharedConfigProfile = `default` + +// DefaultSharedCredentialsFilename returns the SDK's default file path +// for the shared credentials file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/credentials +// - Windows: %USERPROFILE%\.aws\credentials +func DefaultSharedCredentialsFilename() string { + return filepath.Join(userHomeDir(), ".aws", "credentials") +} + +// DefaultSharedConfigFilename returns the SDK's default file path for +// the shared config file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/config +// - Windows: %USERPROFILE%\.aws\config +func DefaultSharedConfigFilename() string { + return filepath.Join(userHomeDir(), ".aws", "config") +} + +// DefaultSharedConfigFiles is a slice of the default shared config files that +// the will be used in order to load the SharedConfig. +var DefaultSharedConfigFiles = []string{ + DefaultSharedCredentialsFilename(), + DefaultSharedConfigFilename(), +} + +// AssumeRoleConfig provides the values defining the configuration for an IAM +// assume role. +type AssumeRoleConfig struct { + RoleARN string + ExternalID string + MFASerial string + RoleSessionName string + + sourceProfile string + Source *SharedConfig +} + +// SharedConfig represents the configuration fields of the SDK config files. +type SharedConfig struct { + Profile string + + // 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 + Credentials aws.Credentials + + AssumeRole AssumeRoleConfig + + // Region is the region the SDK should use for looking up AWS service endpoints + // and signing requests. + // + // region + Region string +} + +// GetRegion returns the region for the profile if a region is set. +func (c SharedConfig) GetRegion() (string, error) { + return c.Region, nil +} + +// GetCredentialsValue returns the credentials for a profile if they were set. +func (c SharedConfig) GetCredentialsValue() (aws.Credentials, error) { + return c.Credentials, nil +} + +// GetAssumeRoleConfig returns the assume role config for a profile. Will be +// a zero value if not set. +func (c SharedConfig) GetAssumeRoleConfig() (AssumeRoleConfig, error) { + return c.AssumeRole, nil +} + +// LoadSharedConfigIgnoreNotExist is an alias for LoadSharedConfig with the +// addition of ignoring when none of the files exist or when the profile +// is not found in any of the files. +func LoadSharedConfigIgnoreNotExist(configs Configs) (Config, error) { + cfg, err := LoadSharedConfig(configs) + if err != nil { + if _, ok := err.(SharedConfigNotExistErrors); ok { + return SharedConfig{}, nil + } + return nil, err + } + + return cfg, nil +} + +// LoadSharedConfig uses the Configs passed in to load the SharedConfig from file +// The file names and profile name are sourced from the Configs. +// +// If profile name is not provided DefaultSharedConfigProfile (default) will +// be used. +// +// If shared config filenames are not provided DefaultSharedConfigFiles will +// be used. +// +// Config providers used: +// * SharedConfigProfileProvider +// * SharedConfigFilesProvider +func LoadSharedConfig(configs Configs) (Config, error) { + var profile string + var files []string + var ok bool + var err error + + profile, ok, err = GetSharedConfigProfile(configs) + if err != nil { + return nil, err + } + if !ok { + profile = DefaultSharedConfigProfile + } + + files, ok, err = GetSharedConfigFiles(configs) + if err != nil { + return nil, err + } + if !ok { + files = DefaultSharedConfigFiles + } + + return NewSharedConfig(profile, files) +} + +// NewSharedConfig 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. +func NewSharedConfig(profile string, filenames []string) (SharedConfig, error) { + if len(filenames) == 0 { + return SharedConfig{}, fmt.Errorf("no shared config files provided") + } + + 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 +} + +type sharedConfigFile struct { + Filename string + IniData *ini.File +} + +func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) { + files := make([]sharedConfigFile, 0, len(filenames)) + + errs := SharedConfigNotExistErrors{} + for _, filename := range filenames { + b, err := ioutil.ReadFile(filename) + if err != nil { + if os.IsNotExist(err) { + errs = append(errs, + SharedConfigFileNotExistError{Filename: filename, Err: err}, + ) + continue + } + return nil, SharedConfigLoadError{Filename: filename, Err: err} + } + + f, err := ini.Load(b) + if err != nil { + return nil, SharedConfigLoadError{Filename: filename, Err: err} + } + + files = append(files, sharedConfigFile{ + Filename: filename, IniData: f, + }) + } + + if len(files) == 0 { + return nil, errs + } + + return files, nil +} + +func (c *SharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error { + var assumeRoleSrc SharedConfig + + // Multiple level assume role chains are not support + if c.AssumeRole.sourceProfile == origProfile { + assumeRoleSrc = *c + assumeRoleSrc.AssumeRole = AssumeRoleConfig{} + } else { + err := assumeRoleSrc.setFromIniFiles(c.AssumeRole.sourceProfile, files) + if err != nil { + return SharedConfigAssumeRoleError{ + Profile: c.Profile, + RoleARN: c.AssumeRole.RoleARN, + Err: err, + } + } + } + + if len(assumeRoleSrc.Credentials.AccessKeyID) == 0 { + return SharedConfigAssumeRoleError{ + Profile: c.Profile, + RoleARN: c.AssumeRole.RoleARN, + Err: fmt.Errorf("source profile has no shared credentials"), + } + } + + c.AssumeRole.Source = &assumeRoleSrc + + return nil +} + +// Returns an error if all of the files fail to load. If at least one file is +// successfully loaded and contains the profile, no error will be returned. +func (c *SharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error { + c.Profile = profile + + existErrs := SharedConfigNotExistErrors{} + for _, f := range files { + if err := c.setFromIniFile(profile, f); err != nil { + if _, ok := err.(SharedConfigProfileNotExistError); ok { + existErrs = append(existErrs, err) + continue + } + return err + } + } + + if len(existErrs) == len(files) { + return existErrs + } + + 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 (c *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 SharedConfigProfileNotExistError{ + Filename: file.Filename, + Profile: profile, + Err: err, + } + } + } + + // Shared Credentials + akid := section.Key(accessKeyIDKey).String() + secret := section.Key(secretAccessKey).String() + if len(akid) > 0 && len(secret) > 0 { + c.Credentials = aws.Credentials{ + AccessKeyID: akid, + SecretAccessKey: secret, + SessionToken: section.Key(sessionTokenKey).String(), + Source: 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 { + c.AssumeRole = AssumeRoleConfig{ + RoleARN: roleArn, + ExternalID: section.Key(externalIDKey).String(), + MFASerial: section.Key(mfaSerialKey).String(), + RoleSessionName: section.Key(roleSessionNameKey).String(), + + sourceProfile: srcProfile, + } + } + + // Region + if v := section.Key(regionKey).String(); len(v) > 0 { + c.Region = v + } + + return nil +} + +// SharedConfigNotExistErrors provides an error type for failure to load shared +// config because resources do not exist. +type SharedConfigNotExistErrors []error + +func (es SharedConfigNotExistErrors) Error() string { + msg := "failed to load shared config\n" + for _, e := range es { + msg += "\t" + e.Error() + } + return msg +} + +// SharedConfigLoadError is an error for the shared config file failed to load. +type SharedConfigLoadError struct { + Filename string + Err error +} + +// Cause is the underlying error that caused the failure. +func (e SharedConfigLoadError) Cause() error { + return e.Err +} + +func (e SharedConfigLoadError) Error() string { + return fmt.Sprintf("failed to load shared config file, %s, %v", e.Filename, e.Err) +} + +// SharedConfigFileNotExistError is an error for the shared config when +// the filename does not exist. +type SharedConfigFileNotExistError struct { + Filename string + Profile string + Err error +} + +// Cause is the underlying error that caused the failure. +func (e SharedConfigFileNotExistError) Cause() error { + return e.Err +} + +func (e SharedConfigFileNotExistError) Error() string { + return fmt.Sprintf("failed to open shared config file, %s, %v", e.Filename, e.Err) +} + +// SharedConfigProfileNotExistError is an error for the shared config when +// the profile was not find in the config file. +type SharedConfigProfileNotExistError struct { + Filename string + Profile string + Err error +} + +// Cause is the underlying error that caused the failure. +func (e SharedConfigProfileNotExistError) Cause() error { + return e.Err +} + +func (e SharedConfigProfileNotExistError) Error() string { + return fmt.Sprintf("failed to get shared config profile, %s, in %s, %v", e.Profile, e.Filename, 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 { + Profile string + RoleARN string + Err error +} + +func (e SharedConfigAssumeRoleError) Error() string { + return fmt.Sprintf("failed to load assume role %s, of profile %s, %v", + e.RoleARN, e.Profile, e.Err) +} + +func userHomeDir() string { + if runtime.GOOS == "windows" { // Windows + return os.Getenv("USERPROFILE") + } + + // *nix + return os.Getenv("HOME") +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/handlers.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/handlers.go new file mode 100644 index 000000000..be2b4535d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/handlers.go @@ -0,0 +1,256 @@ +package aws + +import ( + "fmt" + "strings" +) + +// A Handlers provides a collection of request handlers for various +// stages of handling requests. +type Handlers struct { + Validate HandlerList + Build HandlerList + Sign HandlerList + Send HandlerList + ValidateResponse HandlerList + Unmarshal HandlerList + UnmarshalMeta HandlerList + UnmarshalError HandlerList + Retry HandlerList + AfterRetry HandlerList + Complete HandlerList +} + +// Copy returns of this handler's lists. +func (h *Handlers) Copy() Handlers { + return Handlers{ + Validate: h.Validate.copy(), + Build: h.Build.copy(), + Sign: h.Sign.copy(), + Send: h.Send.copy(), + ValidateResponse: h.ValidateResponse.copy(), + Unmarshal: h.Unmarshal.copy(), + UnmarshalError: h.UnmarshalError.copy(), + UnmarshalMeta: h.UnmarshalMeta.copy(), + Retry: h.Retry.copy(), + AfterRetry: h.AfterRetry.copy(), + Complete: h.Complete.copy(), + } +} + +// Clear removes callback functions for all handlers +func (h *Handlers) Clear() { + h.Validate.Clear() + h.Build.Clear() + h.Send.Clear() + h.Sign.Clear() + h.Unmarshal.Clear() + h.UnmarshalMeta.Clear() + h.UnmarshalError.Clear() + h.ValidateResponse.Clear() + h.Retry.Clear() + h.AfterRetry.Clear() + h.Complete.Clear() +} + +// A HandlerListRunItem represents an entry in the HandlerList which +// is being run. +type HandlerListRunItem struct { + Index int + Handler NamedHandler + Request *Request +} + +// A HandlerList manages zero or more handlers in a list. +type HandlerList struct { + list []NamedHandler + + // Called after each request handler in the list is called. If set + // and the func returns true the HandlerList will continue to iterate + // over the request handlers. If false is returned the HandlerList + // will stop iterating. + // + // Should be used if extra logic to be performed between each handler + // in the list. This can be used to terminate a list's iteration + // based on a condition such as error like, HandlerListStopOnError. + // Or for logging like HandlerListLogItem. + AfterEachFn func(item HandlerListRunItem) bool +} + +// A NamedHandler is a struct that contains a name and function callback. +type NamedHandler struct { + Name string + Fn func(*Request) +} + +// copy creates a copy of the handler list. +func (l *HandlerList) copy() HandlerList { + n := HandlerList{ + AfterEachFn: l.AfterEachFn, + } + if len(l.list) == 0 { + return n + } + + n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...) + return n +} + +// Clear clears the handler list. +func (l *HandlerList) Clear() { + l.list = l.list[0:0] +} + +// Len returns the number of handlers in the list. +func (l *HandlerList) Len() int { + return len(l.list) +} + +// PushBack pushes handler f to the back of the handler list. +func (l *HandlerList) PushBack(f func(*Request)) { + l.PushBackNamed(NamedHandler{"__anonymous", f}) +} + +// PushBackNamed pushes named handler f to the back of the handler list. +func (l *HandlerList) PushBackNamed(n NamedHandler) { + if cap(l.list) == 0 { + l.list = make([]NamedHandler, 0, 5) + } + l.list = append(l.list, n) +} + +// PushFront pushes handler f to the front of the handler list. +func (l *HandlerList) PushFront(f func(*Request)) { + l.PushFrontNamed(NamedHandler{"__anonymous", f}) +} + +// PushFrontNamed pushes named handler f to the front of the handler list. +func (l *HandlerList) PushFrontNamed(n NamedHandler) { + if cap(l.list) == len(l.list) { + // Allocating new list required + l.list = append([]NamedHandler{n}, l.list...) + } else { + // Enough room to prepend into list. + l.list = append(l.list, NamedHandler{}) + copy(l.list[1:], l.list) + l.list[0] = n + } +} + +// Remove removes a NamedHandler n +func (l *HandlerList) Remove(n NamedHandler) { + l.RemoveByName(n.Name) +} + +// RemoveByName removes a NamedHandler by name. +func (l *HandlerList) RemoveByName(name string) { + for i := 0; i < len(l.list); i++ { + m := l.list[i] + if m.Name == name { + // Shift array preventing creating new arrays + copy(l.list[i:], l.list[i+1:]) + l.list[len(l.list)-1] = NamedHandler{} + l.list = l.list[:len(l.list)-1] + + // decrement list so next check to length is correct + i-- + } + } +} + +// SwapNamed will swap out any existing handlers with the same name as the +// passed in NamedHandler returning true if handlers were swapped. False is +// returned otherwise. +func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) { + for i := 0; i < len(l.list); i++ { + if l.list[i].Name == n.Name { + l.list[i].Fn = n.Fn + swapped = true + } + } + + return swapped +} + +// SetBackNamed will replace the named handler if it exists in the handler list. +// If the handler does not exist the handler will be added to the end of the list. +func (l *HandlerList) SetBackNamed(n NamedHandler) { + if !l.SwapNamed(n) { + l.PushBackNamed(n) + } +} + +// SetFrontNamed will replace the named handler if it exists in the handler list. +// If the handler does not exist the handler will be added to the beginning of +// the list. +func (l *HandlerList) SetFrontNamed(n NamedHandler) { + if !l.SwapNamed(n) { + l.PushFrontNamed(n) + } +} + +// Run executes all handlers in the list with a given request object. +func (l *HandlerList) Run(r *Request) { + for i, h := range l.list { + h.Fn(r) + item := HandlerListRunItem{ + Index: i, Handler: h, Request: r, + } + if l.AfterEachFn != nil && !l.AfterEachFn(item) { + return + } + } +} + +// HandlerListLogItem logs the request handler and the state of the +// request's Error value. Always returns true to continue iterating +// request handlers in a HandlerList. +func HandlerListLogItem(item HandlerListRunItem) bool { + if item.Request.Config.Logger == nil { + return true + } + item.Request.Config.Logger.Log("DEBUG: RequestHandler", + item.Index, item.Handler.Name, item.Request.Error) + + return true +} + +// HandlerListStopOnError returns false to stop the HandlerList iterating +// over request handlers if Request.Error is not nil. True otherwise +// to continue iterating. +func HandlerListStopOnError(item HandlerListRunItem) bool { + return item.Request.Error == nil +} + +// WithAppendUserAgent will add a string to the user agent prefixed with a +// single white space. +func WithAppendUserAgent(s string) Option { + return func(r *Request) { + r.Handlers.Build.PushBack(func(r2 *Request) { + AddToUserAgent(r, s) + }) + } +} + +// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request +// header. If the extra parameters are provided they will be added as metadata to the +// name/version pair resulting in the following format. +// "name/version (extra0; extra1; ...)" +// The user agent part will be concatenated with this current request's user agent string. +func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) { + ua := fmt.Sprintf("%s/%s", name, version) + if len(extra) > 0 { + ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; ")) + } + return func(r *Request) { + AddToUserAgent(r, ua) + } +} + +// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header. +// The input string will be concatenated with the current request's user agent string. +func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) { + return func(r *Request) { + AddToUserAgent(r, s) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/http_request.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/http_request.go new file mode 100644 index 000000000..40dfe40d1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/http_request.go @@ -0,0 +1,24 @@ +package aws + +import ( + "io" + "net/http" + "net/url" +) + +func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { + req := new(http.Request) + *req = *r + req.URL = &url.URL{} + *req.URL = *r.URL + req.Body = body + + req.Header = http.Header{} + for k, v := range r.Header { + for _, vv := range v { + req.Header.Add(k, vv) + } + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/jsonvalue.go new file mode 100644 index 000000000..91a6f277a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/jsonvalue.go @@ -0,0 +1,12 @@ +package aws + +// JSONValue is a representation of a grab bag type that will be marshaled +// into a json string. This type can be used just like any other map. +// +// Example: +// +// values := aws.JSONValue{ +// "Foo": "Bar", +// } +// values["Baz"] = "Qux" +type JSONValue map[string]interface{} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/logger.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/logger.go new file mode 100644 index 000000000..189e5201e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/logger.go @@ -0,0 +1,97 @@ +package aws + +import ( + "log" + "os" +) + +// A LogLevel defines the level logging should be performed at. Used to instruct +// the SDK which statements should be logged. +type LogLevel uint + +// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be +// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If +// LogLevel is nil, will default to LogOff comparison. +func (l LogLevel) Matches(v LogLevel) bool { + return l&v == v +} + +// AtLeast returns true if this LogLevel is at least high enough to satisfies v. +// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default +// to LogOff comparison. +func (l LogLevel) AtLeast(v LogLevel) bool { + return l >= v +} + +const ( + // LogOff states that no logging should be performed by the SDK. This is the + // default state of the SDK, and should be use to disable all logging. + LogOff LogLevel = iota * 0x1000 + + // LogDebug state that debug output should be logged by the SDK. This should + // be used to inspect request made and responses received. + LogDebug +) + +// Debug Logging Sub Levels +const ( + // LogDebugWithSigning states that the SDK should log request signing and + // presigning events. This should be used to log the signing details of + // requests for debugging. Will also enable LogDebug. + LogDebugWithSigning LogLevel = LogDebug | (1 << iota) + + // LogDebugWithHTTPBody states the SDK should log HTTP request and response + // HTTP bodys in addition to the headers and path. This should be used to + // see the body content of requests and responses made while using the SDK + // Will also enable LogDebug. + LogDebugWithHTTPBody + + // LogDebugWithRequestRetries states the SDK should log when service requests will + // be retried. This should be used to log when you want to log when service + // requests are being retried. Will also enable LogDebug. + LogDebugWithRequestRetries + + // LogDebugWithRequestErrors states the SDK should log when service requests fail + // to build, send, validate, or unmarshal. + LogDebugWithRequestErrors +) + +// A Logger is a minimalistic interface for the SDK to log messages to. Should +// be used to provide custom logging writers for the SDK to use. +type Logger interface { + Log(...interface{}) +} + +// A LoggerFunc is a convenience type to convert a function taking a variadic +// list of arguments and wrap it so the Logger interface can be used. +// +// Example: +// s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) { +// fmt.Fprintln(os.Stdout, args...) +// })}) +type LoggerFunc func(...interface{}) + +// Log calls the wrapped function with the arguments provided +func (f LoggerFunc) Log(args ...interface{}) { + f(args...) +} + +// NewDefaultLogger returns a Logger which will write log messages to stdout, and +// use same formatting runes as the stdlib log.Logger +// +// TODO remove, moved to default pkg +func NewDefaultLogger() Logger { + return &defaultLogger{ + logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +// A defaultLogger provides a minimalistic logger satisfying the Logger interface. +type defaultLogger struct { + logger *log.Logger +} + +// Log logs the parameters to the stdlib logger. See log.Println. +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/offset_reader.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/offset_reader.go new file mode 100644 index 000000000..cb4614cd3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/offset_reader.go @@ -0,0 +1,58 @@ +package aws + +import ( + "io" + "sync" +) + +// offsetReader is a thread-safe io.ReadCloser to prevent racing +// with retrying requests +type offsetReader struct { + buf io.ReadSeeker + lock sync.Mutex + closed bool +} + +func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader { + reader := &offsetReader{} + buf.Seek(offset, 0) + + reader.buf = buf + return reader +} + +// Close will close the instance of the offset reader's access to +// the underlying io.ReadSeeker. +func (o *offsetReader) Close() error { + o.lock.Lock() + defer o.lock.Unlock() + o.closed = true + return nil +} + +// Read is a thread-safe read of the underlying io.ReadSeeker +func (o *offsetReader) Read(p []byte) (int, error) { + o.lock.Lock() + defer o.lock.Unlock() + + if o.closed { + return 0, io.EOF + } + + return o.buf.Read(p) +} + +// Seek is a thread-safe seeking operation. +func (o *offsetReader) Seek(offset int64, whence int) (int64, error) { + o.lock.Lock() + defer o.lock.Unlock() + + return o.buf.Seek(offset, whence) +} + +// CloseAndCopy will return a new offsetReader with a copy of the old buffer +// and close the old buffer. +func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader { + o.Close() + return newOffsetReader(o.buf, offset) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/doc_1_7.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/doc_1_7.go new file mode 100644 index 000000000..5b269feeb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/doc_1_7.go @@ -0,0 +1,5 @@ +// +build !go1.8 + +// Package plugincreds provides usage of Go plugins for providing credentials +// to the SDK. Only available with Go 1.8 and above. +package plugincreds diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/provider.go new file mode 100644 index 000000000..cae8142c3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/plugincreds/provider.go @@ -0,0 +1,190 @@ +// +build go1.8 + +/* +Package plugincreds implements a credentials provider sourced from a Go +plugin. This package allows you to use a Go plugin to retrieve AWS credentials +for the SDK to use for service API calls. + +As of Go 1.8 plugins are only supported on the Linux platform. + +Plugin Symbol Name + +The "AWSSDKRetrieveCredentials" is the symbol name that will be used to +lookup the credentials provider getter from the plugin. If you want to use a +custom symbol name you should use GetRetrieveFnByName to lookup the +symbol by a custom name. + +This symbol is a function that returns two additional functions. One to +retrieve the credentials, and another to determine if the credentials have +expired. + +Plugin Symbol Signature + +The plugin credential provider requires the symbol to match the +following signature. + + func() (key, secret, token string, exp time.Time, err error) + +Plugin Implementation Exmaple + +The following is an example implementation of a SDK credential provider using +the plugin provider in this package. See the SDK's example/aws/credential/plugincreds/plugin +folder for a runnable example of this. + + func main() {} + + var myCredProvider provider + + // Build: go build -o plugin.so -buildmode=plugin plugin.go + func init() { + // Initialize a mock credential provider with stubs + myCredProvider = provider{"a","b","c"} + } + + // AWSSDKRetrieveCredentials is the symbol SDK will lookup and use to + // retrieve AWS credentials with. + func AWSSDKRetrieveCredentials() (key, secret, token string, exp time.Time, err error) { + key, secret, token, err = getCreds() + if err != nil { + return "", "", "", time.Time{}, err + } + + return key, secrete, token, time.Now().Add(2 * time.Hour), nil + } + + func getCreds() (key, secret, token string, err error){ + // Get credentials + return key, secret, token, err + } + +Configuring SDK for Plugin Credentials + +To configure the SDK to use a plugin's credential provider you'll need to first +open the plugin file using the plugin standard library package. Once you have a +handle to the plugin you can use the NewCredentials function of this package to +create a new credentials.Credentials value that can be set as the credentials +loader of a Session or Config. See the SDK's example/aws/credential/plugincreds +folder for a runnable example of this. + + // Open plugin, and load it into the process. + p, err := plugin.Open("somefile.so") + if err != nil { + return nil, err + } + + // Create a new Credentials value which will source the provider's Retrieve + // and IsExpired functions from the plugin. + creds, err := plugincreds.New(p) + if err != nil { + return nil, err + } + + cfg.Credentails = creds +*/ +package plugincreds + +import ( + "fmt" + "plugin" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// ProviderSymbolName the symbol name the SDK will use to retrieve the +// credentials from. +const ProviderSymbolName = `AWSSDKRetrieveCredentials` + +// ProviderName is the name this credentials provider will label any returned +// credentials Value with. +const ProviderName = `PluginCredentialsProvider` + +const ( + // ErrCodeLookupSymbolError failed to lookup symbol + ErrCodeLookupSymbolError = "LookupSymbolError" + + // ErrCodeInvalidSymbolError symbol invalid + ErrCodeInvalidSymbolError = "InvalidSymbolError" + + // ErrCodePluginRetrieveNil Retrieve function was nil + ErrCodePluginRetrieveNil = "PluginRetrieveNilError" + + // ErrCodePluginIsExpiredNil IsExpired Function was nil + ErrCodePluginIsExpiredNil = "PluginIsExpiredNilError" + + // ErrCodePluginProviderRetrieve plugin provider's retrieve returned error + ErrCodePluginProviderRetrieve = "PluginProviderRetrieveError" +) + +// Provider is the credentials provider that will use the plugin provided +// Retrieve and IsExpired functions to retrieve credentials. +type Provider struct { + aws.SafeCredentialsProvider +} + +// New returns a new Credentials loader using the plugin provider. +// If the symbol isn't found or is invalid in the plugin an error will be +// returned. +func New(p *plugin.Plugin) (*Provider, error) { + fn, err := GetRetrieveFn(p) + if err != nil { + return nil, err + } + + provider := &Provider{} + provider.RetrieveFn = buildRetrieveFn(fn) + + return provider, nil +} + +func buildRetrieveFn(fn func() (k, s, t string, ext time.Time, err error)) func() (aws.Credentials, error) { + return func() (aws.Credentials, error) { + k, s, t, exp, err := fn() + if err != nil { + return aws.Credentials{}, awserr.New(ErrCodePluginProviderRetrieve, + "failed to retrieve credentials with plugin provider", err) + } + + creds := aws.Credentials{ + AccessKeyID: k, + SecretAccessKey: s, + SessionToken: t, + Source: ProviderName, + + CanExpire: !exp.IsZero(), + Expires: exp, + } + + return creds, nil + } +} + +// GetRetrieveFn returns the plugin's Retrieve and IsExpired functions +// returned by the plugin's credential provider getter. +// +// Uses ProviderSymbolName as the symbol name when lookup up the symbol. If you +// want to use a different symbol name, use GetRetrieveFnByName. +func GetRetrieveFn(p *plugin.Plugin) (func() (key, secret, token string, exp time.Time, err error), error) { + return GetRetrieveFnByName(p, ProviderSymbolName) +} + +// GetRetrieveFnByName returns the plugin's Retrieve and IsExpired functions +// returned by the plugin's credential provider getter. +// +// Same as GetRetrieveFn, but takes a custom symbolName to lookup with. +func GetRetrieveFnByName(p *plugin.Plugin, symbolName string) (func() (key, secret, token string, exp time.Time, err error), error) { + sym, err := p.Lookup(symbolName) + if err != nil { + return nil, awserr.New(ErrCodeLookupSymbolError, + fmt.Sprintf("failed to lookup %s plugin provider symbol", symbolName), err) + } + + fn, ok := sym.(func() (key, secret, token string, exp time.Time, err error)) + if !ok { + return nil, awserr.New(ErrCodeInvalidSymbolError, + fmt.Sprintf("symbol %T, does not match the 'func() (key, secret, token string, exp time.Time, err error)' type", sym), nil) + } + + return fn, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request.go new file mode 100644 index 000000000..b180eb3b8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/request.go @@ -0,0 +1,587 @@ +package aws + +import ( + "bytes" + "fmt" + "io" + "net" + "net/http" + "net/url" + "reflect" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +const ( + // ErrCodeSerialization is the serialization error code that is received + // during protocol unmarshaling. + ErrCodeSerialization = "SerializationError" + + // ErrCodeRead is an error that is returned during HTTP reads. + ErrCodeRead = "ReadError" + + // ErrCodeResponseTimeout is the connection timeout error that is received + // during body reads. + ErrCodeResponseTimeout = "ResponseTimeout" + + // ErrCodeRequestCanceled is the error code that will be returned by an + // API request that was canceled. Requests given a Context may + // return this error when canceled. + ErrCodeRequestCanceled = "RequestCanceled" +) + +// A Request is the service request to be made. +type Request struct { + Config Config + Metadata Metadata + Handlers Handlers + + Retryer + Time time.Time + ExpireTime time.Duration + Operation *Operation + HTTPRequest *http.Request + HTTPResponse *http.Response + Body io.ReadSeeker + BodyStart int64 // offset from beginning of Body that the request body starts + Params interface{} + Error error + Data interface{} + RequestID string + RetryCount int + Retryable *bool + RetryDelay time.Duration + NotHoist bool + SignedHeaderVals http.Header + LastSignedAt time.Time + DisableFollowRedirects bool + + context Context + + built bool + + // Need to persist an intermediate body between the input Body and HTTP + // request body because the HTTP Client's transport can maintain a reference + // to the HTTP request's body after the client has returned. This value is + // safe to use concurrently and wrap the input Body for each HTTP request. + safeBody *offsetReader +} + +// An Operation is the service API operation to be made. +type Operation struct { + Name string + HTTPMethod string + HTTPPath string + *Paginator + + BeforePresignFn func(r *Request) error +} + +// New returns a new Request pointer for the service API +// operation and parameters. +// +// Params is any value of input parameters to be the request payload. +// Data is pointer value to an object which the request's response +// payload will be deserialized to. +func New(cfg Config, metadata Metadata, handlers Handlers, + retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request { + + // TODO improve this experiance for config copy? + cfg = cfg.Copy() + + method := operation.HTTPMethod + if method == "" { + method = "POST" + } + + httpReq, _ := http.NewRequest(method, "", nil) + + // TODO need better way of handling this error... NewRequest should return error. + endpoint, err := cfg.EndpointResolver.ResolveEndpoint(metadata.ServiceName, cfg.Region) + if err == nil { + // TODO so ugly + metadata.Endpoint = endpoint.URL + if len(endpoint.SigningName) > 0 && !endpoint.SigningNameDerived { + metadata.SigningName = endpoint.SigningName + } + if len(endpoint.SigningRegion) > 0 { + metadata.SigningRegion = endpoint.SigningRegion + } + + httpReq.URL, err = url.Parse(endpoint.URL + operation.HTTPPath) + if err != nil { + httpReq.URL = &url.URL{} + err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err) + } + } + + r := &Request{ + Config: cfg, + Metadata: metadata, + Handlers: handlers.Copy(), + + Retryer: retryer, + Time: time.Now(), + ExpireTime: 0, + Operation: operation, + HTTPRequest: httpReq, + Body: nil, + Params: params, + Error: err, + Data: data, + } + r.SetBufferBody([]byte{}) + + return r +} + +// A Option is a functional option that can augment or modify a request when +// using a WithContext API operation method. +type Option func(*Request) + +// WithGetResponseHeader builds a request Option which will retrieve a single +// header value from the HTTP Response. If there are multiple values for the +// header key use WithGetResponseHeaders instead to access the http.Header +// map directly. The passed in val pointer must be non-nil. +// +// This Option can be used multiple times with a single API operation. +// +// var id2, versionID string +// svc.PutObjectWithContext(ctx, params, +// request.WithGetResponseHeader("x-amz-id-2", &id2), +// request.WithGetResponseHeader("x-amz-version-id", &versionID), +// ) +func WithGetResponseHeader(key string, val *string) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *val = req.HTTPResponse.Header.Get(key) + }) + } +} + +// WithGetResponseHeaders builds a request Option which will retrieve the +// headers from the HTTP response and assign them to the passed in headers +// variable. The passed in headers pointer must be non-nil. +// +// var headers http.Header +// svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers)) +func WithGetResponseHeaders(headers *http.Header) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *headers = req.HTTPResponse.Header + }) + } +} + +// WithLogLevel is a request option that will set the request to use a specific +// log level when the request is made. +// +// svc.PutObjectWithContext(ctx, params, request.WithLogLevel(LogDebugWithHTTPBody) +func WithLogLevel(l LogLevel) Option { + return func(r *Request) { + r.Config.LogLevel = l + } +} + +// ApplyOptions will apply each option to the request calling them in the order +// the were provided. +func (r *Request) ApplyOptions(opts ...Option) { + for _, opt := range opts { + opt(r) + } +} + +// Context will always returns a non-nil context. If Request does not have a +// context BackgroundContext will be returned. +func (r *Request) Context() Context { + if r.context != nil { + return r.context + } + return BackgroundContext() +} + +// SetContext adds a Context to the current request that can be used to cancel +// a in-flight request. The Context value must not be nil, or this method will +// panic. +// +// Unlike http.Request.WithContext, SetContext does not return a copy of the +// Request. It is not safe to use use a single Request value for multiple +// requests. A new Request should be created for each API operation request. +// +// Go 1.6 and below: +// The http.Request's Cancel field will be set to the Done() value of +// the context. This will overwrite the Cancel field's value. +// +// Go 1.7 and above: +// The http.Request.WithContext will be used to set the context on the underlying +// http.Request. This will create a shallow copy of the http.Request. The SDK +// may create sub contexts in the future for nested requests such as retries. +func (r *Request) SetContext(ctx Context) { + if ctx == nil { + panic("context cannot be nil") + } + setRequestContext(r, ctx) +} + +// WillRetry returns if the request's can be retried. +func (r *Request) WillRetry() bool { + return r.Error != nil && BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() +} + +// ParamsFilled returns if the request's parameters have been populated +// and the parameters are valid. False is returned if no parameters are +// provided or invalid. +func (r *Request) ParamsFilled() bool { + return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid() +} + +// SetBufferBody will set the request's body bytes that will be sent to +// the service API. +func (r *Request) SetBufferBody(buf []byte) { + r.SetReaderBody(bytes.NewReader(buf)) +} + +// SetStringBody sets the body of the request to be backed by a string. +func (r *Request) SetStringBody(s string) { + r.SetReaderBody(strings.NewReader(s)) +} + +// SetReaderBody will set the request's body reader. +func (r *Request) SetReaderBody(reader io.ReadSeeker) { + r.Body = reader + r.ResetBody() +} + +// Presign returns the request's signed URL. Error will be returned +// if the signing fails. +func (r *Request) Presign(expireTime time.Duration) (string, error) { + r.ExpireTime = expireTime + r.NotHoist = false + + if r.Operation.BeforePresignFn != nil { + r = r.copy() + err := r.Operation.BeforePresignFn(r) + if err != nil { + return "", err + } + } + + r.Sign() + if r.Error != nil { + return "", r.Error + } + return r.HTTPRequest.URL.String(), nil +} + +// PresignRequest behaves just like presign, with the addition of returning a +// set of headers that were signed. +// +// Returns the URL string for the API operation with signature in the query string, +// and the HTTP headers that were included in the signature. These headers must +// be included in any HTTP request made with the presigned URL. +// +// To prevent hoisting any headers to the query string set NotHoist to true on +// this Request value prior to calling PresignRequest. +func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) { + r.ExpireTime = expireTime + r.Sign() + if r.Error != nil { + return "", nil, r.Error + } + return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil +} + +func debugLogReqError(r *Request, stage string, retrying bool, err error) { + if !r.Config.LogLevel.Matches(LogDebugWithRequestErrors) { + return + } + + retryStr := "not retrying" + if retrying { + retryStr = "will retry" + } + + r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v", + stage, r.Metadata.ServiceName, r.Operation.Name, retryStr, err)) +} + +// Build will build the request's object so it can be signed and sent +// to the service. Build will also validate all the request's parameters. +// Anny additional build Handlers set on this request will be run +// in the order they were set. +// +// The request will only be built once. Multiple calls to build will have +// no effect. +// +// If any Validate or Build errors occur the build will stop and the error +// which occurred will be returned. +func (r *Request) Build() error { + if !r.built { + r.Handlers.Validate.Run(r) + if r.Error != nil { + debugLogReqError(r, "Validate Request", false, r.Error) + return r.Error + } + r.Handlers.Build.Run(r) + if r.Error != nil { + debugLogReqError(r, "Build Request", false, r.Error) + return r.Error + } + r.built = true + } + + return r.Error +} + +// Sign will sign the request returning error if errors are encountered. +// +// Send will build the request prior to signing. All Sign Handlers will +// be executed in the order they were set. +func (r *Request) Sign() error { + r.Build() + if r.Error != nil { + debugLogReqError(r, "Build Request", false, r.Error) + return r.Error + } + + r.Handlers.Sign.Run(r) + return r.Error +} + +func (r *Request) getNextRequestBody() (io.ReadCloser, error) { + if r.safeBody != nil { + r.safeBody.Close() + } + + r.safeBody = newOffsetReader(r.Body, r.BodyStart) + + // Go 1.8 tightened and clarified the rules code needs to use when building + // requests with the http package. Go 1.8 removed the automatic detection + // of if the Request.Body was empty, or actually had bytes in it. The SDK + // always sets the Request.Body even if it is empty and should not actually + // be sent. This is incorrect. + // + // Go 1.8 did add a http.NoBody value that the SDK can use to tell the http + // client that the request really should be sent without a body. The + // Request.Body cannot be set to nil, which is preferable, because the + // field is exported and could introduce nil pointer dereferences for users + // of the SDK if they used that field. + // + // Related golang/go#18257 + l, err := computeBodyLength(r.Body) + if err != nil { + return nil, awserr.New(ErrCodeSerialization, "failed to compute request body size", err) + } + + var body io.ReadCloser + if l == 0 { + body = NoBody + } else if l > 0 { + body = r.safeBody + } else { + // Hack to prevent sending bodies for methods where the body + // should be ignored by the server. Sending bodies on these + // methods without an associated ContentLength will cause the + // request to socket timeout because the server does not handle + // Transfer-Encoding: chunked bodies for these methods. + // + // This would only happen if a ReaderSeekerCloser was used with + // a io.Reader that was not also an io.Seeker. + switch r.Operation.HTTPMethod { + case "GET", "HEAD", "DELETE": + body = NoBody + default: + body = r.safeBody + } + } + + return body, nil +} + +// Attempts to compute the length of the body of the reader using the +// io.Seeker interface. If the value is not seekable because of being +// a ReaderSeekerCloser without an unerlying Seeker -1 will be returned. +// If no error occurs the length of the body will be returned. +func computeBodyLength(r io.ReadSeeker) (int64, error) { + seekable := true + // Determine if the seeker is actually seekable. ReaderSeekerCloser + // hides the fact that a io.Readers might not actually be seekable. + switch v := r.(type) { + case ReaderSeekerCloser: + seekable = v.IsSeeker() + case *ReaderSeekerCloser: + seekable = v.IsSeeker() + } + if !seekable { + return -1, nil + } + + curOffset, err := r.Seek(0, 1) + if err != nil { + return 0, err + } + + endOffset, err := r.Seek(0, 2) + if err != nil { + return 0, err + } + + _, err = r.Seek(curOffset, 0) + if err != nil { + return 0, err + } + + return endOffset - curOffset, nil +} + +// GetBody will return an io.ReadSeeker of the Request's underlying +// input body with a concurrency safe wrapper. +func (r *Request) GetBody() io.ReadSeeker { + return r.safeBody +} + +// Send will send the request returning error if errors are encountered. +// +// Send will sign the request prior to sending. All Send Handlers will +// be executed in the order they were set. +// +// Canceling a request is non-deterministic. If a request has been canceled, +// then the transport will choose, randomly, one of the state channels during +// reads or getting the connection. +// +// readLoop() and getConn(req *Request, cm connectMethod) +// https://github.com/golang/go/blob/master/src/net/http/transport.go +// +// Send will not close the request.Request's body. +func (r *Request) Send() error { + defer func() { + // Regardless of success or failure of the request trigger the Complete + // request handlers. + r.Handlers.Complete.Run(r) + }() + + for { + if BoolValue(r.Retryable) { + if r.Config.LogLevel.Matches(LogDebugWithRequestRetries) { + r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d", + r.Metadata.ServiceName, r.Operation.Name, r.RetryCount)) + } + + // The previous http.Request will have a reference to the r.Body + // and the HTTP Client's Transport may still be reading from + // the request's body even though the Client's Do returned. + r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil) + r.ResetBody() + + // Closing response body to ensure that no response body is leaked + // between retry attempts. + if r.HTTPResponse != nil && r.HTTPResponse.Body != nil { + r.HTTPResponse.Body.Close() + } + } + + r.Sign() + if r.Error != nil { + return r.Error + } + + r.Retryable = nil + + r.Handlers.Send.Run(r) + if r.Error != nil { + if !shouldRetryCancel(r) { + return r.Error + } + + err := r.Error + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + if r.Error != nil { + debugLogReqError(r, "Send Request", false, err) + return r.Error + } + debugLogReqError(r, "Send Request", true, err) + continue + } + r.Handlers.UnmarshalMeta.Run(r) + r.Handlers.ValidateResponse.Run(r) + if r.Error != nil { + r.Handlers.UnmarshalError.Run(r) + err := r.Error + + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + if r.Error != nil { + debugLogReqError(r, "Validate Response", false, err) + return r.Error + } + debugLogReqError(r, "Validate Response", true, err) + continue + } + + r.Handlers.Unmarshal.Run(r) + if r.Error != nil { + err := r.Error + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + if r.Error != nil { + debugLogReqError(r, "Unmarshal Response", false, err) + return r.Error + } + debugLogReqError(r, "Unmarshal Response", true, err) + continue + } + + break + } + + return nil +} + +// copy will copy a request which will allow for local manipulation of the +// request. +func (r *Request) copy() *Request { + req := &Request{} + *req = *r + req.Handlers = r.Handlers.Copy() + op := *r.Operation + req.Operation = &op + return req +} + +// AddToUserAgent adds the string to the end of the request's current user agent. +func AddToUserAgent(r *Request, s string) { + curUA := r.HTTPRequest.Header.Get("User-Agent") + if len(curUA) > 0 { + s = curUA + " " + s + } + r.HTTPRequest.Header.Set("User-Agent", s) +} + +func shouldRetryCancel(r *Request) bool { + awsErr, ok := r.Error.(awserr.Error) + timeoutErr := false + errStr := r.Error.Error() + if ok { + if awsErr.Code() == ErrCodeRequestCanceled { + return false + } + err := awsErr.OrigErr() + netErr, netOK := err.(net.Error) + timeoutErr = netOK && netErr.Temporary() + if urlErr, ok := err.(*url.Error); !timeoutErr && ok { + errStr = urlErr.Err.Error() + } + } + + // There can be two types of canceled errors here. + // The first being a net.Error and the other being an error. + // If the request was timed out, we want to continue the retry + // process. Otherwise, return the canceled error. + return timeoutErr || + (errStr != "net/http: request canceled" && + errStr != "net/http: request canceled while waiting for connection") + +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_7.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_7.go new file mode 100644 index 000000000..6db88c864 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_7.go @@ -0,0 +1,39 @@ +// +build !go1.8 + +package aws + +import "io" + +// NoBody is an io.ReadCloser with no bytes. Read always returns EOF +// and Close always returns nil. It can be used in an outgoing client +// request to explicitly signal that a request has zero bytes. +// An alternative, however, is to simply set Request.Body to nil. +// +// Copy of Go 1.8 NoBody type from net/http/http.go +type noBody struct{} + +func (noBody) Read([]byte) (int, error) { return 0, io.EOF } +func (noBody) Close() error { return nil } +func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil } + +// NoBody is an empty reader that will trigger the Go HTTP client to not include +// and body in the HTTP request. +var NoBody = noBody{} + +// ResetBody rewinds the request body back to its starting position, and +// set's the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +// +// ResetBody will automatically be called by the SDK's build handler, but if +// the request is being used directly ResetBody must be called before the request +// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically +// call ResetBody. +func (r *Request) ResetBody() { + body, err := r.getNextRequestBody() + if err != nil { + r.Error = err + return + } + + r.HTTPRequest.Body = body +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_8.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_8.go new file mode 100644 index 000000000..ad81c3d8b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_1_8.go @@ -0,0 +1,33 @@ +// +build go1.8 + +package aws + +import ( + "net/http" +) + +// NoBody is a http.NoBody reader instructing Go HTTP client to not include +// and body in the HTTP request. +var NoBody = http.NoBody + +// ResetBody rewinds the request body back to its starting position, and +// set's the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +// +// ResetBody will automatically be called by the SDK's build handler, but if +// the request is being used directly ResetBody must be called before the request +// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically +// call ResetBody. +// +// Will also set the Go 1.8's http.Request.GetBody member to allow retrying +// PUT/POST redirects. +func (r *Request) ResetBody() { + body, err := r.getNextRequestBody() + if err != nil { + r.Error = err + return + } + + r.HTTPRequest.Body = body + r.HTTPRequest.GetBody = r.getNextRequestBody +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request_context.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_context.go new file mode 100644 index 000000000..19fa4fbb7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_context.go @@ -0,0 +1,12 @@ +// +build go1.7 + +package aws + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx Context) { + r.context = ctx + r.HTTPRequest = r.HTTPRequest.WithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request_context_1_6.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_context_1_6.go new file mode 100644 index 000000000..0b333d25e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_context_1_6.go @@ -0,0 +1,12 @@ +// +build !go1.7 + +package aws + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx Context) { + r.context = ctx + r.HTTPRequest.Cancel = ctx.Done() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request_pagination.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_pagination.go new file mode 100644 index 000000000..15594c900 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/request_pagination.go @@ -0,0 +1,187 @@ +package aws + +import ( + "sync/atomic" + + "github.com/aws/aws-sdk-go-v2/internal/awsutil" +) + +// A Pager provides paginating of SDK API operations which are paginatable. +// Generally you should not use this type directly, but use the "Pages" API +// operations method to automatically perform pagination for you. Such as, +// "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods. +// +// Pagier differs from a Paginator type in that pagination is the type that +// does the pagination between API operations, and Paginator defines the +// configuration that will be used per page request. +// +// for p.Next() { +// data := p.CurrentPage().(*s3.ListObjectsOutput) +// // process the page's data +// } +// return p.Err() +// +// See service client API operation Pages methods for examples how the SDK will +// use the Pager type. +type Pager struct { + // Function to return a Request value for each pagination request. + // Any configuration or handlers that need to be applied to the request + // prior to getting the next page should be done here before the request + // returned. + // + // NewRequest should always be built from the same API operations. It is + // undefined if different API operations are returned on subsequent calls. + NewRequest func() (*Request, error) + + started bool + nextTokens []interface{} + + err error + curPage interface{} +} + +// hasNextPage will return true if Pager is able to determine that the API +// operation has additional pages. False will be returned if there are no more +// pages remaining. +// +// Will always return true if Next has not been called yet. +func (p *Pager) hasNextPage() bool { + return !(p.started && len(p.nextTokens) == 0) +} + +// Err returns the error Pager encountered when retrieving the next page. +func (p *Pager) Err() error { + return p.err +} + +// CurrentPage returns the current page. Page should only be called after a successful +// call to Next. It is undefined what Page will return if Page is called after +// Next returns false. +func (p *Pager) CurrentPage() interface{} { + return p.curPage +} + +// Next will attempt to retrieve the next page for the API operation. When a page +// is retrieved true will be returned. If the page cannot be retrieved, or there +// are no more pages false will be returned. +// +// Use the Page method to retrieve the current page data. The data will need +// to be cast to the API operation's output type. +// +// Use the Err method to determine if an error occurred if Page returns false. +func (p *Pager) Next() bool { + if !p.hasNextPage() { + return false + } + + req, err := p.NewRequest() + if err != nil { + p.err = err + return false + } + + if p.started { + for i, intok := range req.Operation.InputTokens { + awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i]) + } + } + p.started = true + + err = req.Send() + if err != nil { + p.err = err + return false + } + + p.nextTokens = req.nextPageTokens() + p.curPage = req.Data + + return true +} + +// A Paginator is the configuration data that defines how an API operation +// should be paginated. This type is used by the API service models to define +// the generated pagination config for service APIs. +// +// The Pager type is what provides iterating between pages of an API. It +// is only used to store the token metadata the SDK should use for performing +// pagination. +type Paginator struct { + InputTokens []string + OutputTokens []string + LimitToken string + TruncationToken string +} + +// nextPageTokens returns the tokens to use when asking for the next page of data. +func (r *Request) nextPageTokens() []interface{} { + if r.Operation.Paginator == nil { + return nil + } + if r.Operation.TruncationToken != "" { + tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) + if len(tr) == 0 { + return nil + } + + switch v := tr[0].(type) { + case *bool: + if !BoolValue(v) { + return nil + } + case bool: + if v == false { + return nil + } + } + } + + tokens := []interface{}{} + tokenAdded := false + for _, outToken := range r.Operation.OutputTokens { + vs, _ := awsutil.ValuesAtPath(r.Data, outToken) + + if len(vs) == 0 { + tokens = append(tokens, nil) + continue + } + v := vs[0] + + switch tv := v.(type) { + case *string: + if len(StringValue(tv)) == 0 { + tokens = append(tokens, nil) + continue + } + case string: + if len(tv) == 0 { + tokens = append(tokens, nil) + continue + } + } + + tokenAdded = true + tokens = append(tokens, v) + } + if !tokenAdded { + return nil + } + + return tokens +} + +// Ensure a deprecated item is only logged once instead of each time its used. +func logDeprecatedf(logger Logger, flag *int32, msg string) { + if logger == nil { + return + } + if atomic.CompareAndSwapInt32(flag, 0, 1) { + logger.Log(msg) + } +} + +var ( + logDeprecatedHasNextPage int32 + logDeprecatedNextPage int32 + logDeprecatedEachPage int32 +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/response.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/response.go new file mode 100644 index 000000000..ea7717bfe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/response.go @@ -0,0 +1,8 @@ +package aws + +// Response provides the response meta data for a SDK API request's response. +type Response struct { + // TODO these fields should be focused on response, not just embedded request value. + // Need refactor of request for this to be better. + Request *Request +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go new file mode 100644 index 000000000..36ec2948d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go @@ -0,0 +1,160 @@ +package aws + +import ( + "time" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// Retryer is an interface to control retry logic for a given service. +// The default implementation used by most services is the client.DefaultRetryer +// structure, which contains basic retry logic using exponential backoff. +type Retryer interface { + RetryRules(*Request) time.Duration + ShouldRetry(*Request) bool + MaxRetries() int +} + +// WithRetryer sets a config Retryer value to the given Config returning it +// for chaining. +func WithRetryer(cfg *Config, retryer Retryer) *Config { + cfg.Retryer = retryer + return cfg +} + +// retryableCodes is a collection of service response codes which are retry-able +// without any further action. +var retryableCodes = map[string]struct{}{ + "RequestError": {}, + "RequestTimeout": {}, + ErrCodeResponseTimeout: {}, + "RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout +} + +var throttleCodes = map[string]struct{}{ + "ProvisionedThroughputExceededException": {}, + "Throttling": {}, + "ThrottlingException": {}, + "RequestLimitExceeded": {}, + "RequestThrottled": {}, + "TooManyRequestsException": {}, // Lambda functions + "PriorRequestNotComplete": {}, // Route53 +} + +// credsExpiredCodes is a collection of error codes which signify the credentials +// need to be refreshed. Expired tokens require refreshing of credentials, and +// resigning before the request can be retried. +var credsExpiredCodes = map[string]struct{}{ + "ExpiredToken": {}, + "ExpiredTokenException": {}, + "RequestExpired": {}, // EC2 Only +} + +func isCodeThrottle(code string) bool { + _, ok := throttleCodes[code] + return ok +} + +func isCodeRetryable(code string) bool { + if _, ok := retryableCodes[code]; ok { + return true + } + + return isCodeExpiredCreds(code) +} + +func isCodeExpiredCreds(code string) bool { + _, ok := credsExpiredCodes[code] + return ok +} + +var validParentCodes = map[string]struct{}{ + ErrCodeSerialization: {}, + ErrCodeRead: {}, +} + +type temporaryError interface { + Temporary() bool +} + +func isNestedErrorRetryable(parentErr awserr.Error) bool { + if parentErr == nil { + return false + } + + if _, ok := validParentCodes[parentErr.Code()]; !ok { + return false + } + + err := parentErr.OrigErr() + if err == nil { + return false + } + + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) + } + + if t, ok := err.(temporaryError); ok { + return t.Temporary() + } + + return isErrConnectionReset(err) +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if error is nil. +func IsErrorRetryable(err error) bool { + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr) + } + } + return false +} + +// IsErrorThrottle returns whether the error is to be throttled based on its code. +// Returns false if error is nil. +func IsErrorThrottle(err error) bool { + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + return isCodeThrottle(aerr.Code()) + } + } + return false +} + +// IsErrorExpiredCreds returns whether the error code is a credential expiry error. +// Returns false if error is nil. +func IsErrorExpiredCreds(err error) bool { + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + return isCodeExpiredCreds(aerr.Code()) + } + } + return false +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorRetryable +func (r *Request) IsErrorRetryable() bool { + return IsErrorRetryable(r.Error) +} + +// IsErrorThrottle returns whether the error is to be throttled based on its code. +// Returns false if the request has no Error set +// +// Alias for the utility function IsErrorThrottle +func (r *Request) IsErrorThrottle() bool { + return IsErrorThrottle(r.Error) +} + +// IsErrorExpired returns whether the error code is a credential expiry error. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorExpiredCreds +func (r *Request) IsErrorExpired() bool { + return IsErrorExpiredCreds(r.Error) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v2/v2.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v2/v2.go new file mode 100644 index 000000000..554388215 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v2/v2.go @@ -0,0 +1,178 @@ +package v2 + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "net/http" + "net/url" + "sort" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +var ( + errInvalidMethod = errors.New("v2 signer only handles HTTP POST") +) + +const ( + signatureVersion = "2" + signatureMethod = "HmacSHA256" + timeFormat = "2006-01-02T15:04:05Z" +) + +type signer struct { + // Values that must be populated from the request + Request *http.Request + Time time.Time + Credentials aws.CredentialsProvider + Debug aws.LogLevel + Logger aws.Logger + + Query url.Values + stringToSign string + signature string +} + +// SignRequestHandler is a named request handler the SDK will use to sign +// service client request with using the V4 signature. +var SignRequestHandler = aws.NamedHandler{ + Name: "v2.SignRequestHandler", Fn: SignSDKRequest, +} + +// SignSDKRequest requests with signature version 2. +// +// Will sign the requests with the service config's Credentials object +// Signing is skipped if the credentials is the aws.AnonymousCredentials +// object. +func SignSDKRequest(req *aws.Request) { + // If the request does not need to be signed ignore the signing of the + // request if the AnonymousCredentials object is used. + if req.Config.Credentials == aws.AnonymousCredentials { + return + } + + if req.HTTPRequest.Method != "POST" && req.HTTPRequest.Method != "GET" { + // The V2 signer only supports GET and POST + req.Error = errInvalidMethod + return + } + + v2 := signer{ + Request: req.HTTPRequest, + Time: req.Time, + Credentials: req.Config.Credentials, + Debug: req.Config.LogLevel, + Logger: req.Config.Logger, + } + + req.Error = v2.Sign() + + if req.Error != nil { + return + } + + if req.HTTPRequest.Method == "POST" { + // Set the body of the request based on the modified query parameters + req.SetStringBody(v2.Query.Encode()) + + // Now that the body has changed, remove any Content-Length header, + // because it will be incorrect + req.HTTPRequest.ContentLength = 0 + req.HTTPRequest.Header.Del("Content-Length") + } else { + req.HTTPRequest.URL.RawQuery = v2.Query.Encode() + } +} + +func (v2 *signer) Sign() error { + credValue, err := v2.Credentials.Retrieve() + if err != nil { + return err + } + + if v2.Request.Method == "POST" { + // Parse the HTTP request to obtain the query parameters that will + // be used to build the string to sign. Note that because the HTTP + // request will need to be modified, the PostForm and Form properties + // are reset to nil after parsing. + v2.Request.ParseForm() + v2.Query = v2.Request.PostForm + v2.Request.PostForm = nil + v2.Request.Form = nil + } else { + v2.Query = v2.Request.URL.Query() + } + + // Set new query parameters + v2.Query.Set("AWSAccessKeyId", credValue.AccessKeyID) + v2.Query.Set("SignatureVersion", signatureVersion) + v2.Query.Set("SignatureMethod", signatureMethod) + v2.Query.Set("Timestamp", v2.Time.UTC().Format(timeFormat)) + if credValue.SessionToken != "" { + v2.Query.Set("SecurityToken", credValue.SessionToken) + } + + // in case this is a retry, ensure no signature present + v2.Query.Del("Signature") + + method := v2.Request.Method + host := v2.Request.URL.Host + path := v2.Request.URL.Path + if path == "" { + path = "/" + } + + // obtain all of the query keys and sort them + queryKeys := make([]string, 0, len(v2.Query)) + for key := range v2.Query { + queryKeys = append(queryKeys, key) + } + sort.Strings(queryKeys) + + // build URL-encoded query keys and values + queryKeysAndValues := make([]string, len(queryKeys)) + for i, key := range queryKeys { + k := strings.Replace(url.QueryEscape(key), "+", "%20", -1) + v := strings.Replace(url.QueryEscape(v2.Query.Get(key)), "+", "%20", -1) + queryKeysAndValues[i] = k + "=" + v + } + + // join into one query string + query := strings.Join(queryKeysAndValues, "&") + + // build the canonical string for the V2 signature + v2.stringToSign = strings.Join([]string{ + method, + host, + path, + query, + }, "\n") + + hash := hmac.New(sha256.New, []byte(credValue.SecretAccessKey)) + hash.Write([]byte(v2.stringToSign)) + v2.signature = base64.StdEncoding.EncodeToString(hash.Sum(nil)) + v2.Query.Set("Signature", v2.signature) + + if v2.Debug.Matches(aws.LogDebugWithSigning) { + v2.logSigningInfo() + } + + return nil +} + +const logSignInfoMsg = `DEBUG: Request Signature: +---[ STRING TO SIGN ]-------------------------------- +%s +---[ SIGNATURE ]------------------------------------- +%s +-----------------------------------------------------` + +func (v2 *signer) logSigningInfo() { + msg := fmt.Sprintf(logSignInfoMsg, v2.stringToSign, v2.Query.Get("Signature")) + v2.Logger.Log(msg) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/header_rules.go new file mode 100644 index 000000000..244c86da0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/header_rules.go @@ -0,0 +1,82 @@ +package v4 + +import ( + "net/http" + "strings" +) + +// validator houses a set of rule needed for validation of a +// string value +type rules []rule + +// rule interface allows for more flexible rules and just simply +// checks whether or not a value adheres to that rule +type rule interface { + IsValid(value string) bool +} + +// IsValid will iterate through all rules and see if any rules +// apply to the value and supports nested rules +func (r rules) IsValid(value string) bool { + for _, rule := range r { + if rule.IsValid(value) { + return true + } + } + return false +} + +// mapRule generic rule for maps +type mapRule map[string]struct{} + +// IsValid for the map rule satisfies whether it exists in the map +func (m mapRule) IsValid(value string) bool { + _, ok := m[value] + return ok +} + +// whitelist is a generic rule for whitelisting +type whitelist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (w whitelist) IsValid(value string) bool { + return w.rule.IsValid(value) +} + +// blacklist is a generic rule for blacklisting +type blacklist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (b blacklist) IsValid(value string) bool { + return !b.rule.IsValid(value) +} + +type patterns []string + +// IsValid for patterns checks each pattern and returns if a match has +// been found +func (p patterns) IsValid(value string) bool { + for _, pattern := range p { + if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) { + return true + } + } + return false +} + +// inclusiveRules rules allow for rules to depend on one another +type inclusiveRules []rule + +// IsValid will return true if all rules are true +func (r inclusiveRules) IsValid(value string) bool { + for _, rule := range r { + if !rule.IsValid(value) { + return false + } + } + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/options.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/options.go new file mode 100644 index 000000000..6aa2ed241 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/options.go @@ -0,0 +1,7 @@ +package v4 + +// WithUnsignedPayload will enable and set the UnsignedPayload field to +// true of the signer. +func WithUnsignedPayload(v4 *Signer) { + v4.UnsignedPayload = true +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/uri_path.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/uri_path.go new file mode 100644 index 000000000..bd082e9d1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/uri_path.go @@ -0,0 +1,24 @@ +// +build go1.5 + +package v4 + +import ( + "net/url" + "strings" +) + +func getURIPath(u *url.URL) string { + var uri string + + if len(u.Opaque) > 0 { + uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") + } else { + uri = u.EscapedPath() + } + + if len(uri) == 0 { + uri = "/" + } + + return uri +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go new file mode 100644 index 000000000..ddbade686 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go @@ -0,0 +1,755 @@ +// Package v4 implements signing for AWS V4 signer +// +// Provides request signing for request that need to be signed with +// AWS V4 Signatures. +// +// Standalone Signer +// +// Generally using the signer outside of the SDK should not require any additional +// logic when using Go v1.5 or higher. The signer does this by taking advantage +// of the URL.EscapedPath method. If your request URI requires additional escaping +// you many need to use the URL.Opaque to define what the raw URI should be sent +// to the service as. +// +// The signer will first check the URL.Opaque field, and use its value if set. +// The signer does require the URL.Opaque field to be set in the form of: +// +// "///" +// +// // e.g. +// "//example.com/some/path" +// +// The leading "//" and hostname are required or the URL.Opaque escaping will +// not work correctly. +// +// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath() +// method and using the returned value. If you're using Go v1.4 you must set +// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with +// Go v1.5 the signer will fallback to URL.Path. +// +// AWS v4 signature validation requires that the canonical string's URI path +// element must be the URI escaped form of the HTTP request's path. +// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html +// +// The Go HTTP client will perform escaping automatically on the request. Some +// of these escaping may cause signature validation errors because the HTTP +// request differs from the URI path or query that the signature was generated. +// https://golang.org/pkg/net/url/#URL.EscapedPath +// +// Because of this, it is recommended that when using the signer outside of the +// SDK that explicitly escaping the request prior to being signed is preferable, +// and will help prevent signature validation errors. This can be done by setting +// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then +// call URL.EscapedPath() if Opaque is not set. +// +// If signing a request intended for HTTP2 server, and you're using Go 1.6.2 +// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the +// request URL. https://github.com/golang/go/issues/16847 points to a bug in +// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP +// message. URL.Opaque generally will force Go to make requests with absolute URL. +// URL.RawPath does not do this, but RawPath must be a valid escaping of Path +// or url.EscapedPath will ignore the RawPath escaping. +// +// Test `TestStandaloneSign` provides a complete example of using the signer +// outside of the SDK and pre-escaping the URI path. +package v4 + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/internal/sdk" + "github.com/aws/aws-sdk-go-v2/private/protocol/rest" +) + +const ( + authHeaderPrefix = "AWS4-HMAC-SHA256" + timeFormat = "20060102T150405Z" + shortTimeFormat = "20060102" + + // emptyStringSHA256 is a SHA256 of an empty string + emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` +) + +var ignoredHeaders = rules{ + blacklist{ + mapRule{ + "Authorization": struct{}{}, + "User-Agent": struct{}{}, + "X-Amzn-Trace-Id": struct{}{}, + }, + }, +} + +// requiredSignedHeaders is a whitelist for build canonical headers. +var requiredSignedHeaders = rules{ + whitelist{ + mapRule{ + "Cache-Control": struct{}{}, + "Content-Disposition": struct{}{}, + "Content-Encoding": struct{}{}, + "Content-Language": struct{}{}, + "Content-Md5": struct{}{}, + "Content-Type": struct{}{}, + "Expires": struct{}{}, + "If-Match": struct{}{}, + "If-Modified-Since": struct{}{}, + "If-None-Match": struct{}{}, + "If-Unmodified-Since": struct{}{}, + "Range": struct{}{}, + "X-Amz-Acl": struct{}{}, + "X-Amz-Copy-Source": struct{}{}, + "X-Amz-Copy-Source-If-Match": struct{}{}, + "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, + "X-Amz-Copy-Source-If-None-Match": struct{}{}, + "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, + "X-Amz-Copy-Source-Range": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Grant-Full-control": struct{}{}, + "X-Amz-Grant-Read": struct{}{}, + "X-Amz-Grant-Read-Acp": struct{}{}, + "X-Amz-Grant-Write": struct{}{}, + "X-Amz-Grant-Write-Acp": struct{}{}, + "X-Amz-Metadata-Directive": struct{}{}, + "X-Amz-Mfa": struct{}{}, + "X-Amz-Request-Payer": struct{}{}, + "X-Amz-Server-Side-Encryption": struct{}{}, + "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Storage-Class": struct{}{}, + "X-Amz-Website-Redirect-Location": struct{}{}, + "X-Amz-Content-Sha256": struct{}{}, + }, + }, + patterns{"X-Amz-Meta-"}, +} + +// allowedHoisting is a whitelist for build query headers. The boolean value +// represents whether or not it is a pattern. +var allowedQueryHoisting = inclusiveRules{ + blacklist{requiredSignedHeaders}, + patterns{"X-Amz-"}, +} + +// Signer applies AWS v4 signing to given request. Use this to sign requests +// that need to be signed with AWS V4 Signatures. +type Signer struct { + // The authentication credentials the request will be signed against. + // This value must be set to sign requests. + Credentials aws.CredentialsProvider + + // Sets the log level the signer should use when reporting information to + // the logger. If the logger is nil nothing will be logged. See + // aws.LogLevel for more information on available logging levels + // + // By default nothing will be logged. + Debug aws.LogLevel + + // The logger loging information will be written to. If there the logger + // is nil, nothing will be logged. + Logger aws.Logger + + // Disables the Signer's moving HTTP header key/value pairs from the HTTP + // request header to the request's query string. This is most commonly used + // with pre-signed requests preventing headers from being added to the + // request's query string. + DisableHeaderHoisting bool + + // Disables the automatic escaping of the URI path of the request for the + // siganture's canonical string's path. For services that do not need additional + // escaping then use this to disable the signer escaping the path. + // + // S3 is an example of a service that does not need additional escaping. + // + // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + DisableURIPathEscaping bool + + // Disales the automatical setting of the HTTP request's Body field with the + // io.ReadSeeker passed in to the signer. This is useful if you're using a + // custom wrapper around the body for the io.ReadSeeker and want to preserve + // the Body value on the Request.Body. + // + // This does run the risk of signing a request with a body that will not be + // sent in the request. Need to ensure that the underlying data of the Body + // values are the same. + DisableRequestBodyOverwrite bool + + // UnsignedPayload will prevent signing of the payload. This will only + // work for services that have support for this. + UnsignedPayload bool +} + +// NewSigner returns a Signer pointer configured with the credentials and optional +// option values provided. If not options are provided the Signer will use its +// default configuration. +func NewSigner(credsProvider aws.CredentialsProvider, options ...func(*Signer)) *Signer { + v4 := &Signer{ + Credentials: credsProvider, + } + + for _, option := range options { + option(v4) + } + + return v4 +} + +type signingCtx struct { + ServiceName string + Region string + Request *http.Request + Body io.ReadSeeker + Query url.Values + Time time.Time + ExpireTime time.Duration + SignedHeaderVals http.Header + + DisableURIPathEscaping bool + + credValues aws.Credentials + isPresign bool + formattedTime string + formattedShortTime string + unsignedPayload bool + + bodyDigest string + signedHeaders string + canonicalHeaders string + canonicalString string + credentialString string + stringToSign string + signature string + authorization string +} + +// Sign signs AWS v4 requests with the provided body, service name, region the +// request is made to, and time the request is signed at. The signTime allows +// you to specify that a request is signed for the future, and cannot be +// used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. Generally for signed requests this value +// is not needed as the full request context will be captured by the http.Request +// value. It is included for reference though. +// +// Sign will set the request's Body to be the `body` parameter passed in. If +// the body is not already an io.ReadCloser, it will be wrapped within one. If +// a `nil` body parameter passed to Sign, the request's Body field will be +// also set to nil. Its important to note that this functionality will not +// change the request's ContentLength of the request. +// +// Sign differs from Presign in that it will sign the request using HTTP +// header values. This type of signing is intended for http.Request values that +// will not be shared, or are shared in a way the header values on the request +// will not be lost. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, 0, signTime) +} + +// Presign signs AWS v4 requests with the provided body, service name, region +// the request is made to, and time the request is signed at. The signTime +// allows you to specify that a request is signed for the future, and cannot +// be used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. For presigned requests these headers +// and their values must be included on the HTTP request when it is made. This +// is helpful to know what header values need to be shared with the party the +// presigned request will be distributed to. +// +// Presign differs from Sign in that it will sign the request using query string +// instead of header values. This allows you to share the Presigned Request's +// URL with third parties, or distribute it throughout your system with minimal +// dependencies. +// +// Presign also takes an exp value which is the duration the +// signed request will be valid after the signing time. This is allows you to +// set when the request will expire. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +// +// Presigning a S3 request will not compute the body's SHA256 hash by default. +// This is done due to the general use case for S3 presigned URLs is to share +// PUT/GET capabilities. If you would like to include the body's SHA256 in the +// presigned request's signature you can set the "X-Amz-Content-Sha256" +// HTTP header and that will be included in the request's signature. +func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, exp, signTime) +} + +func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + ctx := &signingCtx{ + Request: r, + Body: body, + Query: r.URL.Query(), + Time: signTime, + ExpireTime: exp, + isPresign: exp != 0, + ServiceName: service, + Region: region, + DisableURIPathEscaping: v4.DisableURIPathEscaping, + unsignedPayload: v4.UnsignedPayload, + } + + for key := range ctx.Query { + sort.Strings(ctx.Query[key]) + } + + if ctx.isRequestSigned() { + ctx.Time = sdk.NowTime() + ctx.handlePresignRemoval() + } + + var err error + ctx.credValues, err = v4.Credentials.Retrieve() + if err != nil { + return http.Header{}, err + } + + ctx.assignAmzQueryValues() + ctx.build(v4.DisableHeaderHoisting) + + // If the request is not presigned the body should be attached to it. This + // prevents the confusion of wanting to send a signed request without + // the body the request was signed for attached. + if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) { + var reader io.ReadCloser + if body != nil { + var ok bool + if reader, ok = body.(io.ReadCloser); !ok { + reader = ioutil.NopCloser(body) + } + } + r.Body = reader + } + + if v4.Debug.Matches(aws.LogDebugWithSigning) { + v4.logSigningInfo(ctx) + } + + return ctx.SignedHeaderVals, nil +} + +func (ctx *signingCtx) handlePresignRemoval() { + if !ctx.isPresign { + return + } + + // The credentials have expired for this request. The current signing + // is invalid, and needs to be request because the request will fail. + ctx.removePresign() + + // Update the request's query string to ensure the values stays in + // sync in the case retrieving the new credentials fails. + ctx.Request.URL.RawQuery = ctx.Query.Encode() +} + +func (ctx *signingCtx) assignAmzQueryValues() { + if ctx.isPresign { + ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix) + if ctx.credValues.SessionToken != "" { + ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } else { + ctx.Query.Del("X-Amz-Security-Token") + } + + return + } + + if ctx.credValues.SessionToken != "" { + ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } +} + +// SignRequestHandler is a named request handler the SDK will use to sign +// service client request with using the V4 signature. +var SignRequestHandler = aws.NamedHandler{ + Name: "v4.SignRequestHandler", Fn: func(r *aws.Request) { SignSDKRequest(r) }, +} + +// BuildNamedHandler will build a generic handler for signing. +func BuildNamedHandler(name string, opts ...func(*Signer)) aws.NamedHandler { + return aws.NamedHandler{ + Name: name, + Fn: func(req *aws.Request) { + SignSDKRequest(req, opts...) + }, + } +} + +// SignSDKRequest signs an AWS request with the V4 signature. This +// request handler should only be used with the SDK's built in service client's +// API operation requests. +// +// This function should not be used on its on its own, but in conjunction with +// an AWS service client's API operation call. To sign a standalone request +// not created by a service client's API operation method use the "Sign" or +// "Presign" functions of the "Signer" type. +// +// If the credentials of the request's config are set to +// aws.AnonymousCredentials the request will not be signed. +func SignSDKRequest(req *aws.Request, opts ...func(*Signer)) { + // If the request does not need to be signed ignore the signing of the + // request if the AnonymousCredentials object is used. + if req.Config.Credentials == aws.AnonymousCredentials { + return + } + + region := req.Metadata.SigningRegion + if region == "" { + region = req.Config.Region + } + + name := req.Metadata.SigningName + if name == "" { + name = req.Metadata.ServiceName + } + + v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) { + v4.Debug = req.Config.LogLevel + v4.Logger = req.Config.Logger + v4.DisableHeaderHoisting = req.NotHoist + if name == "s3" { + // S3 service should not have any escaping applied + v4.DisableURIPathEscaping = true + } + // Prevents setting the HTTPRequest's Body. Since the Body could be + // wrapped in a custom io.Closer that we do not want to be stompped + // on top of by the signer. + v4.DisableRequestBodyOverwrite = true + }) + + for _, opt := range opts { + opt(v4) + } + + signingTime := req.Time + if !req.LastSignedAt.IsZero() { + signingTime = req.LastSignedAt + } + + signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), + name, region, req.ExpireTime, signingTime, + ) + if err != nil { + req.Error = err + req.SignedHeaderVals = nil + return + } + + req.SignedHeaderVals = signedHeaders + req.LastSignedAt = sdk.NowTime() +} + +const logSignInfoMsg = `DEBUG: Request Signature: +---[ CANONICAL STRING ]----------------------------- +%s +---[ STRING TO SIGN ]-------------------------------- +%s%s +-----------------------------------------------------` +const logSignedURLMsg = ` +---[ SIGNED URL ]------------------------------------ +%s` + +func (v4 *Signer) logSigningInfo(ctx *signingCtx) { + signedURLMsg := "" + if ctx.isPresign { + signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String()) + } + msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg) + v4.Logger.Log(msg) +} + +func (ctx *signingCtx) build(disableHeaderHoisting bool) { + ctx.buildTime() // no depends + ctx.buildCredentialString() // no depends + + ctx.buildBodyDigest() + + unsignedHeaders := ctx.Request.Header + if ctx.isPresign { + if !disableHeaderHoisting { + urlValues := url.Values{} + urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends + for k := range urlValues { + ctx.Query[k] = urlValues[k] + } + } + } + + ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) + ctx.buildCanonicalString() // depends on canon headers / signed headers + ctx.buildStringToSign() // depends on canon string + ctx.buildSignature() // depends on string to sign + + if ctx.isPresign { + ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature + } else { + parts := []string{ + authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, + "SignedHeaders=" + ctx.signedHeaders, + "Signature=" + ctx.signature, + } + ctx.Request.Header.Set("Authorization", strings.Join(parts, ", ")) + } +} + +func (ctx *signingCtx) buildTime() { + ctx.formattedTime = ctx.Time.UTC().Format(timeFormat) + ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat) + + if ctx.isPresign { + duration := int64(ctx.ExpireTime / time.Second) + ctx.Query.Set("X-Amz-Date", ctx.formattedTime) + ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10)) + } else { + ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime) + } +} + +func (ctx *signingCtx) buildCredentialString() { + ctx.credentialString = strings.Join([]string{ + ctx.formattedShortTime, + ctx.Region, + ctx.ServiceName, + "aws4_request", + }, "/") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString) + } +} + +func buildQuery(r rule, header http.Header) (url.Values, http.Header) { + query := url.Values{} + unsignedHeaders := http.Header{} + for k, h := range header { + if r.IsValid(k) { + query[k] = h + } else { + unsignedHeaders[k] = h + } + } + + return query, unsignedHeaders +} +func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { + var headers []string + headers = append(headers, "host") + for k, v := range header { + canonicalKey := http.CanonicalHeaderKey(k) + if !r.IsValid(canonicalKey) { + continue // ignored header + } + if ctx.SignedHeaderVals == nil { + ctx.SignedHeaderVals = make(http.Header) + } + + lowerCaseKey := strings.ToLower(k) + if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok { + // include additional values + ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) + ctx.SignedHeaderVals[lowerCaseKey] = v + } + sort.Strings(headers) + + ctx.signedHeaders = strings.Join(headers, ";") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders) + } + + headerValues := make([]string, len(headers)) + for i, k := range headers { + if k == "host" { + if ctx.Request.Host != "" { + headerValues[i] = "host:" + ctx.Request.Host + } else { + headerValues[i] = "host:" + ctx.Request.URL.Host + } + } else { + headerValues[i] = k + ":" + + strings.Join(ctx.SignedHeaderVals[k], ",") + } + } + stripExcessSpaces(headerValues) + ctx.canonicalHeaders = strings.Join(headerValues, "\n") +} + +func (ctx *signingCtx) buildCanonicalString() { + ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) + + uri := getURIPath(ctx.Request.URL) + + if !ctx.DisableURIPathEscaping { + uri = rest.EscapePath(uri, false) + } + + ctx.canonicalString = strings.Join([]string{ + ctx.Request.Method, + uri, + ctx.Request.URL.RawQuery, + ctx.canonicalHeaders + "\n", + ctx.signedHeaders, + ctx.bodyDigest, + }, "\n") +} + +func (ctx *signingCtx) buildStringToSign() { + ctx.stringToSign = strings.Join([]string{ + authHeaderPrefix, + ctx.formattedTime, + ctx.credentialString, + hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))), + }, "\n") +} + +func (ctx *signingCtx) buildSignature() { + secret := ctx.credValues.SecretAccessKey + date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime)) + region := makeHmac(date, []byte(ctx.Region)) + service := makeHmac(region, []byte(ctx.ServiceName)) + credentials := makeHmac(service, []byte("aws4_request")) + signature := makeHmac(credentials, []byte(ctx.stringToSign)) + ctx.signature = hex.EncodeToString(signature) +} + +func (ctx *signingCtx) buildBodyDigest() { + hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") + if hash == "" { + includeSHA256Header := ctx.unsignedPayload || + ctx.ServiceName == "s3" || + ctx.ServiceName == "glacier" + + s3Presign := ctx.isPresign && ctx.ServiceName == "s3" + + if ctx.unsignedPayload || s3Presign { + hash = "UNSIGNED-PAYLOAD" + includeSHA256Header = !s3Presign + } else if ctx.Body == nil { + hash = emptyStringSHA256 + } else { + hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) + } + + if includeSHA256Header { + ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) + } + } + ctx.bodyDigest = hash +} + +// isRequestSigned returns if the request is currently signed or presigned +func (ctx *signingCtx) isRequestSigned() bool { + if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" { + return true + } + if ctx.Request.Header.Get("Authorization") != "" { + return true + } + + return false +} + +// unsign removes signing flags for both signed and presigned requests. +func (ctx *signingCtx) removePresign() { + ctx.Query.Del("X-Amz-Algorithm") + ctx.Query.Del("X-Amz-Signature") + ctx.Query.Del("X-Amz-Security-Token") + ctx.Query.Del("X-Amz-Date") + ctx.Query.Del("X-Amz-Expires") + ctx.Query.Del("X-Amz-Credential") + ctx.Query.Del("X-Amz-SignedHeaders") +} + +func makeHmac(key []byte, data []byte) []byte { + hash := hmac.New(sha256.New, key) + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256(data []byte) []byte { + hash := sha256.New() + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256Reader(reader io.ReadSeeker) []byte { + hash := sha256.New() + start, _ := reader.Seek(0, 1) + defer reader.Seek(start, 0) + + io.Copy(hash, reader) + return hash.Sum(nil) +} + +const doubleSpace = " " + +// stripExcessSpaces will rewrite the passed in slice's string values to not +// contain muliple side-by-side spaces. +func stripExcessSpaces(vals []string) { + var j, k, l, m, spaces int + for i, str := range vals { + // Trim trailing spaces + for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- { + } + + // Trim leading spaces + for k = 0; k < j && str[k] == ' '; k++ { + } + str = str[k : j+1] + + // Strip multiple spaces. + j = strings.Index(str, doubleSpace) + if j < 0 { + vals[i] = str + continue + } + + buf := []byte(str) + for k, m, l = j, j, len(buf); k < l; k++ { + if buf[k] == ' ' { + if spaces == 0 { + // First space. + buf[m] = buf[k] + m++ + } + spaces++ + } else { + // End of multiple spaces. + spaces = 0 + buf[m] = buf[k] + m++ + } + } + + vals[i] = string(buf[:m]) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/static_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/static_provider.go new file mode 100644 index 000000000..0870016a2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/static_provider.go @@ -0,0 +1,52 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +// StaticCredentialsProviderName provides a name of Static provider +const StaticCredentialsProviderName = "StaticCredentialsProvider" + +var ( + // ErrStaticCredentialsEmpty is emitted when static credentials are empty. + ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) +) + +// A StaticCredentialsProvider is a set of credentials which are set programmatically, +// and will never expire. +type StaticCredentialsProvider struct { + Value Credentials +} + +// NewStaticCredentialsProvider return a StaticCredentialsProvider initialized with the AWS credentials +// passed in. +func NewStaticCredentialsProvider(key, secret, session string) StaticCredentialsProvider { + return StaticCredentialsProvider{ + Value: Credentials{ + AccessKeyID: key, + SecretAccessKey: secret, + SessionToken: session, + }, + } +} + +// Retrieve returns the credentials or error if the credentials are invalid. +func (s StaticCredentialsProvider) Retrieve() (Credentials, error) { + v := s.Value + if v.AccessKeyID == "" || v.SecretAccessKey == "" { + return Credentials{Source: StaticCredentialsProviderName}, ErrStaticCredentialsEmpty + } + + if len(v.Source) == 0 { + v.Source = StaticCredentialsProviderName + } + + return v, nil +} + +// IsExpired returns if the credentials are expired. +// +// For StaticCredentialsProvider, the credentials never expired. +func (s StaticCredentialsProvider) IsExpired() bool { + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/stscreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/stscreds/provider.go new file mode 100644 index 000000000..549a2c1a0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/stscreds/provider.go @@ -0,0 +1,264 @@ +/* +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. + +The SDK will ensure that per instance of credentials.Credentials all requests +to refresh the credentials will be synchronized. But, the SDK is unable to +ensure synchronous usage of the AssumeRoleProvider if the value is shared +between multiple Credentials or service clients. + +Assume Role + +To assume an IAM role using STS with the SDK you can create a new Credentials +with the SDKs's stscreds package. + + // Initial credentials loaded from SDK's default credential chain. Such as + // the environment, shared credentials (~/.aws/credentials), or EC2 Instance + // Role. These credentials will be used to to make the STS Assume Role API. + cfg, err := external.LoadDefaultAWSConfig() + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. + stsSvc := sts.New(cfg) + stsCredProvider := stscreds.NewAssumeRoleProvider(stsSvc, "myRoleArn") + + cfg.Credentials = aws.NewCredentials(stsCredProvider) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(cfg) + +Assume Role with static MFA Token + +To assume an IAM role with a MFA token you can either specify a MFA token code +directly or provide a function to prompt the user each time the credentials +need to refresh the role's credentials. Specifying the TokenCode should be used +for short lived operations that will not need to be refreshed, and when you do +not want to have direct control over the user provides their MFA token. + +With TokenCode the AssumeRoleProvider will be not be able to refresh the role's +credentials. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN using the MFA token code provided. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenCode = aws.String("00000000") + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with MFA Token Provider + +To assume an IAM role with MFA for longer running tasks where the credentials +may need to be refreshed setting the TokenProvider field of AssumeRoleProvider +will allow the credential provider to prompt for new MFA token code when the +role's credentials need to be refreshed. + +The StdinTokenProvider function is available to prompt on stdin to retrieve +the MFA token code from the user. You can also implement custom prompts by +satisfing the TokenProvider function signature. + +Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +have undesirable results as the StdinTokenProvider will not be synchronized. A +single Credentials with an AssumeRoleProvider can be shared safely. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenProvider = stscreds.StdinTokenProvider + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +*/ +package stscreds + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/service/sts" +) + +// StdinTokenProvider will prompt on stdout and read from stdin for a string value. +// An error is returned if reading from stdin fails. +// +// Use this function go read MFA tokens from stdin. The function makes no attempt +// to make atomic prompts from stdin across multiple gorouties. +// +// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +// have undesirable results as the StdinTokenProvider will not be synchronized. A +// single Credentials with an AssumeRoleProvider can be shared safely +// +// Will wait forever until something is provided on the stdin. +func StdinTokenProvider() (string, error) { + var v string + fmt.Printf("Assume Role MFA token code: ") + _, err := fmt.Scanln(&v) + + return v, err +} + +// 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 { + AssumeRoleRequest(input *sts.AssumeRoleInput) sts.AssumeRoleRequest +} + +// 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 credential provider will be used by the SDKs default credential change +// when shared configuration is enabled, and the shared config or shared credentials +// file configure assume role. See Session docs for how to do this. +// +// AssumeRoleProvider does not provide any synchronization and it is not safe +// to share this value across multiple Credentials, Sessions, or service clients +// without also sharing the same Credentials instance. +type AssumeRoleProvider struct { + aws.SafeCredentialsProvider + + // 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. + // + // If SerialNumber is set and neither TokenCode nor TokenProvider are also + // set an error will be returned. + TokenCode *string + + // Async method of providing MFA token code for assuming an IAM role with MFA. + // The value returned by the function will be used as the TokenCode in the Retrieve + // call. See StdinTokenProvider for a provider that prompts and reads from stdin. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed when SerialNumber is also set and + // TokenCode is not set. + // + // If both TokenCode and TokenProvider is set, TokenProvider will be used and + // TokenCode is ignored. + TokenProvider func() (string, error) + + // 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 +} + +// NewAssumeRoleProvider constructs and returns a credentials provider that +// will retrieve credentials by assuming a IAM role using STS. +func NewAssumeRoleProvider(client AssumeRoler, roleARN string) *AssumeRoleProvider { + p := &AssumeRoleProvider{ + Client: client, + RoleARN: roleARN, + } + p.RetrieveFn = p.retrieveFn + + return p +} + +// Retrieve generates a new set of temporary credentials using STS. +func (p *AssumeRoleProvider) retrieveFn() (aws.Credentials, error) { + // Apply defaults where parameters are not set. + if len(p.RoleSessionName) == 0 { + // 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 { + if p.TokenCode != nil { + input.SerialNumber = p.SerialNumber + input.TokenCode = p.TokenCode + } else if p.TokenProvider != nil { + input.SerialNumber = p.SerialNumber + code, err := p.TokenProvider() + if err != nil { + return aws.Credentials{}, err + } + input.TokenCode = aws.String(code) + } else { + return aws.Credentials{}, + awserr.New("AssumeRoleTokenNotAvailable", + "assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil) + } + } + + req := p.Client.AssumeRoleRequest(input) + resp, err := req.Send() + if err != nil { + return aws.Credentials{Source: ProviderName}, err + } + + return aws.Credentials{ + AccessKeyID: *resp.Credentials.AccessKeyId, + SecretAccessKey: *resp.Credentials.SecretAccessKey, + SessionToken: *resp.Credentials.SessionToken, + Source: ProviderName, + + CanExpire: true, + Expires: resp.Credentials.Expiration.Add(-p.ExpiryWindow), + }, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/timeout_read_closer.go new file mode 100644 index 000000000..d8b5124ee --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/timeout_read_closer.go @@ -0,0 +1,94 @@ +package aws + +import ( + "io" + "time" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +var timeoutErr = awserr.New( + ErrCodeResponseTimeout, + "read on body has reached the timeout limit", + nil, +) + +type readResult struct { + n int + err error +} + +// timeoutReadCloser will handle body reads that take too long. +// We will return a ErrReadTimeout error if a timeout occurs. +type timeoutReadCloser struct { + reader io.ReadCloser + duration time.Duration +} + +// Read will spin off a goroutine to call the reader's Read method. We will +// select on the timer's channel or the read's channel. Whoever completes first +// will be returned. +func (r *timeoutReadCloser) Read(b []byte) (int, error) { + timer := time.NewTimer(r.duration) + c := make(chan readResult, 1) + + go func() { + n, err := r.reader.Read(b) + timer.Stop() + c <- readResult{n: n, err: err} + }() + + select { + case data := <-c: + return data.n, data.err + case <-timer.C: + return 0, timeoutErr + } +} + +func (r *timeoutReadCloser) Close() error { + return r.reader.Close() +} + +const ( + // HandlerResponseTimeout is what we use to signify the name of the + // response timeout handler. + HandlerResponseTimeout = "ResponseTimeoutHandler" +) + +// adaptToResponseTimeoutError is a handler that will replace any top level error +// to a ErrCodeResponseTimeout, if its child is that. +func adaptToResponseTimeoutError(req *Request) { + if err, ok := req.Error.(awserr.Error); ok { + aerr, ok := err.OrigErr().(awserr.Error) + if ok && aerr.Code() == ErrCodeResponseTimeout { + req.Error = aerr + } + } +} + +// WithResponseReadTimeout is a request option that will wrap the body in a timeout read closer. +// This will allow for per read timeouts. If a timeout occurred, we will return the +// ErrCodeResponseTimeout. +// +// svc.PutObjectWithContext(ctx, params, request.WithTimeoutReadCloser(30 * time.Second) +func WithResponseReadTimeout(duration time.Duration) Option { + return func(r *Request) { + + var timeoutHandler = NamedHandler{ + HandlerResponseTimeout, + func(req *Request) { + req.HTTPResponse.Body = &timeoutReadCloser{ + reader: req.HTTPResponse.Body, + duration: duration, + } + }} + + // remove the handler so we are not stomping over any new durations. + r.Handlers.Send.RemoveByName(HandlerResponseTimeout) + r.Handlers.Send.PushBackNamed(timeoutHandler) + + r.Handlers.Unmarshal.PushBack(adaptToResponseTimeoutError) + r.Handlers.UnmarshalError.PushBack(adaptToResponseTimeoutError) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/types.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/types.go new file mode 100644 index 000000000..0e2d864e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/types.go @@ -0,0 +1,118 @@ +package aws + +import ( + "io" + "sync" +) + +// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should +// only be used with an io.Reader that is also an io.Seeker. Doing so may +// cause request signature errors, or request body's not sent for GET, HEAD +// and DELETE HTTP methods. +// +// Deprecated: Should only be used with io.ReadSeeker. If using for +// S3 PutObject to stream content use s3manager.Uploader instead. +func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { + return ReaderSeekerCloser{r} +} + +// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and +// io.Closer interfaces to the underlying object if they are available. +type ReaderSeekerCloser struct { + r io.Reader +} + +// Read reads from the reader up to size of p. The number of bytes read, and +// error if it occurred will be returned. +// +// If the reader is not an io.Reader zero bytes read, and nil error will be returned. +// +// Performs the same functionality as io.Reader Read +func (r ReaderSeekerCloser) Read(p []byte) (int, error) { + switch t := r.r.(type) { + case io.Reader: + return t.Read(p) + } + return 0, nil +} + +// Seek sets the offset for the next Read to offset, interpreted according to +// whence: 0 means relative to the origin of the file, 1 means relative to the +// current offset, and 2 means relative to the end. Seek returns the new offset +// and an error, if any. +// +// If the ReaderSeekerCloser is not an io.Seeker nothing will be done. +func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) { + switch t := r.r.(type) { + case io.Seeker: + return t.Seek(offset, whence) + } + return int64(0), nil +} + +// IsSeeker returns if the underlying reader is also a seeker. +func (r ReaderSeekerCloser) IsSeeker() bool { + _, ok := r.r.(io.Seeker) + return ok +} + +// Close closes the ReaderSeekerCloser. +// +// If the ReaderSeekerCloser is not an io.Closer nothing will be done. +func (r ReaderSeekerCloser) Close() error { + switch t := r.r.(type) { + case io.Closer: + return t.Close() + } + return nil +} + +// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface +// Can be used with the s3manager.Downloader to download content to a buffer +// in memory. Safe to use concurrently. +type WriteAtBuffer struct { + buf []byte + m sync.Mutex + + // GrowthCoeff defines the growth rate of the internal buffer. By + // default, the growth rate is 1, where expanding the internal + // buffer will allocate only enough capacity to fit the new expected + // length. + GrowthCoeff float64 +} + +// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer +// provided by buf. +func NewWriteAtBuffer(buf []byte) *WriteAtBuffer { + return &WriteAtBuffer{buf: buf} +} + +// WriteAt writes a slice of bytes to a buffer starting at the position provided +// The number of bytes written will be returned, or error. Can overwrite previous +// written slices if the write ats overlap. +func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) { + pLen := len(p) + expLen := pos + int64(pLen) + b.m.Lock() + defer b.m.Unlock() + if int64(len(b.buf)) < expLen { + if int64(cap(b.buf)) < expLen { + if b.GrowthCoeff < 1 { + b.GrowthCoeff = 1 + } + newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen))) + copy(newBuf, b.buf) + b.buf = newBuf + } + b.buf = b.buf[:expLen] + } + copy(b.buf[pos:], p) + return pLen, nil +} + +// Bytes returns a slice of bytes written to the buffer. +func (b *WriteAtBuffer) Bytes() []byte { + b.m.Lock() + defer b.m.Unlock() + return b.buf +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/url.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/url.go new file mode 100644 index 000000000..6192b2455 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/url.go @@ -0,0 +1,12 @@ +// +build go1.8 + +package aws + +import "net/url" + +// URLHostname will extract the Hostname without port from the URL value. +// +// Wrapper of net/url#URL.Hostname for backwards Go version compatibility. +func URLHostname(url *url.URL) string { + return url.Hostname() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/url_1_7.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/url_1_7.go new file mode 100644 index 000000000..0210d2720 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/url_1_7.go @@ -0,0 +1,29 @@ +// +build !go1.8 + +package aws + +import ( + "net/url" + "strings" +) + +// URLHostname will extract the Hostname without port from the URL value. +// +// Copy of Go 1.8's net/url#URL.Hostname functionality. +func URLHostname(url *url.URL) string { + return stripPort(url.Host) + +} + +// stripPort is copy of Go 1.8 url#URL.Hostname functionality. +// https://golang.org/src/net/url/url.go +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/validation.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/validation.go new file mode 100644 index 000000000..6529ba651 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/validation.go @@ -0,0 +1,234 @@ +package aws + +import ( + "bytes" + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +const ( + // InvalidParameterErrCode is the error code for invalid parameters errors + InvalidParameterErrCode = "InvalidParameter" + // ParamRequiredErrCode is the error code for required parameter errors + ParamRequiredErrCode = "ParamRequiredError" + // ParamMinValueErrCode is the error code for fields with too low of a + // number value. + ParamMinValueErrCode = "ParamMinValueError" + // ParamMinLenErrCode is the error code for fields without enough elements. + ParamMinLenErrCode = "ParamMinLenError" +) + +// Validator provides a way for types to perform validation logic on their +// input values that external code can use to determine if a type's values +// are valid. +type Validator interface { + Validate() error +} + +// An ErrInvalidParams provides wrapping of invalid parameter errors found when +// validating API operation input parameters. +type ErrInvalidParams struct { + // Context is the base context of the invalid parameter group. + Context string + errs []ErrInvalidParam +} + +// Add adds a new invalid parameter error to the collection of invalid +// parameters. The context of the invalid parameter will be updated to reflect +// this collection. +func (e *ErrInvalidParams) Add(err ErrInvalidParam) { + err.SetContext(e.Context) + e.errs = append(e.errs, err) +} + +// AddNested adds the invalid parameter errors from another ErrInvalidParams +// value into this collection. The nested errors will have their nested context +// updated and base context to reflect the merging. +// +// Use for nested validations errors. +func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) { + for _, err := range nested.errs { + err.SetContext(e.Context) + err.AddNestedContext(nestedCtx) + e.errs = append(e.errs, err) + } +} + +// Len returns the number of invalid parameter errors +func (e ErrInvalidParams) Len() int { + return len(e.errs) +} + +// Code returns the code of the error +func (e ErrInvalidParams) Code() string { + return InvalidParameterErrCode +} + +// Message returns the message of the error +func (e ErrInvalidParams) Message() string { + return fmt.Sprintf("%d validation error(s) found.", len(e.errs)) +} + +// Error returns the string formatted form of the invalid parameters. +func (e ErrInvalidParams) Error() string { + w := &bytes.Buffer{} + fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message()) + + for _, err := range e.errs { + fmt.Fprintf(w, "- %s\n", err.Message()) + } + + return w.String() +} + +// OrigErr returns the invalid parameters as a awserr.BatchedErrors value +func (e ErrInvalidParams) OrigErr() error { + return awserr.NewBatchError( + InvalidParameterErrCode, e.Message(), e.OrigErrs()) +} + +// OrigErrs returns a slice of the invalid parameters +func (e ErrInvalidParams) OrigErrs() []error { + errs := make([]error, len(e.errs)) + for i := 0; i < len(errs); i++ { + errs[i] = e.errs[i] + } + + return errs +} + +// An ErrInvalidParam represents an invalid parameter error type. +type ErrInvalidParam interface { + awserr.Error + + // Field name the error occurred on. + Field() string + + // SetContext updates the context of the error. + SetContext(string) + + // AddNestedContext updates the error's context to include a nested level. + AddNestedContext(string) +} + +type errInvalidParam struct { + context string + nestedContext string + field string + code string + msg string +} + +// Code returns the error code for the type of invalid parameter. +func (e *errInvalidParam) Code() string { + return e.code +} + +// Message returns the reason the parameter was invalid, and its context. +func (e *errInvalidParam) Message() string { + return fmt.Sprintf("%s, %s.", e.msg, e.Field()) +} + +// Error returns the string version of the invalid parameter error. +func (e *errInvalidParam) Error() string { + return fmt.Sprintf("%s: %s", e.code, e.Message()) +} + +// OrigErr returns nil, Implemented for awserr.Error interface. +func (e *errInvalidParam) OrigErr() error { + return nil +} + +// Field Returns the field and context the error occurred. +func (e *errInvalidParam) Field() string { + field := e.context + if len(field) > 0 { + field += "." + } + if len(e.nestedContext) > 0 { + field += fmt.Sprintf("%s.", e.nestedContext) + } + field += e.field + + return field +} + +// SetContext updates the base context of the error. +func (e *errInvalidParam) SetContext(ctx string) { + e.context = ctx +} + +// AddNestedContext prepends a context to the field's path. +func (e *errInvalidParam) AddNestedContext(ctx string) { + if len(e.nestedContext) == 0 { + e.nestedContext = ctx + } else { + e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext) + } + +} + +// An ErrParamRequired represents an required parameter error. +type ErrParamRequired struct { + errInvalidParam +} + +// NewErrParamRequired creates a new required parameter error. +func NewErrParamRequired(field string) *ErrParamRequired { + return &ErrParamRequired{ + errInvalidParam{ + code: ParamRequiredErrCode, + field: field, + msg: fmt.Sprintf("missing required field"), + }, + } +} + +// An ErrParamMinValue represents a minimum value parameter error. +type ErrParamMinValue struct { + errInvalidParam + min float64 +} + +// NewErrParamMinValue creates a new minimum value parameter error. +func NewErrParamMinValue(field string, min float64) *ErrParamMinValue { + return &ErrParamMinValue{ + errInvalidParam: errInvalidParam{ + code: ParamMinValueErrCode, + field: field, + msg: fmt.Sprintf("minimum field value of %v", min), + }, + min: min, + } +} + +// MinValue returns the field's require minimum value. +// +// float64 is returned for both int and float min values. +func (e *ErrParamMinValue) MinValue() float64 { + return e.min +} + +// An ErrParamMinLen represents a minimum length parameter error. +type ErrParamMinLen struct { + errInvalidParam + min int +} + +// NewErrParamMinLen creates a new minimum length parameter error. +func NewErrParamMinLen(field string, min int) *ErrParamMinLen { + return &ErrParamMinLen{ + errInvalidParam: errInvalidParam{ + code: ParamMinLenErrCode, + field: field, + msg: fmt.Sprintf("minimum field size of %v", min), + }, + min: min, + } +} + +// MinLen returns the field's required minimum length. +func (e *ErrParamMinLen) MinLen() int { + return e.min +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/version.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/version.go new file mode 100644 index 000000000..9ed4fe6d6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/version.go @@ -0,0 +1,8 @@ +// Package aws provides core functionality for making requests to AWS services. +package aws + +// SDKName is the name of this AWS SDK +const SDKName = "aws-sdk-go" + +// SDKVersion is the version of this SDK +const SDKVersion = "2.0.0-preview.4" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/waiter.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/waiter.go new file mode 100644 index 000000000..6e3f7e7b7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/waiter.go @@ -0,0 +1,284 @@ +package aws + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/internal/awsutil" + "github.com/aws/aws-sdk-go-v2/internal/sdk" +) + +// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when +// the waiter's max attempts have been exhausted. +const WaiterResourceNotReadyErrorCode = "ResourceNotReady" + +// A WaiterOption is a function that will update the Waiter value's fields to +// configure the waiter. +type WaiterOption func(*Waiter) + +// WithWaiterMaxAttempts returns the maximum number of times the waiter should +// attempt to check the resource for the target state. +func WithWaiterMaxAttempts(max int) WaiterOption { + return func(w *Waiter) { + w.MaxAttempts = max + } +} + +// WaiterDelay will return a delay the waiter should pause between attempts to +// check the resource state. The passed in attempt is the number of times the +// Waiter has checked the resource state. +// +// Attempt is the number of attempts the Waiter has made checking the resource +// state. +type WaiterDelay func(attempt int) time.Duration + +// ConstantWaiterDelay returns a WaiterDelay that will always return a constant +// delay the waiter should use between attempts. It ignores the number of +// attempts made. +func ConstantWaiterDelay(delay time.Duration) WaiterDelay { + return func(attempt int) time.Duration { + return delay + } +} + +// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in. +func WithWaiterDelay(delayer WaiterDelay) WaiterOption { + return func(w *Waiter) { + w.Delay = delayer + } +} + +// WithWaiterLogger returns a waiter option to set the logger a waiter +// should use to log warnings and errors to. +func WithWaiterLogger(logger Logger) WaiterOption { + return func(w *Waiter) { + w.Logger = logger + } +} + +// WithWaiterRequestOptions returns a waiter option setting the request +// options for each request the waiter makes. Appends to waiter's request +// options already set. +func WithWaiterRequestOptions(opts ...Option) WaiterOption { + return func(w *Waiter) { + w.RequestOptions = append(w.RequestOptions, opts...) + } +} + +// A Waiter provides the functionality to perform a blocking call which will +// wait for a resource state to be satisfied by a service. +// +// This type should not be used directly. The API operations provided in the +// service packages prefixed with "WaitUntil" should be used instead. +type Waiter struct { + Name string + Acceptors []WaiterAcceptor + Logger Logger + + MaxAttempts int + Delay WaiterDelay + + RequestOptions []Option + NewRequest func([]Option) (*Request, error) + SleepWithContext func(Context, time.Duration) error +} + +// ApplyOptions updates the waiter with the list of waiter options provided. +func (w *Waiter) ApplyOptions(opts ...WaiterOption) { + for _, fn := range opts { + fn(w) + } +} + +// WaiterState are states the waiter uses based on WaiterAcceptor definitions +// to identify if the resource state the waiter is waiting on has occurred. +type WaiterState int + +// String returns the string representation of the waiter state. +func (s WaiterState) String() string { + switch s { + case SuccessWaiterState: + return "success" + case FailureWaiterState: + return "failure" + case RetryWaiterState: + return "retry" + default: + return "unknown waiter state" + } +} + +// States the waiter acceptors will use to identify target resource states. +const ( + SuccessWaiterState WaiterState = iota // waiter successful + FailureWaiterState // waiter failed + RetryWaiterState // waiter needs to be retried +) + +// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor +// definition's Expected attribute. +type WaiterMatchMode int + +// Modes the waiter will use when inspecting API response to identify target +// resource states. +const ( + PathAllWaiterMatch WaiterMatchMode = iota // match on all paths + PathWaiterMatch // match on specific path + PathAnyWaiterMatch // match on any path + PathListWaiterMatch // match on list of paths + StatusWaiterMatch // match on status code + ErrorWaiterMatch // match on error +) + +// String returns the string representation of the waiter match mode. +func (m WaiterMatchMode) String() string { + switch m { + case PathAllWaiterMatch: + return "pathAll" + case PathWaiterMatch: + return "path" + case PathAnyWaiterMatch: + return "pathAny" + case PathListWaiterMatch: + return "pathList" + case StatusWaiterMatch: + return "status" + case ErrorWaiterMatch: + return "error" + default: + return "unknown waiter match mode" + } +} + +// WaitWithContext will make requests for the API operation using NewRequest to +// build API requests. The request's response will be compared against the +// Waiter's Acceptors to determine the successful state of the resource the +// waiter is inspecting. +// +// The passed in context must not be nil. If it is nil a panic will occur. The +// Context will be used to cancel the waiter's pending requests and retry delays. +// Use BackgroundContext if no context is available. +// +// The waiter will continue until the target state defined by the Acceptors, +// or the max attempts expires. +// +// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's +// retryer ShouldRetry returns false. This normally will happen when the max +// wait attempts expires. +func (w Waiter) WaitWithContext(ctx Context) error { + + for attempt := 1; ; attempt++ { + req, err := w.NewRequest(w.RequestOptions) + if err != nil { + waiterLogf(w.Logger, "unable to create request %v", err) + return err + } + req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter")) + err = req.Send() + + // See if any of the acceptors match the request's response, or error + for _, a := range w.Acceptors { + if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched { + return matchErr + } + } + + // The Waiter should only check the resource state MaxAttempts times + // This is here instead of in the for loop above to prevent delaying + // unnecessary when the waiter will not retry. + if attempt == w.MaxAttempts { + break + } + + // Delay to wait before inspecting the resource again + if err := sdk.SleepWithContext(ctx, w.Delay(attempt)); err != nil { + return awserr.New(ErrCodeRequestCanceled, "waiter context canceled", err) + } + } + + return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil) +} + +// A WaiterAcceptor provides the information needed to wait for an API operation +// to complete. +type WaiterAcceptor struct { + State WaiterState + Matcher WaiterMatchMode + Argument string + Expected interface{} +} + +// match returns if the acceptor found a match with the passed in request +// or error. True is returned if the acceptor made a match, error is returned +// if there was an error attempting to perform the match. +func (a *WaiterAcceptor) match(name string, l Logger, req *Request, err error) (bool, error) { + result := false + var vals []interface{} + + switch a.Matcher { + case PathAllWaiterMatch, PathWaiterMatch: + // Require all matches to be equal for result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + if len(vals) == 0 { + break + } + result = true + for _, val := range vals { + if !awsutil.DeepEqual(val, a.Expected) { + result = false + break + } + } + case PathAnyWaiterMatch: + // Only a single match needs to equal for the result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + for _, val := range vals { + if awsutil.DeepEqual(val, a.Expected) { + result = true + break + } + } + case PathListWaiterMatch: + // ignored matcher + case StatusWaiterMatch: + s := a.Expected.(int) + result = s == req.HTTPResponse.StatusCode + case ErrorWaiterMatch: + if aerr, ok := err.(awserr.Error); ok { + result = aerr.Code() == a.Expected.(string) + } + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s", + name, a.Matcher) + } + + if !result { + // If there was no matching result found there is nothing more to do + // for this response, retry the request. + return false, nil + } + + switch a.State { + case SuccessWaiterState: + // waiter completed + return true, nil + case FailureWaiterState: + // Waiter failure state triggered + return true, awserr.New(WaiterResourceNotReadyErrorCode, + "failed waiting for successful resource state", err) + case RetryWaiterState: + // clear the error and retry the operation + return false, nil + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s", + name, a.State) + return false, nil + } +} + +func waiterLogf(logger Logger, msg string, args ...interface{}) { + if logger != nil { + logger.Log(fmt.Sprintf(msg, args...)) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/github.com/aws/aws-sdk-go-v2/internal/awsutil/copy.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/copy.go new file mode 100644 index 000000000..938cd14c1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/copy.go @@ -0,0 +1,112 @@ +package awsutil + +import ( + "io" + "reflect" + "time" +) + +// Copy deeply copies a src structure to dst. Useful for copying request and +// response structures. +// +// Can copy between structs of different type, but will only copy fields which +// are assignable, and exist in both structs. Fields which are not assignable, +// or do not exist in both structs are ignored. +func Copy(dst, src interface{}) { + dstval := reflect.ValueOf(dst) + if !dstval.IsValid() { + panic("Copy dst cannot be nil") + } + + rcopy(dstval, reflect.ValueOf(src), true) +} + +// CopyOf returns a copy of src while also allocating the memory for dst. +// src must be a pointer type or this operation will fail. +func CopyOf(src interface{}) (dst interface{}) { + dsti := reflect.New(reflect.TypeOf(src).Elem()) + dst = dsti.Interface() + rcopy(dsti, reflect.ValueOf(src), true) + return +} + +// rcopy performs a recursive copy of values from the source to destination. +// +// root is used to skip certain aspects of the copy which are not valid +// for the root node of a object. +func rcopy(dst, src reflect.Value, root bool) { + if !src.IsValid() { + return + } + + switch src.Kind() { + case reflect.Ptr: + if _, ok := src.Interface().(io.Reader); ok { + if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { + dst.Elem().Set(src) + } else if dst.CanSet() { + dst.Set(src) + } + } else { + e := src.Type().Elem() + if dst.CanSet() && !src.IsNil() { + if _, ok := src.Interface().(*time.Time); !ok { + if dst.Kind() == reflect.String { + dst.SetString(e.String()) + } else { + 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 dst.Kind() != reflect.String && src.Elem().IsValid() { + // Keep the current root state since the depth hasn't changed + rcopy(dst.Elem(), src.Elem(), root) + } + } + case reflect.Struct: + t := dst.Type() + for i := 0; i < t.NumField(); i++ { + name := t.Field(i).Name + srcVal := src.FieldByName(name) + dstVal := dst.FieldByName(name) + if srcVal.IsValid() && dstVal.CanSet() { + rcopy(dstVal, srcVal, false) + } + } + case reflect.Slice: + if src.IsNil() { + break + } + + s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) + dst.Set(s) + for i := 0; i < src.Len(); i++ { + rcopy(dst.Index(i), src.Index(i), false) + } + case reflect.Map: + if src.IsNil() { + break + } + + s := reflect.MakeMap(src.Type()) + dst.Set(s) + for _, k := range src.MapKeys() { + v := src.MapIndex(k) + v2 := reflect.New(v.Type()).Elem() + rcopy(v2, v, false) + dst.SetMapIndex(k, v2) + } + default: + // Assign the value if possible. If its not assignable, the value would + // need to be converted and the impact of that may be unexpected, or is + // not compatible with the dst type. + if src.Type().AssignableTo(dst.Type()) { + dst.Set(src) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/equal.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/equal.go new file mode 100644 index 000000000..bcfe51a2b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/equal.go @@ -0,0 +1,33 @@ +package awsutil + +import ( + "reflect" +) + +// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual. +// In addition to this, this method will also dereference the input values if +// possible so the DeepEqual performed will not fail if one parameter is a +// pointer and the other is not. +// +// DeepEqual will not perform indirection of nested values of the input parameters. +func DeepEqual(a, b interface{}) bool { + ra := reflect.Indirect(reflect.ValueOf(a)) + rb := reflect.Indirect(reflect.ValueOf(b)) + + if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid { + // If the elements are both nil, and of the same type the are equal + // If they are of different types they are not equal + return reflect.TypeOf(a) == reflect.TypeOf(b) + } else if raValid != rbValid { + // Both values must be valid to be equal + return false + } + + // Special casing for strings as typed enumerations are string aliases + // but are not deep equal. + if ra.Kind() == reflect.String && rb.Kind() == reflect.String { + return ra.String() == rb.String() + } + + return reflect.DeepEqual(ra.Interface(), rb.Interface()) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/path_value.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/path_value.go new file mode 100644 index 000000000..7e69bd5eb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/path_value.go @@ -0,0 +1,225 @@ +package awsutil + +import ( + "reflect" + "regexp" + "strconv" + "strings" + + "github.com/jmespath/go-jmespath" +) + +var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`) + +// rValuesAtPath returns a slice of values found in value v. The values +// in v are explored recursively so all nested values are collected. +func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value { + pathparts := strings.Split(path, "||") + if len(pathparts) > 1 { + for _, pathpart := range pathparts { + vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm) + if len(vals) > 0 { + return vals + } + } + return nil + } + + values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))} + components := strings.Split(path, ".") + for len(values) > 0 && len(components) > 0 { + var index *int64 + var indexStar bool + c := strings.TrimSpace(components[0]) + if c == "" { // no actual component, illegal syntax + return nil + } else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] { + // TODO normalize case for user + return nil // don't support unexported fields + } + + // parse this component + if m := indexRe.FindStringSubmatch(c); m != nil { + c = m[1] + if m[2] == "" { + index = nil + indexStar = true + } else { + i, _ := strconv.ParseInt(m[2], 10, 32) + index = &i + indexStar = false + } + } + + nextvals := []reflect.Value{} + for _, value := range values { + // pull component name out of struct member + if value.Kind() != reflect.Struct { + continue + } + + if c == "*" { // pull all members + for i := 0; i < value.NumField(); i++ { + if f := reflect.Indirect(value.Field(i)); f.IsValid() { + nextvals = append(nextvals, f) + } + } + continue + } + + value = value.FieldByNameFunc(func(name string) bool { + if c == name { + return true + } else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) { + return true + } + return false + }) + + if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 { + if !value.IsNil() { + value.Set(reflect.Zero(value.Type())) + } + return []reflect.Value{value} + } + + if createPath && value.Kind() == reflect.Ptr && value.IsNil() { + // TODO if the value is the terminus it should not be created + // if the value to be set to its position is nil. + value.Set(reflect.New(value.Type().Elem())) + value = value.Elem() + } else { + value = reflect.Indirect(value) + } + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + + if indexStar || index != nil { + nextvals = []reflect.Value{} + for _, valItem := range values { + value := reflect.Indirect(valItem) + if value.Kind() != reflect.Slice { + continue + } + + if indexStar { // grab all indices + for i := 0; i < value.Len(); i++ { + idx := reflect.Indirect(value.Index(i)) + if idx.IsValid() { + nextvals = append(nextvals, idx) + } + } + continue + } + + // pull out index + i := int(*index) + if i >= value.Len() { // check out of bounds + if createPath { + // TODO resize slice + } else { + continue + } + } else if i < 0 { // support negative indexing + i = value.Len() + i + } + value = reflect.Indirect(value.Index(i)) + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + } + + components = components[1:] + } + return values +} + +// ValuesAtPath returns a list of values at the case insensitive lexical +// path inside of a structure. +func ValuesAtPath(i interface{}, path string) ([]interface{}, error) { + result, err := jmespath.Search(path, i) + if err != nil { + return nil, err + } + + v := reflect.ValueOf(result) + if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) { + return nil, nil + } + if s, ok := result.([]interface{}); ok { + return s, err + } + if v.Kind() == reflect.Map && v.Len() == 0 { + return nil, nil + } + if v.Kind() == reflect.Slice { + out := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + out[i] = v.Index(i).Interface() + } + return out, nil + } + + return []interface{}{result}, nil +} + +// SetValueAtPath sets a value at the case insensitive lexical path inside +// of a structure. +func SetValueAtPath(i interface{}, path string, v interface{}) { + if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil { + for _, rval := range rvals { + if rval.Kind() == reflect.Ptr && rval.IsNil() { + continue + } + setValue(rval, v) + } + } +} + +func setValue(dstVal reflect.Value, src interface{}) { + if dstVal.Kind() == reflect.Ptr { + dstVal = reflect.Indirect(dstVal) + } + srcVal := reflect.ValueOf(src) + + if !srcVal.IsValid() { // src is literal nil + if dstVal.CanAddr() { + // Convert to pointer so that pointer's value can be nil'ed + // dstVal = dstVal.Addr() + } + dstVal.Set(reflect.Zero(dstVal.Type())) + + } else if srcVal.Kind() == reflect.Ptr { + if srcVal.IsNil() { + srcVal = reflect.Zero(dstVal.Type()) + } else { + srcVal = reflect.ValueOf(src).Elem() + } + dstVal.Set(srcVal) + } else { + if dstVal.Kind() == reflect.String { + dstVal.SetString(srcVal.String()) + } else { + dstVal.Set(srcVal) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/prettify.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/prettify.go new file mode 100644 index 000000000..710eb432f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/prettify.go @@ -0,0 +1,113 @@ +package awsutil + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strings" +) + +// Prettify returns the string representation of a value. +func Prettify(i interface{}) string { + var buf bytes.Buffer + prettify(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +// prettify will recursively walk value v to build a textual +// representation of the value. +func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + strtype := v.Type().String() + if strtype == "time.Time" { + fmt.Fprintf(buf, "%s", v.Interface()) + break + } else if strings.HasPrefix(strtype, "io.") { + buf.WriteString("") + break + } + + buf.WriteString("{\n") + + names := []string{} + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + f := v.Field(i) + if name[0:1] == strings.ToLower(name[0:1]) { + continue // ignore unexported fields + } + if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() { + continue // ignore unset fields + } + names = append(names, name) + } + + for i, n := range names { + val := v.FieldByName(n) + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(n + ": ") + prettify(val, indent+2, buf) + + if i < len(names)-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + strtype := v.Type().String() + if strtype == "[]uint8" { + fmt.Fprintf(buf, " len %d", v.Len()) + break + } + + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + prettify(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + prettify(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + if !v.IsValid() { + fmt.Fprint(buf, "") + return + } + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + case io.ReadSeeker, io.Reader: + format = "buffer(%p)" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/string_value.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/string_value.go new file mode 100644 index 000000000..b6432f1a1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/awsutil/string_value.go @@ -0,0 +1,89 @@ +package awsutil + +import ( + "bytes" + "fmt" + "reflect" + "strings" +) + +// StringValue returns the string representation of a value. +func StringValue(i interface{}) string { + var buf bytes.Buffer + stringValue(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + buf.WriteString("{\n") + + names := []string{} + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + f := v.Field(i) + if name[0:1] == strings.ToLower(name[0:1]) { + continue // ignore unexported fields + } + if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() { + continue // ignore unset fields + } + names = append(names, name) + } + + for i, n := range names { + val := v.FieldByName(n) + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(n + ": ") + stringValue(val, indent+2, buf) + + if i < len(names)-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + stringValue(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + stringValue(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go new file mode 100644 index 000000000..2b42cbe64 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go @@ -0,0 +1,9 @@ +package sdk + +// Invalidator provides access to a type's invalidate method to make it +// invalidate it cache. +// +// e.g aws.SafeCredentialsProvider's Invalidate method. +type Invalidator interface { + Invalidate() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go new file mode 100644 index 000000000..e5640abd8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go @@ -0,0 +1,44 @@ +package sdk + +import ( + "context" + "time" +) + +func init() { + NowTime = time.Now + Sleep = time.Sleep + SleepWithContext = DefaultSleepWithContext +} + +// NowTime is a value for getting the current time. This value can be overriden +// for testing mocking out current time. +var NowTime func() time.Time + +// Sleep is a value for sleeping for a duration. This value can be overriden +// for testing and mocking out sleep duration. +var Sleep func(time.Duration) + +// SleepWithContext will wait for the timer duration to expire, or the context +// is canceled. Which ever happens first. If the context is canceled the Context's +// error will be returned. +// +// This value can be overriden for testing and mocking out sleep duration. +var SleepWithContext func(context.Context, time.Duration) error + +// DefaultSleepWithContext will wait for the timer duration to expire, or the context +// is canceled. Which ever happens first. If the context is canceled the Context's +// error will be returned. +func DefaultSleepWithContext(ctx context.Context, dur time.Duration) error { + t := time.NewTimer(dur) + defer t.Stop() + + select { + case <-t.C: + break + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/build.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/build.go new file mode 100644 index 000000000..f4932c234 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/build.go @@ -0,0 +1,35 @@ +// Package ec2query provides serialization of AWS EC2 requests and responses. +package ec2query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/ec2.json build_test.go + +import ( + "net/url" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol/query/queryutil" +) + +// BuildHandler is a named request handler for building ec2query protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.ec2query.Build", Fn: Build} + +// Build builds a request for the EC2 protocol. +func Build(r *request.Request) { + body := url.Values{ + "Action": {r.Operation.Name}, + "Version": {r.Metadata.APIVersion}, + } + if err := queryutil.Parse(body, r.Params, true); err != nil { + r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err) + } + + if r.ExpireTime == 0 { + r.HTTPRequest.Method = "POST" + r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + r.SetBufferBody([]byte(body.Encode())) + } else { // This is a pre-signed request + r.HTTPRequest.Method = "GET" + r.HTTPRequest.URL.RawQuery = body.Encode() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/unmarshal.go new file mode 100644 index 000000000..64e3ba433 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/ec2query/unmarshal.go @@ -0,0 +1,61 @@ +package ec2query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/ec2.json unmarshal_test.go + +import ( + "encoding/xml" + "io" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil" +) + +// UnmarshalHandler is a named request handler for unmarshaling ec2query protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.ec2query.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling ec2query protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.ec2query.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling ec2query protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.ec2query.UnmarshalError", Fn: UnmarshalError} + +// Unmarshal unmarshals a response body for the EC2 protocol. +func Unmarshal(r *request.Request) { + defer r.HTTPResponse.Body.Close() + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, "") + if err != nil { + r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err) + return + } +} + +// UnmarshalMeta unmarshals response headers for the EC2 protocol. +func UnmarshalMeta(r *request.Request) { + // TODO implement unmarshaling of request IDs +} + +type xmlErrorResponse struct { + XMLName xml.Name `xml:"Response"` + Code string `xml:"Errors>Error>Code"` + Message string `xml:"Errors>Error>Message"` + RequestID string `xml:"RequestID"` +} + +// UnmarshalError unmarshals a response error for the EC2 protocol. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + resp := &xmlErrorResponse{} + err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) + if err != nil && err != io.EOF { + r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err) + } else { + r.Error = awserr.NewRequestFailure( + awserr.New(resp.Code, resp.Message, nil), + r.HTTPResponse.StatusCode, + resp.RequestID, + ) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/encode.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/encode.go new file mode 100644 index 000000000..dc3d1296c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/encode.go @@ -0,0 +1,95 @@ +package protocol + +import ( + "io" +) + +// A FieldMarshaler interface is used to marshal struct fields when encoding. +type FieldMarshaler interface { + MarshalFields(FieldEncoder) error +} + +// FieldMarshalerFunc is a helper utility that wrapps a function and allows +// that function to be called as a FieldMarshaler. +type FieldMarshalerFunc func(FieldEncoder) error + +// MarshalFields will call the underlying function passing in the field encoder +// with the protocol field encoder. +func (fn FieldMarshalerFunc) MarshalFields(e FieldEncoder) error { + return fn(e) +} + +// ValueMarshaler provides a generic type for all encoding field values to be +// passed into a encoder's methods with. +type ValueMarshaler interface { + MarshalValue() (string, error) + MarshalValueBuf([]byte) ([]byte, error) +} + +// A StreamMarshaler interface is used to marshal a stream when encoding. +type StreamMarshaler interface { + MarshalStream() (io.ReadSeeker, error) +} + +// MarshalListValues is a marshaler for list encoders. +type MarshalListValues interface { + MarshalValues(enc ListEncoder) error +} + +// MapMarshaler is a marshaler for map encoders. +type MapMarshaler interface { + MarshalValues(enc MapEncoder) error +} + +// A ListEncoder provides the interface for encoders that will encode List elements. +type ListEncoder interface { + Start() + End() + + Map() MapEncoder + List() ListEncoder + + ListAddValue(v ValueMarshaler) + ListAddFields(m FieldMarshaler) +} + +// A MapEncoder provides the interface for encoders that will encode map elements. +type MapEncoder interface { + Start() + End() + + Map(k string) MapEncoder + List(k string) ListEncoder + + MapSetValue(k string, v ValueMarshaler) + MapSetFields(k string, m FieldMarshaler) +} + +// A FieldEncoder provides the interface for encoding struct field members. +type FieldEncoder interface { + SetValue(t Target, k string, m ValueMarshaler, meta Metadata) + SetStream(t Target, k string, m StreamMarshaler, meta Metadata) + SetFields(t Target, k string, m FieldMarshaler, meta Metadata) + + Map(t Target, k string, meta Metadata) MapEncoder + List(t Target, k string, meta Metadata) ListEncoder +} + +// A FieldBuffer provides buffering of fields so the number of +// allocations are reduced by providng a persistent buffer that is +// used between fields. +type FieldBuffer struct { + buf []byte +} + +// GetValue will retrieve the ValueMarshaler's value by appending the +// value to the buffer. Will return the buffer that was populated. +// +// This buffer is only valid until the next time GetValue is called. +func (b *FieldBuffer) GetValue(m ValueMarshaler) ([]byte, error) { + v, err := m.MarshalValueBuf(b.buf) + if len(v) > len(b.buf) { + b.buf = v + } + return v, err +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/fields.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/fields.go new file mode 100644 index 000000000..b131e2249 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/fields.go @@ -0,0 +1,197 @@ +package protocol + +import ( + "bytes" + "encoding/base64" + "io" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +// QuotedValue represents a type that should be quoted when encoding +// a string value. +type QuotedValue struct { + ValueMarshaler +} + +// BoolValue provies encoding of bool for AWS protocols. +type BoolValue bool + +// MarshalValue formats the value into a string for encoding. +func (v BoolValue) MarshalValue() (string, error) { + return strconv.FormatBool(bool(v)), nil +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +// +// Will reset the length of the passed in slice to 0. +func (v BoolValue) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return strconv.AppendBool(b, bool(v)), nil +} + +// BytesValue provies encoding of string for AWS protocols. +type BytesValue string + +// MarshalValue formats the value into a string for encoding. +func (v BytesValue) MarshalValue() (string, error) { + return base64.StdEncoding.EncodeToString([]byte(v)), nil +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +func (v BytesValue) MarshalValueBuf(b []byte) ([]byte, error) { + m := []byte(v) + + n := base64.StdEncoding.EncodedLen(len(m)) + if len(b) < n { + b = make([]byte, n) + } + base64.StdEncoding.Encode(b, m) + return b[:n], nil +} + +// StringValue provies encoding of string for AWS protocols. +type StringValue string + +// MarshalValue formats the value into a string for encoding. +func (v StringValue) MarshalValue() (string, error) { + return string(v), nil +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +// +// Will reset the length of the passed in slice to 0. +func (v StringValue) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, v...), nil +} + +// Int64Value provies encoding of int64 for AWS protocols. +type Int64Value int64 + +// MarshalValue formats the value into a string for encoding. +func (v Int64Value) MarshalValue() (string, error) { + return strconv.FormatInt(int64(v), 10), nil +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +// +// Will reset the length of the passed in slice to 0. +func (v Int64Value) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return strconv.AppendInt(b, int64(v), 10), nil +} + +// Float64Value provies encoding of float64 for AWS protocols. +type Float64Value float64 + +// MarshalValue formats the value into a string for encoding. +func (v Float64Value) MarshalValue() (string, error) { + return strconv.FormatFloat(float64(v), 'f', -1, 64), nil +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +// +// Will reset the length of the passed in slice to 0. +func (v Float64Value) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return strconv.AppendFloat(b, float64(v), 'f', -1, 64), nil +} + +// JSONValue provies encoding of aws.JSONValues for AWS protocols. +type JSONValue struct { + V aws.JSONValue + EscapeMode EscapeMode +} + +// MarshalValue formats the value into a string for encoding. +func (v JSONValue) MarshalValue() (string, error) { + return EncodeJSONValue(v.V, v.EscapeMode) +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +// +// Will reset the length of the passed in slice to 0. +func (v JSONValue) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + + m, err := EncodeJSONValue(v.V, v.EscapeMode) + if err != nil { + return nil, err + } + + return append(b, []byte(m)...), nil +} + +// Time formats for protocol time fields. +const ( + ISO8601TimeFormat = "2006-01-02T15:04:05Z" // ISO 8601 formated time. + RFC822TimeFromat = "Mon, 2 Jan 2006 15:04:05 GMT" // RFC822 formatted time. + UnixTimeFormat = "unix time format" // Special case for Unix time +) + +// TimeValue provies encoding of time.Time for AWS protocols. +type TimeValue struct { + V time.Time + Format string +} + +// MarshalValue formats the value into a string givin a format for encoding. +func (v TimeValue) MarshalValue() (string, error) { + t := time.Time(v.V) + + if v.Format == UnixTimeFormat { + return strconv.FormatInt(t.UTC().Unix(), 10), nil + } + return t.UTC().Format(v.Format), nil +} + +// MarshalValueBuf formats the value into a byte slice for encoding. +// If there is enough room in the passed in slice v will be appended to it. +// +// Will reset the length of the passed in slice to 0. +func (v TimeValue) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + + m, err := v.MarshalValue() + if err != nil { + return nil, err + } + + return append(b, m...), nil +} + +// A ReadSeekerStream wrapps an io.ReadSeeker to be used as a StreamMarshaler. +type ReadSeekerStream struct { + V io.ReadSeeker +} + +// MarshalStream returns the wrapped io.ReadSeeker for encoding. +func (v ReadSeekerStream) MarshalStream() (io.ReadSeeker, error) { + return v.V, nil +} + +// A BytesStream aliases a byte slice to be used as a StreamMarshaler. +type BytesStream []byte + +// MarshalStream marshals a byte slice into an io.ReadSeeker for encoding. +func (v BytesStream) MarshalStream() (io.ReadSeeker, error) { + return bytes.NewReader([]byte(v)), nil +} + +// A StringStream aliases a string to be used as a StreamMarshaler. +type StringStream string + +// MarshalStream marshals a string into an io.ReadSeeker for encoding. +func (v StringStream) MarshalStream() (io.ReadSeeker, error) { + return strings.NewReader(string(v)), nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/header_encoder.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/header_encoder.go new file mode 100644 index 000000000..38bae691b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/header_encoder.go @@ -0,0 +1,116 @@ +package protocol + +import ( + "fmt" + "net/http" +) + +// HeaderMapEncoder builds a map valu +type HeaderMapEncoder struct { + Prefix string + Header http.Header + Err error +} + +// MapSetValue adds a single value to the header. +func (e *HeaderMapEncoder) MapSetValue(k string, v ValueMarshaler) { + if e.Err != nil { + return + } + + str, err := v.MarshalValue() + if err != nil { + e.Err = err + return + } + + if len(e.Prefix) > 0 { + k = e.Prefix + k + } + + e.Header.Set(k, str) +} + +// List executes the passed in callback with a list encoder based on +// the context of this HeaderMapEncoder. +func (e *HeaderMapEncoder) List(k string) ListEncoder { + if e.Err != nil { + return nil + } + + if len(e.Prefix) > 0 { + k = e.Prefix + k + } + + return &HeaderListEncoder{Key: k, Header: e.Header} +} + +// Map sets the header element with nested maps appending the +// passed in k to the prefix if one was set. +func (e *HeaderMapEncoder) Map(k string) MapEncoder { + if e.Err != nil { + return nil + } + + if len(e.Prefix) > 0 { + k = e.Prefix + k + } + + return &HeaderMapEncoder{Prefix: k, Header: e.Header} +} + +// Start does nothing for header encodings. +func (e *HeaderMapEncoder) Start() {} + +// End does nothing for header encodings. +func (e *HeaderMapEncoder) End() {} + +// MapSetFields Is not implemented, query map of FieldMarshaler is undefined. +func (e *HeaderMapEncoder) MapSetFields(k string, m FieldMarshaler) { + e.Err = fmt.Errorf("header map encoder MapSetFields not supported, %s", k) +} + +// HeaderListEncoder will encode list values nested into a header key. +type HeaderListEncoder struct { + Key string + Header http.Header + Err error +} + +// ListAddValue encodes an individual list value into the header. +func (e *HeaderListEncoder) ListAddValue(v ValueMarshaler) { + if e.Err != nil { + return + } + + str, err := v.MarshalValue() + if err != nil { + e.Err = err + return + } + + e.Header.Add(e.Key, str) +} + +// List Is not implemented, header list of list is undefined. +func (e *HeaderListEncoder) List() ListEncoder { + e.Err = fmt.Errorf("header list encoder ListAddList not supported, %s", e.Key) + return nil +} + +// Map Is not implemented, header list of map is undefined. +func (e *HeaderListEncoder) Map() MapEncoder { + e.Err = fmt.Errorf("header list encoder ListAddMap not supported, %s", e.Key) + return nil +} + +// Start does nothing for header list encodings. +func (e *HeaderListEncoder) Start() {} + +// End does nothing for header list encodings. +func (e *HeaderListEncoder) End() {} + +// ListAddFields Is not implemented, query list of FieldMarshaler is undefined. +func (e *HeaderListEncoder) ListAddFields(m FieldMarshaler) { + e.Err = fmt.Errorf("header list encoder ListAddFields not supported, %s", e.Key) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/idempotency.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/idempotency.go new file mode 100644 index 000000000..53831dff9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/idempotency.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "crypto/rand" + "fmt" + "reflect" +) + +// RandReader is the random reader the protocol package will use to read +// random bytes from. This is exported for testing, and should not be used. +var RandReader = rand.Reader + +const idempotencyTokenFillTag = `idempotencyToken` + +// CanSetIdempotencyToken returns true if the struct field should be +// automatically populated with a Idempotency token. +// +// Only *string and string type fields that are tagged with idempotencyToken +// which are not already set can be auto filled. +func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool { + switch u := v.Interface().(type) { + // To auto fill an Idempotency token the field must be a string, + // tagged for auto fill, and have a zero value. + case *string: + return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + case string: + return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + } + + return false +} + +// GetIdempotencyToken returns a randomly generated idempotency token. +func GetIdempotencyToken() string { + b := make([]byte, 16) + RandReader.Read(b) + + return UUIDVersion4(b) +} + +// SetIdempotencyToken will set the value provided with a Idempotency Token. +// Given that the value can be set. Will panic if value is not setable. +func SetIdempotencyToken(v reflect.Value) { + if v.Kind() == reflect.Ptr { + if v.IsNil() && v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = reflect.Indirect(v) + + if !v.CanSet() { + panic(fmt.Sprintf("unable to set idempotnecy token %v", v)) + } + + b := make([]byte, 16) + _, err := rand.Read(b) + if err != nil { + // TODO handle error + return + } + + v.Set(reflect.ValueOf(UUIDVersion4(b))) +} + +// UUIDVersion4 returns a Version 4 random UUID from the byte slice provided +func UUIDVersion4(u []byte) string { + // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 + // 13th character is "4" + u[6] = (u[6] | 0x40) & 0x4F + // 17th character is "8", "9", "a", or "b" + u[8] = (u[8] | 0x80) & 0xBF + + return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/encode.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/encode.go new file mode 100644 index 000000000..641b05f58 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/encode.go @@ -0,0 +1,290 @@ +package json + +import ( + "bytes" + "fmt" + "io" + + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// An Encoder provides encoding of the AWS JSON protocol. This encoder will will +// write all content to JSON. Only supports body and payload targets. +type Encoder struct { + encoder + root bool +} + +// NewEncoder creates a new encoder for encoding AWS JSON protocol. Only encodes +// fields into the JSON body, and error is returned if target is anything other +// than Body or Payload. +func NewEncoder() *Encoder { + buf := bytes.NewBuffer([]byte{'{'}) + e := &Encoder{ + encoder: encoder{ + buf: buf, + parent: nil, + fieldBuf: &protocol.FieldBuffer{}, + }, + root: true, + } + + return e +} + +// Encode returns the encoded XMl reader. An error will be returned if one was +// encountered while building the JSON body. +func (e *Encoder) Encode() (io.ReadSeeker, error) { + b, err := e.encode() + if err != nil { + return nil, err + } + + if len(b) == 2 { + // Account for first starting object in buffer + return nil, nil + } + + return bytes.NewReader(b), nil +} + +// SetValue sets an individual value to the JSON body. +func (e *Encoder) SetValue(t protocol.Target, k string, v protocol.ValueMarshaler, meta protocol.Metadata) { + e.encoder.writeSep() + e.writeKey(k) + e.writeValue(v) +} + +// SetStream is not supported for JSON protocol marshaling. +func (e *Encoder) SetStream(t protocol.Target, k string, v protocol.StreamMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + e.err = fmt.Errorf("json encoder SetStream not supported, %s, %s", t, k) +} + +// Map will return a new mapEncoder and create a new scope for the map encoding. +func (e *Encoder) Map(t protocol.Target, k string, meta protocol.Metadata) protocol.MapEncoder { + temp := newScope(e.encoder, &e.encoder) + return &mapEncoder{temp, k} +} + +// List will return a new listEncoder and create a new scope for the list encoding. +func (e *Encoder) List(t protocol.Target, k string, meta protocol.Metadata) protocol.ListEncoder { + temp := newScope(e.encoder, &e.encoder) + return &listEncoder{temp, k} +} + +// SetFields sets the nested fields to the JSON body. +func (e *Encoder) SetFields(t protocol.Target, k string, m protocol.FieldMarshaler, meta protocol.Metadata) { + if t == protocol.PayloadTarget { + // Ignore payload key and only marshal body without wrapping in object first. + nested := Encoder{ + encoder: encoder{ + buf: e.encoder.buf, + fieldBuf: e.encoder.fieldBuf, + }, + } + m.MarshalFields(&nested) + e.err = nested.err + return + } + + e.writeSep() + e.writeKey(k) + e.writeObject(func(enc encoder) error { + temp := newScope(enc, &e.encoder) + nested := Encoder{encoder: temp} + m.MarshalFields(&nested) + return nested.err + }) +} + +// A listEncoder encodes elements within a list for the JSON encoder. +type listEncoder struct { + encoder + k string +} + +// Map return a new mapEncoder while creating a new scope for the encoder. +func (e *listEncoder) Map() protocol.MapEncoder { + temp := newScope(e.encoder, &e.encoder) + return &mapEncoder{temp, ""} +} + +// List return a new listEncoder while creating a new scope for the encoder. +func (e *listEncoder) List() protocol.ListEncoder { + temp := newScope(e.encoder, &e.encoder) + return &listEncoder{temp, ""} +} + +// Start will open a new scope for a list and write the given key. +func (e *listEncoder) Start() { + e.encoder.parent.writeSep() + e.writeKey(e.k) + e.WriteListStart() +} + +// End will close the list. +func (e *listEncoder) End() { + e.WriteListEnd() +} + +// ListAddValue will add the value to the list. +func (e *listEncoder) ListAddValue(v protocol.ValueMarshaler) { + e.encoder.writeSep() + e.writeValue(v) +} + +// ListAddFields will set the nested type's fields to the list. +func (e *listEncoder) ListAddFields(m protocol.FieldMarshaler) { + e.encoder.writeSep() + e.writeObject(func(enc encoder) error { + temp := newScope(enc, &e.encoder) + nested := Encoder{encoder: temp} + m.MarshalFields(&nested) + return nested.err + }) +} + +// A mapEncoder encodes key values pair map values for the JSON encoder. +type mapEncoder struct { + encoder encoder + k string +} + +// Start will open a new scope for a list and write the given key. +func (e *mapEncoder) Start() { + e.encoder.parent.writeSep() + e.encoder.writeKey(e.k) + e.encoder.WriteMapStart() +} + +// End will close the list. +func (e *mapEncoder) End() { + e.encoder.WriteMapEnd() +} + +// Map will create a new scope and return a mapEncoder. +func (e *mapEncoder) Map(k string) protocol.MapEncoder { + temp := newScope(e.encoder, &e.encoder) + return &mapEncoder{temp, k} +} + +// List will create a new scope and return a listEncoder +func (e *mapEncoder) List(k string) protocol.ListEncoder { + temp := newScope(e.encoder, &e.encoder) + return &listEncoder{temp, k} +} + +// MapSetValue sets a map value. +func (e *mapEncoder) MapSetValue(k string, v protocol.ValueMarshaler) { + e.encoder.writeSep() + e.encoder.writeKey(k) + e.encoder.writeValue(v) +} + +// MapSetFields will set the nested type's fields under the map. +func (e *mapEncoder) MapSetFields(k string, m protocol.FieldMarshaler) { + e.encoder.writeSep() + e.encoder.writeKey(k) + e.encoder.writeObject(func(enc encoder) error { + temp := newScope(enc, &e.encoder) + nested := Encoder{encoder: temp} + m.MarshalFields(&nested) + return nested.err + }) +} + +type encoder struct { + buf *bytes.Buffer + fieldBuf *protocol.FieldBuffer + started bool + parent *encoder + err error +} + +func (e encoder) encode() ([]byte, error) { + if e.err != nil { + return nil, e.err + } + + // Close the root object + e.buf.WriteByte('}') + + return e.buf.Bytes(), nil +} + +func (e *encoder) writeKey(k string) { + e.buf.WriteByte('"') + e.buf.WriteString(k) + e.buf.WriteByte('"') + e.buf.WriteByte(':') +} + +func (e *encoder) writeValue(v protocol.ValueMarshaler) { + if e.err != nil { + return + } + + b, err := e.fieldBuf.GetValue(v) + if err != nil { + e.err = err + return + } + + var asStr bool + switch v.(type) { + case protocol.QuotedValue: + asStr = true + } + + if asStr { + escapeStringBytes(e.buf, b) + } else { + e.buf.Write(b) + } +} + +func (e *encoder) writeObject(fn func(encoder) error) { + if e.err != nil { + return + } + + e.buf.WriteByte('{') + e.err = fn(*e) + e.buf.WriteByte('}') +} + +func (e *encoder) WriteListStart() { + e.buf.WriteByte('[') +} + +func (e *encoder) WriteListEnd() { + e.buf.WriteByte(']') +} + +func (e *encoder) WriteMapStart() { + e.buf.WriteByte('{') +} + +func (e *encoder) WriteMapEnd() { + e.buf.WriteByte('}') +} + +func (e *encoder) writeSep() { + if e.started { + e.buf.WriteByte(',') + } else { + e.started = true + } + +} + +// newScope will return a new encoder with the correct parent and started to false. +func newScope(e encoder, parent *encoder) encoder { + temp := e + temp.started = false + temp.parent = parent + return temp +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/escape.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/escape.go new file mode 100644 index 000000000..d984d0cdc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/escape.go @@ -0,0 +1,198 @@ +// 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. + +// Copied and modified from Go 1.8 stdlib's encoding/json/#safeSet + +package json + +import ( + "bytes" + "unicode/utf8" +) + +// safeSet holds the value true if the ASCII character with the given array +// position can be represented inside a JSON string without any further +// escaping. +// +// All values are true except for the ASCII control characters (0-31), the +// double quote ("), and the backslash character ("\"). +var safeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +// copied from Go 1.8 stdlib's encoding/json/#hex +var hex = "0123456789abcdef" + +// escapeStringBytes escapes and writes the passed in string bytes to the dst +// buffer +// +// Copied and modifed from Go 1.8 stdlib's encodeing/json/#encodeState.stringBytes +func escapeStringBytes(e *bytes.Buffer, s []byte) { + e.WriteByte('"') + start := 0 + for i := 0; i < len(s); { + if b := s[i]; b < utf8.RuneSelf { + if safeSet[b] { + i++ + continue + } + if start < i { + e.Write(s[start:i]) + } + switch b { + case '\\', '"': + e.WriteByte('\\') + e.WriteByte(b) + case '\n': + e.WriteByte('\\') + e.WriteByte('n') + case '\r': + e.WriteByte('\\') + e.WriteByte('r') + case '\t': + e.WriteByte('\\') + e.WriteByte('t') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. + e.WriteString(`\u00`) + e.WriteByte(hex[b>>4]) + e.WriteByte(hex[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRune(s[i:]) + if c == utf8.RuneError && size == 1 { + if start < i { + e.Write(s[start:i]) + } + e.WriteString(`\ufffd`) + i += size + start = i + continue + } + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + if c == '\u2028' || c == '\u2029' { + if start < i { + e.Write(s[start:i]) + } + e.WriteString(`\u202`) + e.WriteByte(hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + e.Write(s[start:]) + } + e.WriteByte('"') +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/build.go new file mode 100644 index 000000000..029be3216 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/build.go @@ -0,0 +1,293 @@ +// Package jsonutil provides JSON serialization of AWS requests and responses. +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +var timeType = reflect.ValueOf(time.Time{}).Type() +var byteSliceType = reflect.ValueOf([]byte{}).Type() + +// BuildJSON builds a JSON string for a given object v. +func BuildJSON(v interface{}) ([]byte, error) { + var buf bytes.Buffer + + err := buildAny(reflect.ValueOf(v), &buf, "", false) + return buf.Bytes(), err +} + +func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag, parentCollection bool) error { + origVal := value + value = reflect.Indirect(value) + if !value.IsValid() { + return nil + } + + vtype := value.Type() + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if value.Type() != timeType { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return buildStruct(value, buf, tag) + case "list": + return buildList(value, buf, tag) + case "map": + return buildMap(value, buf, tag) + default: + return buildScalar(origVal, buf, tag, parentCollection) + } +} + +func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + buf.WriteByte('{') + + t := value.Type() + first := true + for i := 0; i < t.NumField(); i++ { + member := value.Field(i) + + // This allocates the most memory. + // Additionally, we cannot skip nil fields due to + // idempotency auto filling. + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("json") == "-" { + continue + } + if field.Tag.Get("location") != "" { + continue // ignore non-body elements + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(member, field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(&token) + } + + if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() { + continue // ignore unset fields + } else if member.Kind() == reflect.String && member.Len() == 0 { + continue + } + + if first { + first = false + } else { + buf.WriteByte(',') + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + writeString(name, buf) + buf.WriteString(`:`) + + err := buildAny(member, buf, field.Tag, false) + if err != nil { + return err + } + + } + + buf.WriteString("}") + + return nil +} + +func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("[") + + for i := 0; i < value.Len(); i++ { + elem := value.Index(i) + buildAny(elem, buf, "", true) + + if i < value.Len()-1 { + buf.WriteString(",") + } + } + + buf.WriteString("]") + + return nil +} + +type sortedValues []reflect.Value + +func (sv sortedValues) Len() int { return len(sv) } +func (sv sortedValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].String() } + +func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("{") + + sv := sortedValues(value.MapKeys()) + sort.Sort(sv) + + for i, k := range sv { + if i > 0 { + buf.WriteByte(',') + } + + writeString(k.String(), buf) + buf.WriteString(`:`) + + buildAny(value.MapIndex(k), buf, "", true) + } + + buf.WriteString("}") + + return nil +} + +func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag, parentCollection bool) error { + // prevents allocation on the heap. + scratch := [64]byte{} + switch value := reflect.Indirect(v); value.Kind() { + case reflect.String: + str := value.String() + isEnum := len(tag.Get("enum")) != 0 + if parentCollection || (len(str) > 0 && isEnum) || !isEnum { + writeString(str, buf) + } + case reflect.Bool: + if value.Bool() { + buf.WriteString("true") + } else { + buf.WriteString("false") + } + case reflect.Int64: + buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10)) + case reflect.Float64: + f := value.Float() + if math.IsInf(f, 0) || math.IsNaN(f) { + return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)} + } + buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) + default: + switch converted := value.Interface().(type) { + case time.Time: + buf.Write(strconv.AppendInt(scratch[:0], converted.UTC().Unix(), 10)) + case []byte: + if !value.IsNil() { + buf.WriteByte('"') + if len(converted) < 1024 { + // for small buffers, using Encode directly is much faster. + dst := make([]byte, base64.StdEncoding.EncodedLen(len(converted))) + base64.StdEncoding.Encode(dst, converted) + buf.Write(dst) + } else { + // for large buffers, avoid unnecessary extra temporary + // buffer space. + enc := base64.NewEncoder(base64.StdEncoding, buf) + enc.Write(converted) + enc.Close() + } + buf.WriteByte('"') + } + case aws.JSONValue: + str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) + if err != nil { + return fmt.Errorf("unable to encode JSONValue, %v", err) + } + buf.WriteString(str) + default: + return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) + } + } + return nil +} + +var hex = "0123456789abcdef" + +func writeString(s string, buf *bytes.Buffer) { + buf.WriteByte('"') + for i := 0; i < len(s); i++ { + if s[i] == '"' { + buf.WriteString(`\"`) + } else if s[i] == '\\' { + buf.WriteString(`\\`) + } else if s[i] == '\b' { + buf.WriteString(`\b`) + } else if s[i] == '\f' { + buf.WriteString(`\f`) + } else if s[i] == '\r' { + buf.WriteString(`\r`) + } else if s[i] == '\t' { + buf.WriteString(`\t`) + } else if s[i] == '\n' { + buf.WriteString(`\n`) + } else if s[i] < 32 { + buf.WriteString("\\u00") + buf.WriteByte(hex[s[i]>>4]) + buf.WriteByte(hex[s[i]&0xF]) + } else { + buf.WriteByte(s[i]) + } + } + buf.WriteByte('"') +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/unmarshal.go new file mode 100644 index 000000000..dce3a67b1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil/unmarshal.go @@ -0,0 +1,242 @@ +package jsonutil + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "reflect" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// UnmarshalJSON reads a stream and unmarshals the results in object v. +func UnmarshalJSON(v interface{}, stream io.Reader) error { + var out interface{} + + b, err := ioutil.ReadAll(stream) + if err != nil { + return err + } + + if len(b) == 0 { + return nil + } + + if err := json.Unmarshal(b, &out); err != nil { + return err + } + + return unmarshalAny(reflect.ValueOf(v), out, "") +} + +func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error { + vtype := value.Type() + if vtype.Kind() == reflect.Ptr { + vtype = vtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + _, tok := value.Interface().(*time.Time) + if _, ok := value.Interface().(time.Time); !(ok || tok) { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return unmarshalStruct(value, data, tag) + case "list": + return unmarshalList(value, data, tag) + case "map": + return unmarshalMap(value, data, tag) + default: + return unmarshalScalar(value, data, tag) + } +} + +func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a structure (%#v)", data) + } + + t := value.Type() + if value.Kind() == reflect.Ptr { + if value.IsNil() { // create the structure if it's nil + s := reflect.New(value.Type().Elem()) + value.Set(s) + value = s + } + + value = value.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return unmarshalAny(value.FieldByName(payload), data, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if field.PkgPath != "" { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + member := value.FieldByIndex(field.Index) + err := unmarshalAny(member, mapData[name], field.Tag) + if err != nil { + return err + } + } + return nil +} + +func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + listData, ok := data.([]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a list (%#v)", data) + } + + if value.IsNil() { + l := len(listData) + value.Set(reflect.MakeSlice(value.Type(), l, l)) + } + + for i, c := range listData { + err := unmarshalAny(value.Index(i), c, "") + if err != nil { + return err + } + } + + return nil +} + +func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a map (%#v)", data) + } + + if value.IsNil() { + value.Set(reflect.MakeMap(value.Type())) + } + + for k, v := range mapData { + kvalue := reflect.ValueOf(k) + vvalue := reflect.New(value.Type().Elem()).Elem() + unmarshalAny(vvalue, v, "") + value.SetMapIndex(kvalue, vvalue) + } + + return nil +} + +func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error { + errf := func() error { + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + + switch d := data.(type) { + case nil: + return nil // nothing to do here + case string: + if value.Kind() == reflect.String { + value.SetString(d) + return nil + } + + switch value.Interface().(type) { + case *string: + value.Set(reflect.ValueOf(&d)) + case string: + value.Set(reflect.ValueOf(d)) + case []byte: + b, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(b)) + case aws.JSONValue: + // No need to use escaping as the value is a non-quoted string. + v, err := protocol.DecodeJSONValue(d, protocol.NoEscape) + if err != nil { + return err + } + value.Set(reflect.ValueOf(v)) + default: + return errf() + } + case float64: + switch value.Interface().(type) { + case *int64: + di := int64(d) + value.Set(reflect.ValueOf(&di)) + case int64: + di := int64(d) + value.Set(reflect.ValueOf(di)) + case *float64: + value.Set(reflect.ValueOf(&d)) + case float64: + value.Set(reflect.ValueOf(d)) + case *time.Time: + t := time.Unix(int64(d), 0).UTC() + value.Set(reflect.ValueOf(&t)) + case time.Time: + t := time.Unix(int64(d), 0).UTC() + value.Set(reflect.ValueOf(t)) + default: + return errf() + } + case bool: + switch value.Interface().(type) { + case *bool: + value.Set(reflect.ValueOf(&d)) + default: + return errf() + } + default: + return fmt.Errorf("unsupported JSON value (%v)", data) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonrpc/jsonrpc.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonrpc/jsonrpc.go new file mode 100644 index 000000000..d2d4f8290 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonrpc/jsonrpc.go @@ -0,0 +1,109 @@ +// Package jsonrpc provides JSON RPC utilities for serialization of AWS +// requests and responses. +package jsonrpc + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go + +import ( + "encoding/json" + "io/ioutil" + "strings" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil" + "github.com/aws/aws-sdk-go-v2/private/protocol/rest" +) + +var emptyJSON = []byte("{}") + +// BuildHandler is a named request handler for building jsonrpc protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling jsonrpc protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalError", Fn: UnmarshalError} + +// Build builds a JSON payload for a JSON RPC request. +func Build(req *request.Request) { + var buf []byte + var err error + if req.ParamsFilled() { + buf, err = jsonutil.BuildJSON(req.Params) + if err != nil { + req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err) + return + } + } else { + buf = emptyJSON + } + + if req.Metadata.TargetPrefix != "" || string(buf) != "{}" { + req.SetBufferBody(buf) + } + + if req.Metadata.TargetPrefix != "" { + target := req.Metadata.TargetPrefix + "." + req.Operation.Name + req.HTTPRequest.Header.Add("X-Amz-Target", target) + } + if req.Metadata.JSONVersion != "" { + jsonVersion := req.Metadata.JSONVersion + req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion) + } +} + +// Unmarshal unmarshals a response for a JSON RPC service. +func Unmarshal(req *request.Request) { + defer req.HTTPResponse.Body.Close() + err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.New("SerializationError", "failed decoding JSON RPC response", err) + } + return +} + +// UnmarshalMeta unmarshals headers from a response for a JSON RPC service. +func UnmarshalMeta(req *request.Request) { + rest.UnmarshalMeta(req) +} + +// UnmarshalError unmarshals an error response for a JSON RPC service. +func UnmarshalError(req *request.Request) { + defer req.HTTPResponse.Body.Close() + bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err) + return + } + if len(bodyBytes) == 0 { + req.Error = awserr.NewRequestFailure( + awserr.New("SerializationError", req.HTTPResponse.Status, nil), + req.HTTPResponse.StatusCode, + "", + ) + return + } + var jsonErr jsonErrorResponse + if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { + req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err) + return + } + + codes := strings.SplitN(jsonErr.Code, "#", 2) + req.Error = awserr.NewRequestFailure( + awserr.New(codes[len(codes)-1], jsonErr.Message, nil), + req.HTTPResponse.StatusCode, + req.RequestID, + ) +} + +type jsonErrorResponse struct { + Code string `json:"__type"` + Message string `json:"message"` +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonvalue.go new file mode 100644 index 000000000..8a270434d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/jsonvalue.go @@ -0,0 +1,76 @@ +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +// EscapeMode is the mode that should be use for escaping a value +type EscapeMode uint + +// The modes for escaping a value before it is marshaled, and unmarshaled. +const ( + NoEscape EscapeMode = iota + Base64Escape + QuotedEscape +) + +// EncodeJSONValue marshals the value into a JSON string, and optionally base64 +// encodes the string before returning it. +// +// Will panic if the escape mode is unknown. +func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + + switch escape { + case NoEscape: + return string(b), nil + case Base64Escape: + return base64.StdEncoding.EncodeToString(b), nil + case QuotedEscape: + return strconv.Quote(string(b)), nil + } + + panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape)) +} + +// DecodeJSONValue will attempt to decode the string input as a JSONValue. +// Optionally decoding base64 the value first before JSON unmarshaling. +// +// Will panic if the escape mode is unknown. +func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) { + var b []byte + var err error + + switch escape { + case NoEscape: + b = []byte(v) + case Base64Escape: + b, err = base64.StdEncoding.DecodeString(v) + case QuotedEscape: + var u string + u, err = strconv.Unquote(v) + b = []byte(u) + default: + panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape)) + } + + if err != nil { + return nil, err + } + + m := aws.JSONValue{} + err = json.Unmarshal(b, &m) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/metadata.go new file mode 100644 index 000000000..3a94fd02f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/metadata.go @@ -0,0 +1,24 @@ +package protocol + +// An Attribute is a FieldValue that resides within the imediant context of +// another field. Such as XML attribute for tags. +type Attribute struct { + Name string + Value ValueMarshaler + Meta Metadata +} + +// Metadata is a collection of configuration flags for encoders to render the +// output. +type Metadata struct { + Attributes []Attribute + + Flatten bool + + ListLocationName string + MapLocationNameKey string + MapLocationNameValue string + + XMLNamespacePrefix string + XMLNamespaceURI string +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/path_replace.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/path_replace.go new file mode 100644 index 000000000..ae64a17db --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/path_replace.go @@ -0,0 +1,136 @@ +package protocol + +import ( + "bytes" + "fmt" +) + +const ( + uriTokenStart = '{' + uriTokenStop = '}' + uriTokenSkip = '+' +) + +func bufCap(b []byte, n int) []byte { + if cap(b) < n { + return make([]byte, 0, n) + } + + return b[0:0] +} + +// PathReplace replaces path elements using field buffers +type PathReplace struct { + // May mutate path slice + path []byte + rawPath []byte + fieldBuf []byte +} + +// NewPathReplace creats a built PathReplace value that can be used to replace +// path elements. +func NewPathReplace(path string) PathReplace { + return PathReplace{ + path: []byte(path), + rawPath: []byte(path), + } +} + +// Encode returns an unescaped path, and escaped path. +func (r *PathReplace) Encode() (path string, rawPath string) { + return string(r.path), string(r.rawPath) +} + +// ReplaceElement replaces a single element in the path string. +func (r *PathReplace) ReplaceElement(key, val string) (err error) { + r.path, r.fieldBuf, err = replacePathElement(r.path, r.fieldBuf, key, val, false) + r.rawPath, r.fieldBuf, err = replacePathElement(r.rawPath, r.fieldBuf, key, val, true) + return err +} + +func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) { + fieldBuf = bufCap(fieldBuf, len(key)+3) // { [+] } + fieldBuf = append(fieldBuf, uriTokenStart) + fieldBuf = append(fieldBuf, key...) + + start := bytes.Index(path, fieldBuf) + end := start + len(fieldBuf) + if start < 0 || len(path[end:]) == 0 { + // TODO what to do about error? + return path, fieldBuf, fmt.Errorf("invalid path index, start=%d,end=%d. %s", start, end, path) + } + + encodeSep := true + if path[end] == uriTokenSkip { + // '+' token means do not escape slashes + encodeSep = false + end++ + } + + if escape { + val = escapePath(val, encodeSep) + } + + if path[end] != uriTokenStop { + return path, fieldBuf, fmt.Errorf("invalid path element, does not contain token stop, %s", path) + } + end++ + + fieldBuf = bufCap(fieldBuf, len(val)) + fieldBuf = append(fieldBuf, val...) + + keyLen := end - start + valLen := len(fieldBuf) + + if keyLen == valLen { + copy(path[start:], fieldBuf) + return path, fieldBuf, nil + } + + newLen := len(path) + (valLen - keyLen) + if len(path) < newLen { + path = path[:cap(path)] + } + if cap(path) < newLen { + newURI := make([]byte, newLen) + copy(newURI, path) + path = newURI + } + + // shift + copy(path[start+valLen:], path[end:]) + path = path[:newLen] + copy(path[start:], fieldBuf) + + return path, fieldBuf, nil +} + +// copied from rest.EscapePath +// escapes part of a URL path in Amazon style +func escapePath(path string, encodeSep bool) string { + var buf bytes.Buffer + for i := 0; i < len(path); i++ { + c := path[i] + if noEscape[c] || (c == '/' && !encodeSep) { + buf.WriteByte(c) + } else { + fmt.Fprintf(&buf, "%%%02X", c) + } + } + return buf.String() +} + +var noEscape [256]bool + +func init() { + for i := 0; i < len(noEscape); i++ { + // AWS expects every character except these to be escaped + noEscape[i] = (i >= 'A' && i <= 'Z') || + (i >= 'a' && i <= 'z') || + (i >= '0' && i <= '9') || + i == '-' || + i == '.' || + i == '_' || + i == '~' + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/build.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/build.go new file mode 100644 index 000000000..3905c4bc6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/build.go @@ -0,0 +1,36 @@ +// Package query provides serialization of AWS query requests, and responses. +package query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go + +import ( + "net/url" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol/query/queryutil" +) + +// BuildHandler is a named request handler for building query protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build} + +// Build builds a request for an AWS Query service. +func Build(r *request.Request) { + body := url.Values{ + "Action": {r.Operation.Name}, + "Version": {r.Metadata.APIVersion}, + } + if err := queryutil.Parse(body, r.Params, false); err != nil { + r.Error = awserr.New("SerializationError", "failed encoding Query request", err) + return + } + + if r.ExpireTime == 0 { + r.HTTPRequest.Method = "POST" + r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + r.SetBufferBody([]byte(body.Encode())) + } else { // This is a pre-signed request + r.HTTPRequest.Method = "GET" + r.HTTPRequest.URL.RawQuery = body.Encode() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/queryutil/queryutil.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/queryutil/queryutil.go new file mode 100644 index 000000000..01de5ca94 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/queryutil/queryutil.go @@ -0,0 +1,261 @@ +package queryutil + +import ( + "encoding/base64" + "fmt" + "net/url" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// Parse parses an object i and fills a url.Values object. The isEC2 flag +// indicates if this is the EC2 Query sub-protocol. +func Parse(body url.Values, i interface{}, isEC2 bool) error { + q := queryParser{isEC2: isEC2} + return q.parseValue(body, reflect.ValueOf(i), "", "", false) +} + +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +type queryParser struct { + isEC2 bool +} + +func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag, parentCollection bool) error { + value = elemOf(value) + + // no need to handle zero values + if !value.IsValid() { + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + var err error + switch t { + case "structure": + err = q.parseStruct(v, value, prefix) + case "list": + err = q.parseList(v, value, prefix, tag) + case "map": + err = q.parseMap(v, value, prefix, tag) + default: + err = q.parseScalar(v, value, prefix, tag, parentCollection) + } + + if protocol.IsNotSetError(err) { + return nil + } + return err +} + +func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error { + if !value.IsValid() { + return nil + } + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + elemValue := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + elemValue = reflect.ValueOf(token) + } + + var name string + if q.isEC2 { + name = field.Tag.Get("queryName") + } + if name == "" { + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + if name != "" && q.isEC2 { + name = strings.ToUpper(name[0:1]) + name[1:] + } + } + if name == "" { + name = field.Name + } + + if prefix != "" { + name = prefix + "." + name + } + + if err := q.parseValue(v, elemValue, name, field.Tag, false); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + if _, ok := value.Interface().([]byte); ok { + return q.parseScalar(v, value, prefix, tag, true) + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + if listName := tag.Get("locationNameList"); listName == "" { + prefix += ".member" + } else { + prefix += "." + listName + } + } + + for i := 0; i < value.Len(); i++ { + slicePrefix := prefix + if slicePrefix == "" { + slicePrefix = strconv.Itoa(i + 1) + } else { + slicePrefix = slicePrefix + "." + strconv.Itoa(i+1) + } + if err := q.parseValue(v, value.Index(i), slicePrefix, "", true); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + prefix += ".entry" + } + + // sort keys for improved serialization consistency. + // this is not strictly necessary for protocol support. + mapKeyValues := value.MapKeys() + mapKeys := map[string]reflect.Value{} + mapKeyNames := make([]string, len(mapKeyValues)) + for i, mapKey := range mapKeyValues { + name := mapKey.String() + mapKeys[name] = mapKey + mapKeyNames[i] = name + } + sort.Strings(mapKeyNames) + + for i, mapKeyName := range mapKeyNames { + mapKey := mapKeys[mapKeyName] + mapValue := value.MapIndex(mapKey) + + kname := tag.Get("locationNameKey") + if kname == "" { + kname = "key" + } + vname := tag.Get("locationNameValue") + if vname == "" { + vname = "value" + } + + // serialize key + var keyName string + if prefix == "" { + keyName = strconv.Itoa(i+1) + "." + kname + } else { + keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname + } + + if err := q.parseValue(v, mapKey, keyName, "", true); err != nil { + return err + } + + // serialize value + var valueName string + if prefix == "" { + valueName = strconv.Itoa(i+1) + "." + vname + } else { + valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname + } + + if err := q.parseValue(v, mapValue, valueName, "", true); err != nil { + return err + } + } + + return nil +} + +func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag, parentCollection bool) error { + if r.Kind() == reflect.String { + val, err := protocol.GetValue(r) + isEnum := len(tag.Get("enum")) != 0 + + if err == nil || parentCollection { + v.Set(name, val) + } else if isEnum && len(val) > 0 { + v.Set(name, val) + } else if !isEnum { + v.Set(name, val) + } + return err + } + + switch value := r.Interface().(type) { + case string: + v.Set(name, value) + case []byte: + if !r.IsNil() { + v.Set(name, base64.StdEncoding.EncodeToString(value)) + } + case bool: + v.Set(name, strconv.FormatBool(value)) + case int64: + v.Set(name, strconv.FormatInt(value, 10)) + case int: + v.Set(name, strconv.Itoa(value)) + case float64: + v.Set(name, strconv.FormatFloat(value, 'f', -1, 64)) + case float32: + v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32)) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + v.Set(name, value.UTC().Format(ISO8601UTC)) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal.go new file mode 100644 index 000000000..36c0e12e4 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal.go @@ -0,0 +1,33 @@ +package query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go + +import ( + "encoding/xml" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil" +) + +// UnmarshalHandler is a named request handler for unmarshaling query protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals a response for an AWS Query service. +func Unmarshal(r *request.Request) { + defer r.HTTPResponse.Body.Close() + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") + if err != nil { + r.Error = awserr.New("SerializationError", "failed decoding Query response", err) + return + } +} + +// UnmarshalMeta unmarshals header response values for an AWS Query service. +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal_error.go new file mode 100644 index 000000000..2af00c326 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query/unmarshal_error.go @@ -0,0 +1,66 @@ +package query + +import ( + "encoding/xml" + "io/ioutil" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" +) + +type xmlErrorResponse struct { + XMLName xml.Name `xml:"ErrorResponse"` + Code string `xml:"Error>Code"` + Message string `xml:"Error>Message"` + RequestID string `xml:"RequestId"` +} + +type xmlServiceUnavailableResponse struct { + XMLName xml.Name `xml:"ServiceUnavailableException"` +} + +// UnmarshalErrorHandler is a name request handler to unmarshal request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError} + +// UnmarshalError unmarshals an error response for an AWS Query service. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err) + return + } + + // First check for specific error + resp := xmlErrorResponse{} + decodeErr := xml.Unmarshal(bodyBytes, &resp) + if decodeErr == nil { + reqID := resp.RequestID + if reqID == "" { + reqID = r.RequestID + } + r.Error = awserr.NewRequestFailure( + awserr.New(resp.Code, resp.Message, nil), + r.HTTPResponse.StatusCode, + reqID, + ) + return + } + + // Check for unhandled error + servUnavailResp := xmlServiceUnavailableResponse{} + unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp) + if unavailErr == nil { + r.Error = awserr.NewRequestFailure( + awserr.New("ServiceUnavailableException", "service is unavailable", nil), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + // Failed to retrieve any error message from the response body + r.Error = awserr.New("SerializationError", + "failed to decode query XML error response", decodeErr) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query_encoder.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query_encoder.go new file mode 100644 index 000000000..baebc9944 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/query_encoder.go @@ -0,0 +1,105 @@ +package protocol + +import ( + "fmt" + "net/url" +) + +// QueryMapEncoder builds a query string. +type QueryMapEncoder struct { + Prefix string + Query url.Values + Err error +} + +// List will return a new QueryListEncoder. +func (e *QueryMapEncoder) List(k string) ListEncoder { + if len(e.Prefix) > 0 { + k = e.Prefix + k + } + + return &QueryListEncoder{k, e.Query, nil} +} + +// Map will return a new QueryMapEncoder. +func (e *QueryMapEncoder) Map(k string) MapEncoder { + if len(e.Prefix) > 0 { + k = e.Prefix + k + } + + return &QueryMapEncoder{k, e.Query, nil} +} + +// Start does nothing. +func (e *QueryMapEncoder) Start() {} + +// End does nothing. +func (e *QueryMapEncoder) End() {} + +// MapSetValue adds a single value to the query. +func (e *QueryMapEncoder) MapSetValue(k string, v ValueMarshaler) { + if e.Err != nil { + return + } + + str, err := v.MarshalValue() + if err != nil { + e.Err = err + return + } + + if len(e.Prefix) > 0 { + k = e.Prefix + k + } + + e.Query.Add(k, str) +} + +// MapSetFields Is not implemented, query map of map is undefined. +func (e *QueryMapEncoder) MapSetFields(k string, m FieldMarshaler) { + e.Err = fmt.Errorf("query map encoder MapSetFields not supported, %s", e.Prefix) +} + +// QueryListEncoder will encode list values nested into a query key. +type QueryListEncoder struct { + Key string + Query url.Values + Err error +} + +// List will return a new QueryListEncoder. +func (e *QueryListEncoder) List() ListEncoder { + return &QueryListEncoder{e.Key, e.Query, nil} +} + +// Start does nothing for the query protocol. +func (e *QueryListEncoder) Start() {} + +// End does nothing for the query protocol. +func (e *QueryListEncoder) End() {} + +// Map will return a new QueryMapEncoder. +func (e *QueryListEncoder) Map() MapEncoder { + k := e.Key + return &QueryMapEncoder{k, e.Query, nil} +} + +// ListAddValue encodes an individual list value into the querystring. +func (e *QueryListEncoder) ListAddValue(v ValueMarshaler) { + if e.Err != nil { + return + } + + str, err := v.MarshalValue() + if err != nil { + e.Err = err + return + } + + e.Query.Add(e.Key, str) +} + +// ListAddFields Is not implemented, query list of FieldMarshaler is undefined. +func (e *QueryListEncoder) ListAddFields(m FieldMarshaler) { + e.Err = fmt.Errorf("query list encoder ListAddFields not supported, %s", e.Key) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/build.go new file mode 100644 index 000000000..14c9f474e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/build.go @@ -0,0 +1,339 @@ +// Package rest provides RESTful serialization of AWS requests and responses. +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/url" + "path" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// RFC822 returns an RFC822 formatted timestamp for AWS protocols +const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT" + +// Whether the byte value can be sent without escaping in AWS URLs +var noEscape [256]bool + +func init() { + for i := 0; i < len(noEscape); i++ { + // AWS expects every character except these to be escaped + noEscape[i] = (i >= 'A' && i <= 'Z') || + (i >= 'a' && i <= 'z') || + (i >= '0' && i <= '9') || + i == '-' || + i == '.' || + i == '_' || + i == '~' + } +} + +// BuildHandler is a named request handler for building rest protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build} + +// Build builds the REST component of a service request. +func Build(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, false) + buildBody(r, v) + } +} + +// BuildAsGET builds the REST component of a service request with the ability to hoist +// data from the body. +func BuildAsGET(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, true) + buildBody(r, v) + } +} + +func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) { + query := r.HTTPRequest.URL.Query() + + // Setup the raw path to match the base path pattern. This is needed + // so that when the path is mutated a custom escaped version can be + // stored in RawPath that will be used by the Go client. + r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path + + for i := 0; i < v.NumField(); i++ { + m := v.Field(i) + if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + field := v.Type().Field(i) + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + + switch m.Kind() { + case reflect.Ptr, reflect.Interface: + if !m.Elem().IsValid() { + continue + } + } + + if field.Tag.Get("ignore") != "" { + continue + } + + var err error + switch field.Tag.Get("location") { + case "headers": // header maps + err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag) + case "header": + err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag) + case "uri": + err = buildURI(r.HTTPRequest.URL, m, name, field.Tag) + case "querystring": + err = buildQueryString(query, m, name, field.Tag) + default: + if buildGETQuery { + err = buildQueryString(query, m, name, field.Tag) + } + } + + if protocol.IsNotSetError(err) { + err = nil + } + r.Error = err + } + if r.Error != nil { + return + } + } + + r.HTTPRequest.URL.RawQuery = query.Encode() + if !r.Config.DisableRestProtocolURICleaning { + cleanPath(r.HTTPRequest.URL) + } +} + +func buildBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := reflect.Indirect(v.FieldByName(payloadName)) + if payload.IsValid() && payload.Interface() != nil { + switch reader := payload.Interface().(type) { + case io.ReadSeeker: + r.SetReaderBody(reader) + case []byte: + r.SetBufferBody(reader) + case string: + r.SetStringBody(reader) + default: + r.Error = awserr.New("SerializationError", + "failed to encode REST request", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } +} + +func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error { + var err error + str := "" + + if v.Kind() == reflect.String { + str, err = protocol.GetValue(v) + } else { + str, err = convertType(v, tag) + } + + if protocol.IsNotSetError(err) { + return nil + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + } + + header.Add(name, str) + + return nil +} + +func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error { + prefix := tag.Get("locationName") + for _, key := range v.MapKeys() { + str, err := convertType(v.MapIndex(key), tag) + if protocol.IsNotSetError(err) { + continue + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + + } + + header.Add(prefix+key.String(), str) + } + return nil +} + +func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error { + value := "" + var err error + if v.Kind() == reflect.String { + value, err = protocol.GetValue(v) + } else { + value, err = convertType(v, tag) + } + + if protocol.IsNotSetError(err) { + return nil + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + } + + u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1) + u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1) + + u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1) + u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1) + + return nil +} + +func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error { + if kind := v.Kind(); kind == reflect.String { + value, err := protocol.GetValue(v) + if err == nil { + query.Add(name, value) + } + return err + } else if kind == reflect.Ptr { + v = v.Elem() + } + + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.String { + for i := 0; i < v.Len(); i++ { + query.Add(name, v.Index(i).String()) + } + return nil + } + + switch value := v.Interface().(type) { + case []*string: + for _, item := range value { + query.Add(name, *item) + } + case []string: + for _, item := range value { + query.Add(name, item) + } + case map[string]*string: + for key, item := range value { + query.Add(key, *item) + } + case map[string]string: + for key, item := range value { + query.Add(key, item) + } + case map[string][]*string: + for key, items := range value { + for _, item := range items { + query.Add(key, *item) + } + } + case map[string][]string: + for key, items := range value { + for _, item := range items { + query.Add(key, item) + } + } + default: + str, err := convertType(v, tag) + if protocol.IsNotSetError(err) { + return nil + } else if err != nil { + return awserr.New("SerializationError", "failed to encode REST request", err) + } + + query.Set(name, str) + } + + return nil +} + +func cleanPath(u *url.URL) { + hasSlash := strings.HasSuffix(u.Path, "/") + + // clean up path, removing duplicate `/` + u.Path = path.Clean(u.Path) + u.RawPath = path.Clean(u.RawPath) + + if hasSlash && !strings.HasSuffix(u.Path, "/") { + u.Path += "/" + u.RawPath += "/" + } +} + +// EscapePath escapes part of a URL path in Amazon style +func EscapePath(path string, encodeSep bool) string { + var buf bytes.Buffer + for i := 0; i < len(path); i++ { + c := path[i] + if noEscape[c] || (c == '/' && !encodeSep) { + buf.WriteByte(c) + } else { + fmt.Fprintf(&buf, "%%%02X", c) + } + } + return buf.String() +} + +func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) { + v = reflect.Indirect(v) + if !v.IsValid() { + return "", &protocol.ErrValueNotSet{} + } + + switch value := v.Interface().(type) { + case string: + str = value + case []byte: + str = base64.StdEncoding.EncodeToString(value) + case bool: + str = strconv.FormatBool(value) + case int64: + str = strconv.FormatInt(value, 10) + case float64: + str = strconv.FormatFloat(value, 'f', -1, 64) + case time.Time: + str = value.UTC().Format(RFC822) + case aws.JSONValue: + if len(value) == 0 { + return "", &protocol.ErrValueNotSet{} + } + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + str, err = protocol.EncodeJSONValue(value, escaping) + if err != nil { + return "", fmt.Errorf("unable to encode JSONValue, %v", err) + } + + default: + err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type()) + return "", err + } + return str, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/encode.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/encode.go new file mode 100644 index 000000000..ff1ce9493 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/encode.go @@ -0,0 +1,144 @@ +package rest + +import ( + "fmt" + "io" + "net/http" + "net/url" + + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// An Encoder provides encoding of REST URI path, query, and header components +// of an HTTP request. Can also encode a stream as the payload. +// +// Does not support SetFields. +type Encoder struct { + req *http.Request + + path protocol.PathReplace + + query url.Values + header http.Header + + payload io.ReadSeeker + + err error +} + +// NewEncoder creates a new encoder from the passed in request. All query and +// header values will be added on top of the request's existing values. Overwriting +// duplicate values. +func NewEncoder(req *http.Request) *Encoder { + e := &Encoder{ + req: req, + + path: protocol.NewPathReplace(req.URL.Path), + query: req.URL.Query(), + header: req.Header, + } + + return e +} + +// Encode will return the request and body if one was set. If the body +// payload was not set the io.ReadSeeker will be nil. +// +// returns any error if one occured while encoding the API's parameters. +func (e *Encoder) Encode() (*http.Request, io.ReadSeeker, error) { + if e.err != nil { + return nil, nil, e.err + } + + e.req.URL.Path, e.req.URL.RawPath = e.path.Encode() + e.req.URL.RawQuery = e.query.Encode() + e.req.Header = e.header + + return e.req, e.payload, nil +} + +// SetValue will set a value to the header, path, query. +// +// If the request's method is GET all BodyTarget values will be written to +// the query string. +func (e *Encoder) SetValue(t protocol.Target, k string, v protocol.ValueMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + var str string + str, e.err = v.MarshalValue() + if e.err != nil { + return + } + + switch t { + case protocol.HeaderTarget: + e.header.Set(k, str) + case protocol.PathTarget: + e.path.ReplaceElement(k, str) + case protocol.QueryTarget: + e.query.Set(k, str) + case protocol.BodyTarget: + if e.req.Method != "GET" { + e.err = fmt.Errorf("body target not supported for rest non-GET methods %s, %s", t, k) + return + } + e.query.Set(k, str) + default: + e.err = fmt.Errorf("unknown SetValue rest encode target, %s, %s", t, k) + } +} + +// SetStream will set the stream to the payload of the request. +func (e *Encoder) SetStream(t protocol.Target, k string, v protocol.StreamMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PayloadTarget: + e.payload, e.err = v.MarshalStream() + default: + e.err = fmt.Errorf("unknown SetStream rest encode target, %s, %s", t, k) + } +} + +// List will set the nested list values to the header or query. +func (e *Encoder) List(t protocol.Target, k string, meta protocol.Metadata) protocol.ListEncoder { + if e.err != nil { + return nil + } + + switch t { + case protocol.QueryTarget: + return &protocol.QueryListEncoder{Key: k, Query: e.query} + case protocol.HeaderTarget: + return &protocol.HeaderListEncoder{Key: k, Header: e.header} + default: + e.err = fmt.Errorf("unknown SetList rest encode target, %s, %s", t, k) + return nil + } +} + +// Map will set the nested map values to the header or query. +func (e *Encoder) Map(t protocol.Target, k string, meta protocol.Metadata) protocol.MapEncoder { + if e.err != nil { + return nil + } + + switch t { + case protocol.QueryTarget: + return &protocol.QueryMapEncoder{Query: e.query} + case protocol.HeadersTarget: + return &protocol.HeaderMapEncoder{Prefix: k, Header: e.header} + default: + e.err = fmt.Errorf("unknown SetMap rest encode target, %s, %s", t, k) + return nil + } +} + +// SetFields is not supported for REST encoder. +func (e *Encoder) SetFields(t protocol.Target, k string, m protocol.FieldMarshaler, meta protocol.Metadata) { + e.err = fmt.Errorf("rest encoder SetFields not supported, %s, %s", t, k) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/payload.go new file mode 100644 index 000000000..4366de2e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/payload.go @@ -0,0 +1,45 @@ +package rest + +import "reflect" + +// PayloadMember returns the payload field member of i if there is one, or nil. +func PayloadMember(i interface{}) interface{} { + if i == nil { + return nil + } + + v := reflect.ValueOf(i).Elem() + if !v.IsValid() { + return nil + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + field, _ := v.Type().FieldByName(payloadName) + if field.Tag.Get("type") != "structure" { + return nil + } + + payload := v.FieldByName(payloadName) + if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { + return payload.Interface() + } + } + } + return nil +} + +// PayloadType returns the type of a payload field member of i if there is one, or "". +func PayloadType(i interface{}) string { + v := reflect.Indirect(reflect.ValueOf(i)) + if !v.IsValid() { + return "" + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + if member, ok := v.Type().FieldByName(payloadName); ok { + return member.Tag.Get("type") + } + } + } + return "" +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/unmarshal.go new file mode 100644 index 000000000..a9f141546 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/rest/unmarshal.go @@ -0,0 +1,251 @@ +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals the REST component of a response in a REST service. +func Unmarshal(r *request.Request) { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalBody(r, v) +} + +// UnmarshalMeta unmarshals the REST metadata of a response in a REST service +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") + if r.RequestID == "" { + // Alternative version of request id in the header + r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") + } + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalLocationElements(r, v) +} + +func unmarshalBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := v.FieldByName(payloadName) + if payload.IsValid() { + switch payload.Interface().(type) { + case []byte: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + } else { + payload.Set(reflect.ValueOf(b)) + } + case *string: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + } else { + str := string(b) + payload.Set(reflect.ValueOf(&str)) + } + default: + switch payload.Type().String() { + case "io.ReadCloser": + payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) + case "io.ReadSeeker": + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", + "failed to read response body", err) + return + } + payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) + default: + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + defer r.HTTPResponse.Body.Close() + r.Error = awserr.New("SerializationError", + "failed to decode REST response", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } + } +} + +func unmarshalLocationElements(r *request.Request, v reflect.Value) { + for i := 0; i < v.NumField(); i++ { + m, field := v.Field(i), v.Type().Field(i) + if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + + switch field.Tag.Get("location") { + case "statusCode": + unmarshalStatusCode(m, r.HTTPResponse.StatusCode) + case "header": + err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + break + } + case "headers": + prefix := field.Tag.Get("locationName") + err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) + break + } + } + } + if r.Error != nil { + return + } + } +} + +func unmarshalStatusCode(v reflect.Value, statusCode int) { + if !v.IsValid() { + return + } + + switch v.Interface().(type) { + case *int64: + s := int64(statusCode) + v.Set(reflect.ValueOf(&s)) + case int64: + s := int64(statusCode) + v.Set(reflect.ValueOf(s)) + } +} + +func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error { + switch r.Interface().(type) { + case map[string]string: // we only support string map value types + out := map[string]string{} + for k, v := range headers { + k = http.CanonicalHeaderKey(k) + if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) { + out[k[len(prefix):]] = v[0] + } + } + r.Set(reflect.ValueOf(out)) + } + return nil +} + +func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error { + isJSONValue := tag.Get("type") == "jsonvalue" + if isJSONValue { + if len(header) == 0 { + return nil + } + } else if v.Kind() == reflect.String { + if len(header) > 0 { + v.SetString(header) + } + return nil + } else if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) { + return nil + } + + switch v.Interface().(type) { + case *string: + v.Set(reflect.ValueOf(&header)) + case string: + v.Set(reflect.ValueOf(header)) + case []byte: + b, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *bool: + b, err := strconv.ParseBool(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case bool: + b, err := strconv.ParseBool(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(b)) + case *int64: + i, err := strconv.ParseInt(header, 10, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&i)) + case int64: + i, err := strconv.ParseInt(header, 10, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(i)) + case *float64: + f, err := strconv.ParseFloat(header, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&f)) + case float64: + f, err := strconv.ParseFloat(header, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(f)) + case *time.Time: + t, err := time.Parse(RFC822, header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&t)) + case time.Time: + t, err := time.Parse(RFC822, header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(t)) + case aws.JSONValue: + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + m, err := protocol.DecodeJSONValue(header, escaping) + if err != nil { + return err + } + v.Set(reflect.ValueOf(m)) + default: + err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/encode.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/encode.go new file mode 100644 index 000000000..84c6dc809 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/encode.go @@ -0,0 +1,165 @@ +package restjson + +import ( + "fmt" + "io" + "net/http" + + "github.com/aws/aws-sdk-go-v2/private/protocol" + "github.com/aws/aws-sdk-go-v2/private/protocol/json" + "github.com/aws/aws-sdk-go-v2/private/protocol/rest" +) + +// An Encoder provides encoding of the AWS RESTJSON protocol. This encoder combindes +// the JSON and REST encoders deligating to them for their associated targets. +// +// It is invalid to set a JSON and stream payload on the same encoder. +type Encoder struct { + method string + reqEncoder *rest.Encoder + bodyEncoder *json.Encoder + t protocol.Target + + err error +} + +// NewEncoder creates a new encoder for encoding the AWS RESTJSON protocol. +// The request passed in will be the base the path, query, and headers encoded +// will be set on top of. +func NewEncoder(req *http.Request) *Encoder { + e := &Encoder{ + method: req.Method, + reqEncoder: rest.NewEncoder(req), + bodyEncoder: json.NewEncoder(), + } + + return e +} + +// Encode returns the encoded request, and body payload. If no payload body was +// set nil will be returned. If an error occurred while encoding the API an +// error will be returned. +func (e *Encoder) Encode() (*http.Request, io.ReadSeeker, error) { + req, payloadBody, err := e.reqEncoder.Encode() + if err != nil { + return nil, nil, err + } + + jsonBody, err := e.bodyEncoder.Encode() + if err != nil { + return nil, nil, err + } + + havePayload := payloadBody != nil + haveJSON := jsonBody != nil + + if havePayload == haveJSON && haveJSON { + return nil, nil, fmt.Errorf("unexpected JSON body and request payload for AWSMarshaler") + } + + body := payloadBody + if body == nil { + body = jsonBody + } + + return req, body, err +} + +// SetValue will set a value to the header, path, query, or body. +// +// If the request's method is GET all BodyTarget values will be written to +// the query string. +func (e *Encoder) SetValue(t protocol.Target, k string, v protocol.ValueMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PathTarget: + fallthrough + case protocol.QueryTarget: + fallthrough + case protocol.HeaderTarget: + e.reqEncoder.SetValue(t, k, v, meta) + case protocol.BodyTarget: + fallthrough + case protocol.PayloadTarget: + if e.method == "GET" { + e.reqEncoder.SetValue(t, k, v, meta) + } else { + e.bodyEncoder.SetValue(t, k, v, meta) + } + default: + e.err = fmt.Errorf("unknown SetValue restjson encode target, %s, %s", t, k) + } +} + +// SetStream will set the stream to the payload of the request. +func (e *Encoder) SetStream(t protocol.Target, k string, v protocol.StreamMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PayloadTarget: + e.reqEncoder.SetStream(t, k, v, meta) + default: + e.err = fmt.Errorf("invalid target %s, for SetStream, must be PayloadTarget", t) + } +} + +// List will return the proper list encoder based on the given protocol.Target. +func (e *Encoder) List(t protocol.Target, k string, meta protocol.Metadata) protocol.ListEncoder { + if e.err != nil { + return nil + } + e.t = t + + switch t { + case protocol.HeaderTarget: + fallthrough + case protocol.QueryTarget: + return e.reqEncoder.List(t, k, meta) + case protocol.BodyTarget: + return e.bodyEncoder.List(t, k, meta) + default: + e.err = fmt.Errorf("unknown SetList restjson encode target, %s, %s", t, k) + return nil + } +} + +// Map will return the proper map encoder based on the given protocol Target. +func (e *Encoder) Map(t protocol.Target, k string, meta protocol.Metadata) protocol.MapEncoder { + if e.err != nil { + return nil + } + + e.t = t + switch t { + case protocol.QueryTarget: + fallthrough + case protocol.HeadersTarget: + return e.reqEncoder.Map(t, k, meta) + case protocol.BodyTarget: + return e.bodyEncoder.Map(t, k, meta) + default: + e.err = fmt.Errorf("unknown SetMap restjson encode target, %s, %s", t, k) + return nil + } +} + +// SetFields will set the nested type's fields to the body. +func (e *Encoder) SetFields(t protocol.Target, k string, m protocol.FieldMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PayloadTarget: + fallthrough + case protocol.BodyTarget: + e.bodyEncoder.SetFields(t, k, m, meta) + default: + e.err = fmt.Errorf("unknown SetMarshaler restjson encode target, %s, %s", t, k) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/restjson.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/restjson.go new file mode 100644 index 000000000..2e7aff236 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restjson/restjson.go @@ -0,0 +1,112 @@ +// Package restjson provides RESTful JSON serialization of AWS +// requests and responses. +package restjson + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-json.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-json.json unmarshal_test.go + +import ( + "encoding/json" + "io" + "io/ioutil" + "strings" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol" + "github.com/aws/aws-sdk-go-v2/private/protocol/jsonrpc" + "github.com/aws/aws-sdk-go-v2/private/protocol/rest" +) + +// BuildHandler is a named request handler for building restjson protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.restjson.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling restjson protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.restjson.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling restjson protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.restjson.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling restjson protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.restjson.UnmarshalError", Fn: UnmarshalError} + +// Build builds a request for the REST JSON protocol. +func Build(r *request.Request) { + if m, ok := r.Params.(protocol.FieldMarshaler); ok { + e := NewEncoder(r.HTTPRequest) + + m.MarshalFields(e) + + var body io.ReadSeeker + var err error + r.HTTPRequest, body, err = e.Encode() + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to encode rest JSON request", err) + return + } + if body != nil { + r.SetReaderBody(body) + } + return + } + + rest.Build(r) + + if t := rest.PayloadType(r.Params); t == "structure" || t == "" { + jsonrpc.Build(r) + } +} + +// Unmarshal unmarshals a response body for the REST JSON protocol. +func Unmarshal(r *request.Request) { + if t := rest.PayloadType(r.Data); t == "structure" || t == "" { + jsonrpc.Unmarshal(r) + } else { + rest.Unmarshal(r) + } +} + +// UnmarshalMeta unmarshals response headers for the REST JSON protocol. +func UnmarshalMeta(r *request.Request) { + rest.UnmarshalMeta(r) +} + +// UnmarshalError unmarshals a response error for the REST JSON protocol. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + code := r.HTTPResponse.Header.Get("X-Amzn-Errortype") + bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "failed reading REST JSON error response", err) + return + } + if len(bodyBytes) == 0 { + r.Error = awserr.NewRequestFailure( + awserr.New("SerializationError", r.HTTPResponse.Status, nil), + r.HTTPResponse.StatusCode, + "", + ) + return + } + var jsonErr jsonErrorResponse + if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { + r.Error = awserr.New("SerializationError", "failed decoding REST JSON error response", err) + return + } + + if code == "" { + code = jsonErr.Code + } + + code = strings.SplitN(code, ":", 2)[0] + r.Error = awserr.NewRequestFailure( + awserr.New(code, jsonErr.Message, nil), + r.HTTPResponse.StatusCode, + r.RequestID, + ) +} + +type jsonErrorResponse struct { + Code string `json:"code"` + Message string `json:"message"` +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/encode.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/encode.go new file mode 100644 index 000000000..501e79acf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/encode.go @@ -0,0 +1,162 @@ +package restxml + +import ( + "bytes" + "fmt" + "io" + "net/http" + + "github.com/aws/aws-sdk-go-v2/private/protocol" + "github.com/aws/aws-sdk-go-v2/private/protocol/rest" + "github.com/aws/aws-sdk-go-v2/private/protocol/xml" +) + +// An Encoder provides encoding of the AWS RESTXML protocol. This encoder combindes +// the XML and REST encoders deligating to them for their associated targets. +// +// It is invalid to set a XML and stream payload on the same encoder. +type Encoder struct { + method string + reqEncoder *rest.Encoder + bodyEncoder *xml.Encoder + + buf *bytes.Buffer + err error +} + +// NewEncoder creates a new encoder for encoding the AWS RESTXML protocol. +// The request passed in will be the base the path, query, and headers encoded +// will be set on top of. +func NewEncoder(req *http.Request) *Encoder { + e := &Encoder{ + method: req.Method, + reqEncoder: rest.NewEncoder(req), + bodyEncoder: xml.NewEncoder(), + } + + return e +} + +// Encode returns the encoded request, and body payload. If no payload body was +// set nil will be returned. If an error occurred while encoding the API an +// error will be returned. +func (e *Encoder) Encode() (*http.Request, io.ReadSeeker, error) { + req, payloadBody, err := e.reqEncoder.Encode() + if err != nil { + return nil, nil, err + } + + xmlBody, err := e.bodyEncoder.Encode() + if err != nil { + return nil, nil, err + } + + havePayload := payloadBody != nil + haveXML := xmlBody != nil + + if havePayload == haveXML && haveXML { + return nil, nil, fmt.Errorf("unexpected XML body and request payload for AWSMarshaler") + } + + body := payloadBody + if body == nil { + body = xmlBody + } + + return req, body, err +} + +// List will return a new list encoder based on the Target. +func (e *Encoder) List(t protocol.Target, k string, meta protocol.Metadata) protocol.ListEncoder { + if e.err != nil { + return nil + } + + switch t { + case protocol.HeaderTarget: + fallthrough + case protocol.QueryTarget: + return e.reqEncoder.List(t, k, meta) + case protocol.BodyTarget: + return e.bodyEncoder.List(t, k, meta) + default: + e.err = fmt.Errorf("unknown SetList restxml encode target, %s, %s", t, k) + return nil + } +} + +// Map will return a new map encoder based on the Target. +func (e *Encoder) Map(t protocol.Target, k string, meta protocol.Metadata) protocol.MapEncoder { + if e.err != nil { + return nil + } + + switch t { + case protocol.HeadersTarget: + fallthrough + case protocol.QueryTarget: + return e.reqEncoder.Map(t, k, meta) + case protocol.BodyTarget: + return e.bodyEncoder.Map(t, k, meta) + default: + e.err = fmt.Errorf("unknown SetMap restxml encode target, %s, %s", t, k) + return nil + } +} + +// SetValue will set a value to the header, path, query, or body. +// +// If the request's method is GET all BodyTarget values will be written to +// the query string. +func (e *Encoder) SetValue(t protocol.Target, k string, v protocol.ValueMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PathTarget: + fallthrough + case protocol.QueryTarget: + fallthrough + case protocol.HeaderTarget: + e.reqEncoder.SetValue(t, k, v, meta) + case protocol.BodyTarget: + if e.method == "GET" { + e.reqEncoder.SetValue(t, k, v, meta) + } else { + e.bodyEncoder.SetValue(t, k, v, meta) + } + default: + e.err = fmt.Errorf("unknown SetValue restxml encode target, %s, %s", t, k) + } +} + +// SetStream will set the stream to the payload of the request. +func (e *Encoder) SetStream(t protocol.Target, k string, v protocol.StreamMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PayloadTarget: + e.reqEncoder.SetStream(t, k, v, meta) + default: + e.err = fmt.Errorf("invalid target %s, for SetStream, must be PayloadTarget", t) + } +} + +// SetFields will set the nested type's fields to the body. +func (e *Encoder) SetFields(t protocol.Target, k string, m protocol.FieldMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + + switch t { + case protocol.PayloadTarget: + fallthrough + case protocol.BodyTarget: + e.bodyEncoder.SetFields(t, k, m, meta) + default: + e.err = fmt.Errorf("unknown SetMarshaler restxml encode target, %s, %s", t, k) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/restxml.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/restxml.go new file mode 100644 index 000000000..65faeae30 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/restxml/restxml.go @@ -0,0 +1,90 @@ +// Package restxml provides RESTful XML serialization of AWS +// requests and responses. +package restxml + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go + +import ( + "bytes" + "encoding/xml" + "io" + + request "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/awserr" + "github.com/aws/aws-sdk-go-v2/private/protocol" + "github.com/aws/aws-sdk-go-v2/private/protocol/query" + "github.com/aws/aws-sdk-go-v2/private/protocol/rest" + "github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil" +) + +// BuildHandler is a named request handler for building restxml protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.restxml.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling restxml protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.restxml.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling restxml protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.restxml.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling restxml protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.restxml.UnmarshalError", Fn: UnmarshalError} + +// Build builds a request payload for the REST XML protocol. +func Build(r *request.Request) { + if m, ok := r.Params.(protocol.FieldMarshaler); ok { + e := NewEncoder(r.HTTPRequest) + + m.MarshalFields(e) + + var body io.ReadSeeker + var err error + r.HTTPRequest, body, err = e.Encode() + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to encode rest XML request", err) + return + } + if body != nil { + r.SetReaderBody(body) + } + return + } + + // Fall back to old reflection based marshaler + rest.Build(r) + + if t := rest.PayloadType(r.Params); t == "structure" || t == "" { + var buf bytes.Buffer + err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf)) + if err != nil { + r.Error = awserr.New("SerializationError", "failed to encode rest XML request", err) + return + } + r.SetBufferBody(buf.Bytes()) + } +} + +// Unmarshal unmarshals a payload response for the REST XML protocol. +func Unmarshal(r *request.Request) { + if t := rest.PayloadType(r.Data); t == "structure" || t == "" { + defer r.HTTPResponse.Body.Close() + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, "") + if err != nil { + r.Error = awserr.New("SerializationError", "failed to decode REST XML response", err) + return + } + } else { + rest.Unmarshal(r) + } +} + +// UnmarshalMeta unmarshals response headers for the REST XML protocol. +func UnmarshalMeta(r *request.Request) { + rest.UnmarshalMeta(r) +} + +// UnmarshalError unmarshals a response error for the REST XML protocol. +func UnmarshalError(r *request.Request) { + query.UnmarshalError(r) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/target.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/target.go new file mode 100644 index 000000000..36e65d32a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/target.go @@ -0,0 +1,38 @@ +package protocol + +import "fmt" + +// Target is the encode and decode targets of protocol marshaling. +type Target int + +// The protocol marshaling targets. +const ( + PathTarget Target = iota + QueryTarget + HeaderTarget + HeadersTarget + StatusCodeTarget + BodyTarget + PayloadTarget +) + +func (e Target) String() string { + switch e { + case PathTarget: + return "Path" + case QueryTarget: + return "Query" + case HeaderTarget: + return "Header" + case HeadersTarget: + return "Headers" + case StatusCodeTarget: + return "StatusCode" + case BodyTarget: + return "Body" + case PayloadTarget: + return "Payload" + default: + panic(fmt.Sprintf("// unknown encoding target, %d", e)) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/unmarshal.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/unmarshal.go new file mode 100644 index 000000000..de0483489 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/unmarshal.go @@ -0,0 +1,21 @@ +package protocol + +import ( + "io" + "io/ioutil" + + request "github.com/aws/aws-sdk-go-v2/aws" +) + +// UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body +var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} + +// UnmarshalDiscardBody is a request handler to empty a response's body and closing it. +func UnmarshalDiscardBody(r *request.Request) { + if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { + return + } + + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + r.HTTPResponse.Body.Close() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/value.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/value.go new file mode 100644 index 000000000..892b286e5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/value.go @@ -0,0 +1,30 @@ +package protocol + +import ( + "reflect" +) + +// ErrValueNotSet is an error that is returned when the value +// has not been set. +type ErrValueNotSet struct{} + +func (err *ErrValueNotSet) Error() string { + return "value not set" +} + +// IsNotSetError will return true if the error is of ErrValueNotSet +func IsNotSetError(err error) bool { + _, ok := err.(*ErrValueNotSet) + return ok +} + +// GetValue will return the value that is associated with the reflect.Value. +// If that value is not set, this will return an ErrValueNotSet +func GetValue(r reflect.Value) (string, error) { + val := r.String() + if len(val) == 0 { + return "", &ErrValueNotSet{} + } + + return val, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/encode.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/encode.go new file mode 100644 index 000000000..7d8ea051d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/encode.go @@ -0,0 +1,415 @@ +package xml + +import ( + "bytes" + "encoding/xml" + "fmt" + "io" + + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// An Encoder provides encoding of the AWS XML protocol. This encoder will will +// write all content to XML. Only supports body and payload targets. +type Encoder struct { + encoder *xml.Encoder + encodedBuf *bytes.Buffer + fieldBuf protocol.FieldBuffer + err error +} + +// NewEncoder creates a new encoder for encoding AWS XML protocol. Only encodes +// fields into the XML body, and error is returned if target is anything other +// than Body or Payload. +func NewEncoder() *Encoder { + encodedBuf := bytes.NewBuffer(nil) + return &Encoder{ + encodedBuf: encodedBuf, + encoder: xml.NewEncoder(encodedBuf), + } +} + +// Encode returns the encoded XMl reader. An error will be returned if one was +// encountered while building the XML body. +func (e *Encoder) Encode() (io.ReadSeeker, error) { + if e.err != nil { + return nil, e.err + } + + if err := e.encoder.Flush(); err != nil { + return nil, fmt.Errorf("unable to marshal XML, %v", err) + } + + if e.encodedBuf.Len() == 0 { + return nil, nil + } + + return bytes.NewReader(e.encodedBuf.Bytes()), e.err +} + +// SetValue sets an individual value to the XML body. +func (e *Encoder) SetValue(t protocol.Target, k string, v protocol.ValueMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + if t != protocol.BodyTarget && t != protocol.PayloadTarget { + e.err = fmt.Errorf(" invalid target %s for xml encoder SetValue, %s", t, k) + return + } + + e.err = addValueToken(e.encoder, &e.fieldBuf, k, v, meta) +} + +// SetStream is not supported for XML protocol marshaling. +func (e *Encoder) SetStream(t protocol.Target, k string, v protocol.StreamMarshaler, meta protocol.Metadata) { + e.err = fmt.Errorf("xml encoder SetStream not supported, %s, %s", t, k) +} + +// List creates an XML list and calls the passed in fn callback with a list encoder. +func (e *Encoder) List(t protocol.Target, k string, meta protocol.Metadata) protocol.ListEncoder { + if e.err != nil { + return nil + } + if t != protocol.BodyTarget && t != protocol.PayloadTarget { + e.err = fmt.Errorf(" invalid target %s for xml encoder SetValue, %s", t, k) + return nil + } + + if v := meta.ListLocationName; len(v) == 0 { + if meta.Flatten { + meta.ListLocationName = k + } else { + meta.ListLocationName = "member" + } + } + + return &ListEncoder{ + Base: e, + Key: k, + Metadata: meta, + } +} + +// Map creates an XML map and calls the passed in fn callback with a map encoder. +func (e *Encoder) Map(t protocol.Target, k string, meta protocol.Metadata) protocol.MapEncoder { + if e.err != nil { + return nil + } + if t != protocol.BodyTarget && t != protocol.PayloadTarget { + e.err = fmt.Errorf(" invalid target %s for xml encoder SetValue, %s", t, k) + return nil + } + + me := MapEncoder{Base: e, + // TODO: Get rid of these fields as we need the metadata structure now + Flatten: meta.Flatten, + KeyName: meta.MapLocationNameKey, + ValueName: meta.MapLocationNameValue, + Metadata: meta, + Key: k, + } + + return &me + +} + +// SetFields sets the nested fields to the XML body. +func (e *Encoder) SetFields(t protocol.Target, k string, m protocol.FieldMarshaler, meta protocol.Metadata) { + if e.err != nil { + return + } + if t != protocol.BodyTarget && t != protocol.PayloadTarget { + e.err = fmt.Errorf(" invalid target %s for xml encoder SetFields, %s", t, k) + return + } + + tok, err := xmlStartElem(k, meta) + if err != nil { + e.err = err + return + } + + e.encoder.EncodeToken(tok) + m.MarshalFields(e) + e.encoder.EncodeToken(xml.EndElement{Name: tok.Name}) +} + +// A ListEncoder encodes elements within a list for the XML encoder. +type ListEncoder struct { + Base *Encoder + Key string + Metadata protocol.Metadata + Token xml.StartElement + err error +} + +// Map will return an error since nested collections are not support by this protocol. +func (e *ListEncoder) Map() protocol.MapEncoder { + e.err = fmt.Errorf("xml list encoder ListSetMap not supported") + return nil +} + +// List will return an error since nested collections are not support by this protocol. +func (e *ListEncoder) List() protocol.ListEncoder { + e.err = fmt.Errorf("xml list encoder ListSetList not supported") + return nil +} + +// Start will write the start element and set the token for closing +func (e *ListEncoder) Start() { + var tok xml.StartElement + var err error + if !e.Metadata.Flatten { + tok, err = xmlStartElem(e.Key, e.Metadata) + if err != nil { + e.err = err + return + } + + e.Base.encoder.EncodeToken(tok) + } + + e.Token = tok +} + +// End will write the end element if the list is not flat. +func (e *ListEncoder) End() { + if !e.Metadata.Flatten { + e.err = e.Base.encoder.EncodeToken(xml.EndElement{Name: e.Token.Name}) + } +} + +// ListAddValue will add the value to the list. +func (e *ListEncoder) ListAddValue(v protocol.ValueMarshaler) { + if e.err != nil { + return + } + + e.err = addValueToken(e.Base.encoder, &e.Base.fieldBuf, e.Metadata.ListLocationName, v, protocol.Metadata{}) +} + +// ListAddFields will set the nested type's fields to the list. +func (e *ListEncoder) ListAddFields(m protocol.FieldMarshaler) { + if e.err != nil { + return + } + + var tok xml.StartElement + tok, e.err = xmlStartElem(e.Metadata.ListLocationName, protocol.Metadata{}) + if e.err != nil { + return + } + + e.Base.encoder.EncodeToken(tok) + m.MarshalFields(e.Base) + e.Base.encoder.EncodeToken(xml.EndElement{Name: tok.Name}) +} + +// A MapEncoder encodes key values pair map values for the XML encoder. +type MapEncoder struct { + Base *Encoder + Flatten bool + Key string + KeyName string + ValueName string + err error + + Token xml.StartElement + Metadata protocol.Metadata +} + +// Start will open a new scope by creating a new XML start element tag. +func (e *MapEncoder) Start() { + tok, err := xmlStartElem(e.Key, e.Metadata) + if err != nil { + e.err = err + return + } + + e.Token = tok + e.Base.encoder.EncodeToken(tok) +} + +// End will close the associated tag. +func (e *MapEncoder) End() { + e.Base.encoder.EncodeToken(xml.EndElement{Name: e.Token.Name}) +} + +// Map will set err as nested collections are not supported in this protocol. +func (e *MapEncoder) Map(k string) protocol.MapEncoder { + e.err = fmt.Errorf("xml map encoder MapSetList not supported, %s", k) + return nil +} + +// List will set err as nested collections are not supported in this protocol. +func (e *MapEncoder) List(k string) protocol.ListEncoder { + e.err = fmt.Errorf("xml map encoder ListSetList not supported, %s", k) + return nil +} + +// MapSetValue sets a map value. +func (e *MapEncoder) MapSetValue(k string, v protocol.ValueMarshaler) { + if e.err != nil { + return + } + + var tok xml.StartElement + if !e.Flatten { + tok, e.err = xmlStartElem("entry", protocol.Metadata{}) + if e.err != nil { + return + } + e.Base.encoder.EncodeToken(tok) + } + + keyName, valueName := e.KeyName, e.ValueName + if len(keyName) == 0 { + keyName = "key" + } + if len(valueName) == 0 { + valueName = "value" + } + + e.err = addValueToken(e.Base.encoder, &e.Base.fieldBuf, keyName, protocol.StringValue(k), protocol.Metadata{}) + if e.err != nil { + return + } + + e.err = addValueToken(e.Base.encoder, &e.Base.fieldBuf, valueName, v, protocol.Metadata{}) + if e.err != nil { + return + } + + if !e.Flatten { + e.Base.encoder.EncodeToken(xml.EndElement{Name: tok.Name}) + } +} + +// MapSetList is not supported. +func (e *MapEncoder) MapSetList(k string, fn func(le protocol.ListEncoder)) { + e.err = fmt.Errorf("xml map encoder MapSetList not supported, %s", k) +} + +// MapSetMap is not supported. +func (e *MapEncoder) MapSetMap(k string, fn func(me protocol.MapEncoder)) { + e.err = fmt.Errorf("xml map encoder MapSetMap not supported, %s", k) +} + +// MapSetFields will set the nested type's fields under the map. +func (e *MapEncoder) MapSetFields(k string, m protocol.FieldMarshaler) { + if e.err != nil { + return + } + + var tok xml.StartElement + if !e.Flatten { + tok, e.err = xmlStartElem("entry", protocol.Metadata{}) + if e.err != nil { + return + } + e.Base.encoder.EncodeToken(tok) + } + + keyName, valueName := e.KeyName, e.ValueName + if len(keyName) == 0 { + keyName = "key" + } + if len(valueName) == 0 { + valueName = "value" + } + + e.err = addValueToken(e.Base.encoder, &e.Base.fieldBuf, keyName, protocol.StringValue(k), protocol.Metadata{}) + if e.err != nil { + return + } + + valTok, err := xmlStartElem(valueName, protocol.Metadata{}) + if err != nil { + e.err = err + return + } + e.Base.encoder.EncodeToken(valTok) + + m.MarshalFields(e.Base) + + e.Base.encoder.EncodeToken(xml.EndElement{Name: valTok.Name}) + + if !e.Flatten { + e.Base.encoder.EncodeToken(xml.EndElement{Name: tok.Name}) + } +} + +func addValueToken(e *xml.Encoder, fieldBuf *protocol.FieldBuffer, k string, v protocol.ValueMarshaler, meta protocol.Metadata) error { + b, err := fieldBuf.GetValue(v) + if err != nil { + return err + } + + tok, err := xmlStartElem(k, meta) + if err != nil { + return err + } + + e.EncodeToken(tok) + e.EncodeToken(xml.CharData(b)) + e.EncodeToken(xml.EndElement{Name: tok.Name}) + + return nil +} + +func xmlStartElem(k string, meta protocol.Metadata) (xml.StartElement, error) { + tok := xml.StartElement{Name: xmlName(k, meta)} + attrs, err := buildAttributes(meta) + if err != nil { + return xml.StartElement{}, err + } + tok.Attr = attrs + + return tok, nil +} + +func xmlName(k string, meta protocol.Metadata) xml.Name { + name := xml.Name{Local: k} + + // TODO need to do something with namespace? + // if len(meta.XMLNamespacePrefix) > 0 && len(meta.XMLNamespaceURI) { + // name.Space = prefix + // } + + return name +} + +func buildAttributes(meta protocol.Metadata) ([]xml.Attr, error) { + n := len(meta.Attributes) + if len(meta.XMLNamespaceURI) > 0 { + n++ + } + + if n == 0 { + return nil, nil + } + + attrs := make([]xml.Attr, n) + + for _, a := range meta.Attributes { + str, err := a.Value.MarshalValue() + if err != nil { + return nil, err + } + + attrs = append(attrs, xml.Attr{Name: xmlName(a.Name, a.Meta), Value: str}) + } + + if uri := meta.XMLNamespaceURI; len(uri) > 0 { + attr := xml.Attr{ + Name: xml.Name{Local: "xmlns"}, + Value: uri, + } + if p := meta.XMLNamespacePrefix; len(p) > 0 { + attr.Name.Local += ":" + p + } + attrs = append(attrs, attr) + } + + return attrs, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/build.go new file mode 100644 index 000000000..ab4f1e4e8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/build.go @@ -0,0 +1,302 @@ +// Package xmlutil provides XML serialization of AWS requests and responses. +package xmlutil + +import ( + "encoding/base64" + "encoding/xml" + "fmt" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go-v2/private/protocol" +) + +// BuildXML will serialize params into an xml.Encoder. +// Error will be returned if the serialization of any of the params or nested values fails. +func BuildXML(params interface{}, e *xml.Encoder) error { + b := xmlBuilder{encoder: e, namespaces: map[string]string{}} + root := NewXMLElement(xml.Name{}) + if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil { + return err + } + for _, c := range root.Children { + for _, v := range c { + return StructToXML(e, v, false) + } + } + return nil +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +// A xmlBuilder serializes values from Go code to XML +type xmlBuilder struct { + encoder *xml.Encoder + namespaces map[string]string +} + +// buildValue generic XMLNode builder for any type. Will build value for their specific type +// struct, list, map, scalar. +// +// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If +// type is not provided reflect will be used to determine the value's type. +func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + value = elemOf(value) + if !value.IsValid() { // no need to handle zero values + return nil + } else if tag.Get("location") != "" { // don't handle non-body location values + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := value.Type().FieldByName("_"); ok { + tag = tag + reflect.StructTag(" ") + field.Tag + } + return b.buildStruct(value, current, tag) + case "list": + return b.buildList(value, current, tag) + case "map": + return b.buildMap(value, current, tag) + default: + return b.buildScalar(value, current, tag) + } +} + +// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested +// types are converted to XMLNodes also. +func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + fieldAdded := false + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + child := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + + // there is an xmlNamespace associated with this struct + if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" { + ns := xml.Attr{ + Name: xml.Name{Local: "xmlns"}, + Value: uri, + } + if prefix != "" { + b.namespaces[prefix] = uri // register the namespace + ns.Name.Local = "xmlns:" + prefix + } + + child.Attr = append(child.Attr, ns) + } + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + member := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("ignore") != "" { + continue + } + + mTag := field.Tag + if mTag.Get("location") != "" { // skip non-body members + continue + } + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(token) + } + + memberName := mTag.Get("locationName") + if memberName == "" { + memberName = field.Name + mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`) + } + if err := b.buildValue(member, child, mTag); err != nil { + return err + } + + fieldAdded = true + } + + if fieldAdded { // only append this child if we have one ore more valid members + current.AddChild(child) + } + + return nil +} + +// buildList adds the value's list items to the current XMLNode as children nodes. All +// nested values in the list are converted to XMLNodes also. +func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted lists + return nil + } + + // check for unflattened list member + flattened := tag.Get("flattened") != "" + + xname := xml.Name{Local: tag.Get("locationName")} + if flattened { + for i := 0; i < value.Len(); i++ { + child := NewXMLElement(xname) + current.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } else { + list := NewXMLElement(xname) + current.AddChild(list) + + for i := 0; i < value.Len(); i++ { + iname := tag.Get("locationNameList") + if iname == "" { + iname = "member" + } + + child := NewXMLElement(xml.Name{Local: iname}) + list.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } + + return nil +} + +// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All +// nested values in the map are converted to XMLNodes also. +// +// Error will be returned if it is unable to build the map's values into XMLNodes +func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted maps + return nil + } + + maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + current.AddChild(maproot) + current = maproot + + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + // sorting is not required for compliance, but it makes testing easier + keys := make([]string, value.Len()) + for i, k := range value.MapKeys() { + keys[i] = k.String() + } + sort.Strings(keys) + + for _, k := range keys { + v := value.MapIndex(reflect.ValueOf(k)) + + mapcur := current + if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps + child := NewXMLElement(xml.Name{Local: "entry"}) + mapcur.AddChild(child) + mapcur = child + } + + kchild := NewXMLElement(xml.Name{Local: kname}) + kchild.Text = k + vchild := NewXMLElement(xml.Name{Local: vname}) + mapcur.AddChild(kchild) + mapcur.AddChild(vchild) + + if err := b.buildValue(v, vchild, ""); err != nil { + return err + } + } + + return nil +} + +// buildScalar will convert the value into a string and append it as a attribute or child +// of the current XMLNode. +// +// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value. +// +// Error will be returned if the value type is unsupported. +func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + var str string + switch converted := value.Interface().(type) { + case string: + str = converted + case []byte: + if !value.IsNil() { + str = base64.StdEncoding.EncodeToString(converted) + } + case bool: + str = strconv.FormatBool(converted) + case int64: + str = strconv.FormatInt(converted, 10) + case int: + str = strconv.Itoa(converted) + case float64: + str = strconv.FormatFloat(converted, 'f', -1, 64) + case float32: + str = strconv.FormatFloat(float64(converted), 'f', -1, 32) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + str = converted.UTC().Format(ISO8601UTC) + default: + if value.Kind() != reflect.String { + return fmt.Errorf("unsupported value for param %s: %v (%s)", + tag.Get("locationName"), value.Interface(), value.Type().Name()) + } + str = value.Convert(reflect.TypeOf("")).String() + } + + if len(str) == 0 { + return nil + } + xname := xml.Name{Local: tag.Get("locationName")} + if tag.Get("xmlAttribute") != "" { // put into current node's attribute list + attr := xml.Attr{Name: xname, Value: str} + current.Attr = append(current.Attr, attr) + } else { // regular text node + current.AddChild(&XMLNode{Name: xname, Text: str}) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/unmarshal.go new file mode 100644 index 000000000..2b95c35e6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/unmarshal.go @@ -0,0 +1,278 @@ +package xmlutil + +import ( + "encoding/base64" + "encoding/xml" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "time" +) + +// UnmarshalXML deserializes an xml.Decoder into the container v. V +// needs to match the shape of the XML expected to be decoded. +// If the shape doesn't match unmarshaling will fail. +func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { + n, err := XMLToStruct(d, nil) + if err != nil { + return err + } + if n.Children != nil { + for _, root := range n.Children { + for _, c := range root { + if wrappedChild, ok := c.Children[wrapper]; ok { + c = wrappedChild[0] // pull out wrapped element + } + + err = parse(reflect.ValueOf(v), c, "") + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } + } + return nil + } + return nil +} + +// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect +// will be used to determine the type from r. +func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + rtype := r.Type() + if rtype.Kind() == reflect.Ptr { + rtype = rtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch rtype.Kind() { + case reflect.Struct: + // also it can't be a time object + _, tok := r.Interface().(*time.Time) + if _, ok := r.Interface().(time.Time); !(ok || tok) { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := r.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := rtype.FieldByName("_"); ok { + tag = field.Tag + } + return parseStruct(r, node, tag) + case "list": + return parseList(r, node, tag) + case "map": + return parseMap(r, node, tag) + default: + return parseScalar(r, node, tag) + } +} + +// parseStruct deserializes a structure and its fields from an XMLNode. Any nested +// types in the structure will also be deserialized. +func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + if r.Kind() == reflect.Ptr { + if r.IsNil() { // create the structure if it's nil + s := reflect.New(r.Type().Elem()) + r.Set(s) + r = s + } + + r = r.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return parseStruct(r.FieldByName(payload), node, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if c := field.Name[0:1]; strings.ToLower(c) == c { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + // try to find the field by name in elements + elems := node.Children[name] + + if elems == nil { // try to find the field in attributes + if val, ok := node.findElem(name); ok { + elems = []*XMLNode{{Text: val}} + } + } + + member := r.FieldByName(field.Name) + for _, elem := range elems { + err := parse(member, elem, field.Tag) + if err != nil { + return err + } + } + } + return nil +} + +// parseList deserializes a list of values from an XML node. Each list entry +// will also be deserialized. +func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + + if tag.Get("flattened") == "" { // look at all item entries + mname := "member" + if name := tag.Get("locationNameList"); name != "" { + mname = name + } + + if Children, ok := node.Children[mname]; ok { + if r.IsNil() { + r.Set(reflect.MakeSlice(t, len(Children), len(Children))) + } + + for i, c := range Children { + err := parse(r.Index(i), c, "") + if err != nil { + return err + } + } + } + } else { // flattened list means this is a single element + if r.IsNil() { + r.Set(reflect.MakeSlice(t, 0, 0)) + } + + childR := reflect.Zero(t.Elem()) + r.Set(reflect.Append(r, childR)) + err := parse(r.Index(r.Len()-1), node, "") + if err != nil { + return err + } + } + + return nil +} + +// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode +// will also be deserialized as map entries. +func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + if r.IsNil() { + r.Set(reflect.MakeMap(r.Type())) + } + + if tag.Get("flattened") == "" { // look at all child entries + for _, entry := range node.Children["entry"] { + parseMapEntry(r, entry, tag) + } + } else { // this element is itself an entry + parseMapEntry(r, node, tag) + } + + return nil +} + +// parseMapEntry deserializes a map entry from a XML node. +func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + keys, ok := node.Children[kname] + values := node.Children[vname] + if ok { + for i, key := range keys { + keyR := reflect.ValueOf(key.Text) + value := values[i] + valueR := reflect.New(r.Type().Elem()).Elem() + + parse(valueR, value, "") + r.SetMapIndex(keyR, valueR) + } + } + return nil +} + +// parseScaller deserializes an XMLNode value into a concrete type based on the +// interface type of r. +// +// Error is returned if the deserialization fails due to invalid type conversion, +// or unsupported interface type. +func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + if r.Kind() == reflect.String { + r.SetString(node.Text) + return nil + } + + if r.Kind() == reflect.Ptr { + if r.IsNil() { + r.Set(reflect.New(r.Type().Elem())) + } + r = r.Elem() + } + + switch r.Interface().(type) { + case string: + r.Set(reflect.ValueOf(node.Text)) + case []byte: + b, err := base64.StdEncoding.DecodeString(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(b)) + case bool: + v, err := strconv.ParseBool(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(v)) + case int64: + v, err := strconv.ParseInt(node.Text, 10, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(v)) + case float64: + v, err := strconv.ParseFloat(node.Text, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(v)) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + t, err := time.Parse(ISO8601UTC, node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/xml_to_struct.go new file mode 100644 index 000000000..3e970b629 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil/xml_to_struct.go @@ -0,0 +1,147 @@ +package xmlutil + +import ( + "encoding/xml" + "fmt" + "io" + "sort" +) + +// A XMLNode contains the values to be encoded or decoded. +type XMLNode struct { + Name xml.Name `json:",omitempty"` + Children map[string][]*XMLNode `json:",omitempty"` + Text string `json:",omitempty"` + Attr []xml.Attr `json:",omitempty"` + + namespaces map[string]string + parent *XMLNode +} + +// NewXMLElement returns a pointer to a new XMLNode initialized to default values. +func NewXMLElement(name xml.Name) *XMLNode { + return &XMLNode{ + Name: name, + Children: map[string][]*XMLNode{}, + Attr: []xml.Attr{}, + } +} + +// AddChild adds child to the XMLNode. +func (n *XMLNode) AddChild(child *XMLNode) { + if _, ok := n.Children[child.Name.Local]; !ok { + n.Children[child.Name.Local] = []*XMLNode{} + } + n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child) +} + +// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values. +func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) { + out := &XMLNode{} + for { + tok, err := d.Token() + if err != nil { + if err == io.EOF { + break + } else { + return out, err + } + } + + if tok == nil { + break + } + + switch typed := tok.(type) { + case xml.CharData: + out.Text = string(typed.Copy()) + case xml.StartElement: + el := typed.Copy() + out.Attr = el.Attr + if out.Children == nil { + out.Children = map[string][]*XMLNode{} + } + + name := typed.Name.Local + slice := out.Children[name] + if slice == nil { + slice = []*XMLNode{} + } + node, e := XMLToStruct(d, &el) + out.findNamespaces() + if e != nil { + return out, e + } + node.Name = typed.Name + node.findNamespaces() + tempOut := *out + // Save into a temp variable, simply because out gets squashed during + // loop iterations + node.parent = &tempOut + slice = append(slice, node) + out.Children[name] = slice + case xml.EndElement: + if s != nil && s.Name.Local == typed.Name.Local { // matching end token + return out, nil + } + out = &XMLNode{} + } + } + return out, nil +} + +func (n *XMLNode) findNamespaces() { + ns := map[string]string{} + for _, a := range n.Attr { + if a.Name.Space == "xmlns" { + ns[a.Value] = a.Name.Local + } + } + + n.namespaces = ns +} + +func (n *XMLNode) findElem(name string) (string, bool) { + for node := n; node != nil; node = node.parent { + for _, a := range node.Attr { + namespace := a.Name.Space + if v, ok := node.namespaces[namespace]; ok { + namespace = v + } + if name == fmt.Sprintf("%s:%s", namespace, a.Name.Local) { + return a.Value, true + } + } + } + return "", false +} + +// StructToXML writes an XMLNode to a xml.Encoder as tokens. +func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error { + e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr}) + + if node.Text != "" { + e.EncodeToken(xml.CharData([]byte(node.Text))) + } else if sorted { + sortedNames := []string{} + for k := range node.Children { + sortedNames = append(sortedNames, k) + } + sort.Strings(sortedNames) + + for _, k := range sortedNames { + for _, v := range node.Children[k] { + StructToXML(e, v, sorted) + } + } + } else { + for _, c := range node.Children { + for _, v := range c { + StructToXML(e, v, sorted) + } + } + } + + e.EncodeToken(xml.EndElement{Name: node.Name}) + return e.Flush() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/github.com/aws/aws-sdk-go-v2/service/cloudwatch/api.go b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/api.go new file mode 100644 index 000000000..156b31f19 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/api.go @@ -0,0 +1,3517 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package cloudwatch + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/internal/awsutil" + "github.com/aws/aws-sdk-go-v2/private/protocol" + "github.com/aws/aws-sdk-go-v2/private/protocol/query" +) + +const opDeleteAlarms = "DeleteAlarms" + +// DeleteAlarmsRequest is a API request type for the DeleteAlarms API operation. +type DeleteAlarmsRequest struct { + *aws.Request + Input *DeleteAlarmsInput + Copy func(*DeleteAlarmsInput) DeleteAlarmsRequest +} + +// Send marshals and sends the DeleteAlarms API request. +func (r DeleteAlarmsRequest) Send() (*DeleteAlarmsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DeleteAlarmsOutput), nil +} + +// DeleteAlarmsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Deletes the specified alarms. In the event of an error, no alarms are deleted. +// +// // Example sending a request using the DeleteAlarmsRequest method. +// req := client.DeleteAlarmsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteAlarms +func (c *CloudWatch) DeleteAlarmsRequest(input *DeleteAlarmsInput) DeleteAlarmsRequest { + op := &aws.Operation{ + Name: opDeleteAlarms, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteAlarmsInput{} + } + + output := &DeleteAlarmsOutput{} + req := c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output.responseMetadata = aws.Response{Request: req} + + return DeleteAlarmsRequest{Request: req, Input: input, Copy: c.DeleteAlarmsRequest} +} + +const opDeleteDashboards = "DeleteDashboards" + +// DeleteDashboardsRequest is a API request type for the DeleteDashboards API operation. +type DeleteDashboardsRequest struct { + *aws.Request + Input *DeleteDashboardsInput + Copy func(*DeleteDashboardsInput) DeleteDashboardsRequest +} + +// Send marshals and sends the DeleteDashboards API request. +func (r DeleteDashboardsRequest) Send() (*DeleteDashboardsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DeleteDashboardsOutput), nil +} + +// DeleteDashboardsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Deletes all dashboards that you specify. You may specify up to 100 dashboards +// to delete. If there is an error during this call, no dashboards are deleted. +// +// // Example sending a request using the DeleteDashboardsRequest method. +// req := client.DeleteDashboardsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboards +func (c *CloudWatch) DeleteDashboardsRequest(input *DeleteDashboardsInput) DeleteDashboardsRequest { + op := &aws.Operation{ + Name: opDeleteDashboards, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDashboardsInput{} + } + + output := &DeleteDashboardsOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return DeleteDashboardsRequest{Request: req, Input: input, Copy: c.DeleteDashboardsRequest} +} + +const opDescribeAlarmHistory = "DescribeAlarmHistory" + +// DescribeAlarmHistoryRequest is a API request type for the DescribeAlarmHistory API operation. +type DescribeAlarmHistoryRequest struct { + *aws.Request + Input *DescribeAlarmHistoryInput + Copy func(*DescribeAlarmHistoryInput) DescribeAlarmHistoryRequest +} + +// Send marshals and sends the DescribeAlarmHistory API request. +func (r DescribeAlarmHistoryRequest) Send() (*DescribeAlarmHistoryOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DescribeAlarmHistoryOutput), nil +} + +// DescribeAlarmHistoryRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Retrieves the history for the specified alarm. You can filter the results +// by date range or item type. If an alarm name is not specified, the histories +// for all alarms are returned. +// +// CloudWatch retains the history of an alarm even if you delete the alarm. +// +// // Example sending a request using the DescribeAlarmHistoryRequest method. +// req := client.DescribeAlarmHistoryRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmHistory +func (c *CloudWatch) DescribeAlarmHistoryRequest(input *DescribeAlarmHistoryInput) DescribeAlarmHistoryRequest { + op := &aws.Operation{ + Name: opDescribeAlarmHistory, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &aws.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeAlarmHistoryInput{} + } + + output := &DescribeAlarmHistoryOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return DescribeAlarmHistoryRequest{Request: req, Input: input, Copy: c.DescribeAlarmHistoryRequest} +} + +// Paginate pages iterates over the pages of a DescribeAlarmHistoryRequest operation, +// calling the Next method for each page. Using the paginators Next +// method will depict whether or not there are more pages. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeAlarmHistory operation. +// req := client.DescribeAlarmHistoryRequest(input) +// p := req.Paginate() +// for p.Next() { +// page := p.CurrentPage() +// } +// +// if err := p.Err(); err != nil { +// return err +// } +// +func (p *DescribeAlarmHistoryRequest) Paginate(opts ...aws.Option) DescribeAlarmHistoryPager { + return DescribeAlarmHistoryPager{ + Pager: aws.Pager{ + NewRequest: func() (*aws.Request, error) { + var inCpy *DescribeAlarmHistoryInput + if p.Input != nil { + tmp := *p.Input + inCpy = &tmp + } + + req := p.Copy(inCpy) + req.ApplyOptions(opts...) + + return req.Request, nil + }, + }, + } +} + +// DescribeAlarmHistoryPager is used to paginate the request. This can be done by +// calling Next and CurrentPage. +type DescribeAlarmHistoryPager struct { + aws.Pager +} + +func (p *DescribeAlarmHistoryPager) CurrentPage() *DescribeAlarmHistoryOutput { + return p.Pager.CurrentPage().(*DescribeAlarmHistoryOutput) +} + +const opDescribeAlarms = "DescribeAlarms" + +// DescribeAlarmsRequest is a API request type for the DescribeAlarms API operation. +type DescribeAlarmsRequest struct { + *aws.Request + Input *DescribeAlarmsInput + Copy func(*DescribeAlarmsInput) DescribeAlarmsRequest +} + +// Send marshals and sends the DescribeAlarms API request. +func (r DescribeAlarmsRequest) Send() (*DescribeAlarmsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DescribeAlarmsOutput), nil +} + +// DescribeAlarmsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Retrieves the specified alarms. If no alarms are specified, all alarms are +// returned. Alarms can be retrieved by using only a prefix for the alarm name, +// the alarm state, or a prefix for any action. +// +// // Example sending a request using the DescribeAlarmsRequest method. +// req := client.DescribeAlarmsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarms +func (c *CloudWatch) DescribeAlarmsRequest(input *DescribeAlarmsInput) DescribeAlarmsRequest { + op := &aws.Operation{ + Name: opDescribeAlarms, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &aws.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeAlarmsInput{} + } + + output := &DescribeAlarmsOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return DescribeAlarmsRequest{Request: req, Input: input, Copy: c.DescribeAlarmsRequest} +} + +// Paginate pages iterates over the pages of a DescribeAlarmsRequest operation, +// calling the Next method for each page. Using the paginators Next +// method will depict whether or not there are more pages. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeAlarms operation. +// req := client.DescribeAlarmsRequest(input) +// p := req.Paginate() +// for p.Next() { +// page := p.CurrentPage() +// } +// +// if err := p.Err(); err != nil { +// return err +// } +// +func (p *DescribeAlarmsRequest) Paginate(opts ...aws.Option) DescribeAlarmsPager { + return DescribeAlarmsPager{ + Pager: aws.Pager{ + NewRequest: func() (*aws.Request, error) { + var inCpy *DescribeAlarmsInput + if p.Input != nil { + tmp := *p.Input + inCpy = &tmp + } + + req := p.Copy(inCpy) + req.ApplyOptions(opts...) + + return req.Request, nil + }, + }, + } +} + +// DescribeAlarmsPager is used to paginate the request. This can be done by +// calling Next and CurrentPage. +type DescribeAlarmsPager struct { + aws.Pager +} + +func (p *DescribeAlarmsPager) CurrentPage() *DescribeAlarmsOutput { + return p.Pager.CurrentPage().(*DescribeAlarmsOutput) +} + +const opDescribeAlarmsForMetric = "DescribeAlarmsForMetric" + +// DescribeAlarmsForMetricRequest is a API request type for the DescribeAlarmsForMetric API operation. +type DescribeAlarmsForMetricRequest struct { + *aws.Request + Input *DescribeAlarmsForMetricInput + Copy func(*DescribeAlarmsForMetricInput) DescribeAlarmsForMetricRequest +} + +// Send marshals and sends the DescribeAlarmsForMetric API request. +func (r DescribeAlarmsForMetricRequest) Send() (*DescribeAlarmsForMetricOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DescribeAlarmsForMetricOutput), nil +} + +// DescribeAlarmsForMetricRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Retrieves the alarms for the specified metric. To filter the results, specify +// a statistic, period, or unit. +// +// // Example sending a request using the DescribeAlarmsForMetricRequest method. +// req := client.DescribeAlarmsForMetricRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmsForMetric +func (c *CloudWatch) DescribeAlarmsForMetricRequest(input *DescribeAlarmsForMetricInput) DescribeAlarmsForMetricRequest { + op := &aws.Operation{ + Name: opDescribeAlarmsForMetric, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeAlarmsForMetricInput{} + } + + output := &DescribeAlarmsForMetricOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return DescribeAlarmsForMetricRequest{Request: req, Input: input, Copy: c.DescribeAlarmsForMetricRequest} +} + +const opDisableAlarmActions = "DisableAlarmActions" + +// DisableAlarmActionsRequest is a API request type for the DisableAlarmActions API operation. +type DisableAlarmActionsRequest struct { + *aws.Request + Input *DisableAlarmActionsInput + Copy func(*DisableAlarmActionsInput) DisableAlarmActionsRequest +} + +// Send marshals and sends the DisableAlarmActions API request. +func (r DisableAlarmActionsRequest) Send() (*DisableAlarmActionsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DisableAlarmActionsOutput), nil +} + +// DisableAlarmActionsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Disables the actions for the specified alarms. When an alarm's actions are +// disabled, the alarm actions do not execute when the alarm state changes. +// +// // Example sending a request using the DisableAlarmActionsRequest method. +// req := client.DisableAlarmActionsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DisableAlarmActions +func (c *CloudWatch) DisableAlarmActionsRequest(input *DisableAlarmActionsInput) DisableAlarmActionsRequest { + op := &aws.Operation{ + Name: opDisableAlarmActions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableAlarmActionsInput{} + } + + output := &DisableAlarmActionsOutput{} + req := c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output.responseMetadata = aws.Response{Request: req} + + return DisableAlarmActionsRequest{Request: req, Input: input, Copy: c.DisableAlarmActionsRequest} +} + +const opEnableAlarmActions = "EnableAlarmActions" + +// EnableAlarmActionsRequest is a API request type for the EnableAlarmActions API operation. +type EnableAlarmActionsRequest struct { + *aws.Request + Input *EnableAlarmActionsInput + Copy func(*EnableAlarmActionsInput) EnableAlarmActionsRequest +} + +// Send marshals and sends the EnableAlarmActions API request. +func (r EnableAlarmActionsRequest) Send() (*EnableAlarmActionsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*EnableAlarmActionsOutput), nil +} + +// EnableAlarmActionsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Enables the actions for the specified alarms. +// +// // Example sending a request using the EnableAlarmActionsRequest method. +// req := client.EnableAlarmActionsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/EnableAlarmActions +func (c *CloudWatch) EnableAlarmActionsRequest(input *EnableAlarmActionsInput) EnableAlarmActionsRequest { + op := &aws.Operation{ + Name: opEnableAlarmActions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &EnableAlarmActionsInput{} + } + + output := &EnableAlarmActionsOutput{} + req := c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output.responseMetadata = aws.Response{Request: req} + + return EnableAlarmActionsRequest{Request: req, Input: input, Copy: c.EnableAlarmActionsRequest} +} + +const opGetDashboard = "GetDashboard" + +// GetDashboardRequest is a API request type for the GetDashboard API operation. +type GetDashboardRequest struct { + *aws.Request + Input *GetDashboardInput + Copy func(*GetDashboardInput) GetDashboardRequest +} + +// Send marshals and sends the GetDashboard API request. +func (r GetDashboardRequest) Send() (*GetDashboardOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*GetDashboardOutput), nil +} + +// GetDashboardRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Displays the details of the dashboard that you specify. +// +// To copy an existing dashboard, use GetDashboard, and then use the data returned +// within DashboardBody as the template for the new dashboard when you call +// PutDashboard to create the copy. +// +// // Example sending a request using the GetDashboardRequest method. +// req := client.GetDashboardRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboard +func (c *CloudWatch) GetDashboardRequest(input *GetDashboardInput) GetDashboardRequest { + op := &aws.Operation{ + Name: opGetDashboard, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDashboardInput{} + } + + output := &GetDashboardOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return GetDashboardRequest{Request: req, Input: input, Copy: c.GetDashboardRequest} +} + +const opGetMetricData = "GetMetricData" + +// GetMetricDataRequest is a API request type for the GetMetricData API operation. +type GetMetricDataRequest struct { + *aws.Request + Input *GetMetricDataInput + Copy func(*GetMetricDataInput) GetMetricDataRequest +} + +// Send marshals and sends the GetMetricData API request. +func (r GetMetricDataRequest) Send() (*GetMetricDataOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*GetMetricDataOutput), nil +} + +// GetMetricDataRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// You can use the GetMetricData API to retrieve as many as 100 different metrics +// in a single request, with a total of as many as 100,800 datapoints. You can +// also optionally perform math expressions on the values of the returned statistics, +// to create new time series that represent new insights into your data. For +// example, using Lambda metrics, you could divide the Errors metric by the +// Invocations metric to get an error rate time series. For more information +// about metric math expressions, see Metric Math Syntax and Functions (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html#metric-math-syntax) +// in the Amazon CloudWatch User Guide. +// +// Calls to the GetMetricData API have a different pricing structure than calls +// to GetMetricStatistics. For more information about pricing, see Amazon CloudWatch +// Pricing (https://aws.amazon.com/cloudwatch/pricing/). +// +// // Example sending a request using the GetMetricDataRequest method. +// req := client.GetMetricDataRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricData +func (c *CloudWatch) GetMetricDataRequest(input *GetMetricDataInput) GetMetricDataRequest { + op := &aws.Operation{ + Name: opGetMetricData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetMetricDataInput{} + } + + output := &GetMetricDataOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return GetMetricDataRequest{Request: req, Input: input, Copy: c.GetMetricDataRequest} +} + +const opGetMetricStatistics = "GetMetricStatistics" + +// GetMetricStatisticsRequest is a API request type for the GetMetricStatistics API operation. +type GetMetricStatisticsRequest struct { + *aws.Request + Input *GetMetricStatisticsInput + Copy func(*GetMetricStatisticsInput) GetMetricStatisticsRequest +} + +// Send marshals and sends the GetMetricStatistics API request. +func (r GetMetricStatisticsRequest) Send() (*GetMetricStatisticsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*GetMetricStatisticsOutput), nil +} + +// GetMetricStatisticsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Gets statistics for the specified metric. +// +// The maximum number of data points returned from a single call is 1,440. If +// you request more than 1,440 data points, CloudWatch returns an error. To +// reduce the number of data points, you can narrow the specified time range +// and make multiple requests across adjacent time ranges, or you can increase +// the specified period. Data points are not returned in chronological order. +// +// CloudWatch aggregates data points based on the length of the period that +// you specify. For example, if you request statistics with a one-hour period, +// CloudWatch aggregates all data points with time stamps that fall within each +// one-hour period. Therefore, the number of values aggregated by CloudWatch +// is larger than the number of data points returned. +// +// CloudWatch needs raw data points to calculate percentile statistics. If you +// publish data using a statistic set instead, you can only retrieve percentile +// statistics for this data if one of the following conditions is true: +// +// * The SampleCount value of the statistic set is 1. +// +// * The Min and the Max values of the statistic set are equal. +// +// Amazon CloudWatch retains metric data as follows: +// +// * Data points with a period of less than 60 seconds are available for +// 3 hours. These data points are high-resolution metrics and are available +// only for custom metrics that have been defined with a StorageResolution +// of 1. +// +// * Data points with a period of 60 seconds (1-minute) are available for +// 15 days. +// +// * Data points with a period of 300 seconds (5-minute) are available for +// 63 days. +// +// * Data points with a period of 3600 seconds (1 hour) are available for +// 455 days (15 months). +// +// Data points that are initially published with a shorter period are aggregated +// together for long-term storage. For example, if you collect data using a +// period of 1 minute, the data remains available for 15 days with 1-minute +// resolution. After 15 days, this data is still available, but is aggregated +// and retrievable only with a resolution of 5 minutes. After 63 days, the data +// is further aggregated and is available with a resolution of 1 hour. +// +// CloudWatch started retaining 5-minute and 1-hour metric data as of July 9, +// 2016. +// +// For information about metrics and dimensions supported by AWS services, see +// the Amazon CloudWatch Metrics and Dimensions Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html) +// in the Amazon CloudWatch User Guide. +// +// // Example sending a request using the GetMetricStatisticsRequest method. +// req := client.GetMetricStatisticsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatistics +func (c *CloudWatch) GetMetricStatisticsRequest(input *GetMetricStatisticsInput) GetMetricStatisticsRequest { + op := &aws.Operation{ + Name: opGetMetricStatistics, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetMetricStatisticsInput{} + } + + output := &GetMetricStatisticsOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return GetMetricStatisticsRequest{Request: req, Input: input, Copy: c.GetMetricStatisticsRequest} +} + +const opListDashboards = "ListDashboards" + +// ListDashboardsRequest is a API request type for the ListDashboards API operation. +type ListDashboardsRequest struct { + *aws.Request + Input *ListDashboardsInput + Copy func(*ListDashboardsInput) ListDashboardsRequest +} + +// Send marshals and sends the ListDashboards API request. +func (r ListDashboardsRequest) Send() (*ListDashboardsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*ListDashboardsOutput), nil +} + +// ListDashboardsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Returns a list of the dashboards for your account. If you include DashboardNamePrefix, +// only those dashboards with names starting with the prefix are listed. Otherwise, +// all dashboards in your account are listed. +// +// // Example sending a request using the ListDashboardsRequest method. +// req := client.ListDashboardsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboards +func (c *CloudWatch) ListDashboardsRequest(input *ListDashboardsInput) ListDashboardsRequest { + op := &aws.Operation{ + Name: opListDashboards, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListDashboardsInput{} + } + + output := &ListDashboardsOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return ListDashboardsRequest{Request: req, Input: input, Copy: c.ListDashboardsRequest} +} + +const opListMetrics = "ListMetrics" + +// ListMetricsRequest is a API request type for the ListMetrics API operation. +type ListMetricsRequest struct { + *aws.Request + Input *ListMetricsInput + Copy func(*ListMetricsInput) ListMetricsRequest +} + +// Send marshals and sends the ListMetrics API request. +func (r ListMetricsRequest) Send() (*ListMetricsOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*ListMetricsOutput), nil +} + +// ListMetricsRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// List the specified metrics. You can use the returned metrics with GetMetricStatistics +// to obtain statistical data. +// +// Up to 500 results are returned for any one call. To retrieve additional results, +// use the returned token with subsequent calls. +// +// After you create a metric, allow up to fifteen minutes before the metric +// appears. Statistics about the metric, however, are available sooner using +// GetMetricStatistics. +// +// // Example sending a request using the ListMetricsRequest method. +// req := client.ListMetricsRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListMetrics +func (c *CloudWatch) ListMetricsRequest(input *ListMetricsInput) ListMetricsRequest { + op := &aws.Operation{ + Name: opListMetrics, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &aws.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &ListMetricsInput{} + } + + output := &ListMetricsOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return ListMetricsRequest{Request: req, Input: input, Copy: c.ListMetricsRequest} +} + +// Paginate pages iterates over the pages of a ListMetricsRequest operation, +// calling the Next method for each page. Using the paginators Next +// method will depict whether or not there are more pages. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListMetrics operation. +// req := client.ListMetricsRequest(input) +// p := req.Paginate() +// for p.Next() { +// page := p.CurrentPage() +// } +// +// if err := p.Err(); err != nil { +// return err +// } +// +func (p *ListMetricsRequest) Paginate(opts ...aws.Option) ListMetricsPager { + return ListMetricsPager{ + Pager: aws.Pager{ + NewRequest: func() (*aws.Request, error) { + var inCpy *ListMetricsInput + if p.Input != nil { + tmp := *p.Input + inCpy = &tmp + } + + req := p.Copy(inCpy) + req.ApplyOptions(opts...) + + return req.Request, nil + }, + }, + } +} + +// ListMetricsPager is used to paginate the request. This can be done by +// calling Next and CurrentPage. +type ListMetricsPager struct { + aws.Pager +} + +func (p *ListMetricsPager) CurrentPage() *ListMetricsOutput { + return p.Pager.CurrentPage().(*ListMetricsOutput) +} + +const opPutDashboard = "PutDashboard" + +// PutDashboardRequest is a API request type for the PutDashboard API operation. +type PutDashboardRequest struct { + *aws.Request + Input *PutDashboardInput + Copy func(*PutDashboardInput) PutDashboardRequest +} + +// Send marshals and sends the PutDashboard API request. +func (r PutDashboardRequest) Send() (*PutDashboardOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*PutDashboardOutput), nil +} + +// PutDashboardRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Creates a dashboard if it does not already exist, or updates an existing +// dashboard. If you update a dashboard, the entire contents are replaced with +// what you specify here. +// +// You can have up to 500 dashboards per account. All dashboards in your account +// are global, not region-specific. +// +// A simple way to create a dashboard using PutDashboard is to copy an existing +// dashboard. To copy an existing dashboard using the console, you can load +// the dashboard and then use the View/edit source command in the Actions menu +// to display the JSON block for that dashboard. Another way to copy a dashboard +// is to use GetDashboard, and then use the data returned within DashboardBody +// as the template for the new dashboard when you call PutDashboard. +// +// When you create a dashboard with PutDashboard, a good practice is to add +// a text widget at the top of the dashboard with a message that the dashboard +// was created by script and should not be changed in the console. This message +// could also point console users to the location of the DashboardBody script +// or the CloudFormation template used to create the dashboard. +// +// // Example sending a request using the PutDashboardRequest method. +// req := client.PutDashboardRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboard +func (c *CloudWatch) PutDashboardRequest(input *PutDashboardInput) PutDashboardRequest { + op := &aws.Operation{ + Name: opPutDashboard, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutDashboardInput{} + } + + output := &PutDashboardOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return PutDashboardRequest{Request: req, Input: input, Copy: c.PutDashboardRequest} +} + +const opPutMetricAlarm = "PutMetricAlarm" + +// PutMetricAlarmRequest is a API request type for the PutMetricAlarm API operation. +type PutMetricAlarmRequest struct { + *aws.Request + Input *PutMetricAlarmInput + Copy func(*PutMetricAlarmInput) PutMetricAlarmRequest +} + +// Send marshals and sends the PutMetricAlarm API request. +func (r PutMetricAlarmRequest) Send() (*PutMetricAlarmOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*PutMetricAlarmOutput), nil +} + +// PutMetricAlarmRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Creates or updates an alarm and associates it with the specified metric. +// Optionally, this operation can associate one or more Amazon SNS resources +// with the alarm. +// +// When this operation creates an alarm, the alarm state is immediately set +// to INSUFFICIENT_DATA. The alarm is evaluated and its state is set appropriately. +// Any actions associated with the state are then executed. +// +// When you update an existing alarm, its state is left unchanged, but the update +// completely overwrites the previous configuration of the alarm. +// +// If you are an IAM user, you must have Amazon EC2 permissions for some operations: +// +// * iam:CreateServiceLinkedRole for all alarms with EC2 actions +// +// * ec2:DescribeInstanceStatus and ec2:DescribeInstances for all alarms +// on EC2 instance status metrics +// +// * ec2:StopInstances for alarms with stop actions +// +// * ec2:TerminateInstances for alarms with terminate actions +// +// * ec2:DescribeInstanceRecoveryAttribute and ec2:RecoverInstances for alarms +// with recover actions +// +// If you have read/write permissions for Amazon CloudWatch but not for Amazon +// EC2, you can still create an alarm, but the stop or terminate actions are +// not performed. However, if you are later granted the required permissions, +// the alarm actions that you created earlier are performed. +// +// If you are using an IAM role (for example, an EC2 instance profile), you +// cannot stop or terminate the instance using alarm actions. However, you can +// still see the alarm state and perform any other actions such as Amazon SNS +// notifications or Auto Scaling policies. +// +// If you are using temporary security credentials granted using AWS STS, you +// cannot stop or terminate an EC2 instance using alarm actions. +// +// You must create at least one stop, terminate, or reboot alarm using either +// the Amazon EC2 or CloudWatch consoles to create the EC2ActionsAccess IAM +// role. After this IAM role is created, you can create stop, terminate, or +// reboot alarms using a command-line interface or API. +// +// // Example sending a request using the PutMetricAlarmRequest method. +// req := client.PutMetricAlarmRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricAlarm +func (c *CloudWatch) PutMetricAlarmRequest(input *PutMetricAlarmInput) PutMetricAlarmRequest { + op := &aws.Operation{ + Name: opPutMetricAlarm, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutMetricAlarmInput{} + } + + output := &PutMetricAlarmOutput{} + req := c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output.responseMetadata = aws.Response{Request: req} + + return PutMetricAlarmRequest{Request: req, Input: input, Copy: c.PutMetricAlarmRequest} +} + +const opPutMetricData = "PutMetricData" + +// PutMetricDataRequest is a API request type for the PutMetricData API operation. +type PutMetricDataRequest struct { + *aws.Request + Input *PutMetricDataInput + Copy func(*PutMetricDataInput) PutMetricDataRequest +} + +// Send marshals and sends the PutMetricData API request. +func (r PutMetricDataRequest) Send() (*PutMetricDataOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*PutMetricDataOutput), nil +} + +// PutMetricDataRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Publishes metric data points to Amazon CloudWatch. CloudWatch associates +// the data points with the specified metric. If the specified metric does not +// exist, CloudWatch creates the metric. When CloudWatch creates a metric, it +// can take up to fifteen minutes for the metric to appear in calls to ListMetrics. +// +// Each PutMetricData request is limited to 40 KB in size for HTTP POST requests. +// +// Although the Value parameter accepts numbers of type Double, CloudWatch rejects +// values that are either too small or too large. Values must be in the range +// of 8.515920e-109 to 1.174271e+108 (Base 10) or 2e-360 to 2e360 (Base 2). +// In addition, special values (for example, NaN, +Infinity, -Infinity) are +// not supported. +// +// You can use up to 10 dimensions per metric to further clarify what data the +// metric collects. For more information about specifying dimensions, see Publishing +// Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html) +// in the Amazon CloudWatch User Guide. +// +// Data points with time stamps from 24 hours ago or longer can take at least +// 48 hours to become available for GetMetricStatistics from the time they are +// submitted. +// +// CloudWatch needs raw data points to calculate percentile statistics. If you +// publish data using a statistic set instead, you can only retrieve percentile +// statistics for this data if one of the following conditions is true: +// +// * The SampleCount value of the statistic set is 1 +// +// * The Min and the Max values of the statistic set are equal +// +// // Example sending a request using the PutMetricDataRequest method. +// req := client.PutMetricDataRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricData +func (c *CloudWatch) PutMetricDataRequest(input *PutMetricDataInput) PutMetricDataRequest { + op := &aws.Operation{ + Name: opPutMetricData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutMetricDataInput{} + } + + output := &PutMetricDataOutput{} + req := c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output.responseMetadata = aws.Response{Request: req} + + return PutMetricDataRequest{Request: req, Input: input, Copy: c.PutMetricDataRequest} +} + +const opSetAlarmState = "SetAlarmState" + +// SetAlarmStateRequest is a API request type for the SetAlarmState API operation. +type SetAlarmStateRequest struct { + *aws.Request + Input *SetAlarmStateInput + Copy func(*SetAlarmStateInput) SetAlarmStateRequest +} + +// Send marshals and sends the SetAlarmState API request. +func (r SetAlarmStateRequest) Send() (*SetAlarmStateOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*SetAlarmStateOutput), nil +} + +// SetAlarmStateRequest returns a request value for making API operation for +// Amazon CloudWatch. +// +// Temporarily sets the state of an alarm for testing purposes. When the updated +// state differs from the previous value, the action configured for the appropriate +// state is invoked. For example, if your alarm is configured to send an Amazon +// SNS message when an alarm is triggered, temporarily changing the alarm state +// to ALARM sends an SNS message. The alarm returns to its actual state (often +// within seconds). Because the alarm state change happens quickly, it is typically +// only visible in the alarm's History tab in the Amazon CloudWatch console +// or through DescribeAlarmHistory. +// +// // Example sending a request using the SetAlarmStateRequest method. +// req := client.SetAlarmStateRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/SetAlarmState +func (c *CloudWatch) SetAlarmStateRequest(input *SetAlarmStateInput) SetAlarmStateRequest { + op := &aws.Operation{ + Name: opSetAlarmState, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &SetAlarmStateInput{} + } + + output := &SetAlarmStateOutput{} + req := c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(query.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output.responseMetadata = aws.Response{Request: req} + + return SetAlarmStateRequest{Request: req, Input: input, Copy: c.SetAlarmStateRequest} +} + +// Represents the history of a specific alarm. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/AlarmHistoryItem +type AlarmHistoryItem struct { + _ struct{} `type:"structure"` + + // The descriptive name for the alarm. + AlarmName *string `min:"1" type:"string"` + + // Data about the alarm, in JSON format. + HistoryData *string `min:"1" type:"string"` + + // The type of alarm history item. + HistoryItemType HistoryItemType `type:"string" enum:"true"` + + // A summary of the alarm history, in text format. + HistorySummary *string `min:"1" type:"string"` + + // The time stamp for the alarm history item. + Timestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s AlarmHistoryItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AlarmHistoryItem) GoString() string { + return s.String() +} + +// Represents a specific dashboard. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DashboardEntry +type DashboardEntry struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the dashboard. + DashboardArn *string `type:"string"` + + // The name of the dashboard. + DashboardName *string `type:"string"` + + // The time stamp of when the dashboard was last modified, either by an API + // call or through the console. This number is expressed as the number of milliseconds + // since Jan 1, 1970 00:00:00 UTC. + LastModified *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The size of the dashboard, in bytes. + Size *int64 `type:"long"` +} + +// String returns the string representation +func (s DashboardEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DashboardEntry) GoString() string { + return s.String() +} + +// An error or warning for the operation. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DashboardValidationMessage +type DashboardValidationMessage struct { + _ struct{} `type:"structure"` + + // The data path related to the message. + DataPath *string `type:"string"` + + // A message describing the error or warning. + Message *string `type:"string"` +} + +// String returns the string representation +func (s DashboardValidationMessage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DashboardValidationMessage) GoString() string { + return s.String() +} + +// Encapsulates the statistical data that CloudWatch computes from metric data. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/Datapoint +type Datapoint struct { + _ struct{} `type:"structure"` + + // The average of the metric values that correspond to the data point. + Average *float64 `type:"double"` + + // The percentile statistic for the data point. + ExtendedStatistics map[string]float64 `type:"map"` + + // The maximum metric value for the data point. + Maximum *float64 `type:"double"` + + // The minimum metric value for the data point. + Minimum *float64 `type:"double"` + + // The number of metric values that contributed to the aggregate value of this + // data point. + SampleCount *float64 `type:"double"` + + // The sum of the metric values for the data point. + Sum *float64 `type:"double"` + + // The time stamp used for the data point. + Timestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The standard unit for the data point. + Unit StandardUnit `type:"string" enum:"true"` +} + +// String returns the string representation +func (s Datapoint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Datapoint) GoString() string { + return s.String() +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteAlarmsInput +type DeleteAlarmsInput struct { + _ struct{} `type:"structure"` + + // The alarms to be deleted. + // + // AlarmNames is a required field + AlarmNames []string `type:"list" required:"true"` +} + +// String returns the string representation +func (s DeleteAlarmsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteAlarmsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteAlarmsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DeleteAlarmsInput"} + + if s.AlarmNames == nil { + invalidParams.Add(aws.NewErrParamRequired("AlarmNames")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteAlarmsOutput +type DeleteAlarmsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s DeleteAlarmsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteAlarmsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DeleteAlarmsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboardsInput +type DeleteDashboardsInput struct { + _ struct{} `type:"structure"` + + // The dashboards to be deleted. This parameter is required. + // + // DashboardNames is a required field + DashboardNames []string `type:"list" required:"true"` +} + +// String returns the string representation +func (s DeleteDashboardsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDashboardsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDashboardsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DeleteDashboardsInput"} + + if s.DashboardNames == nil { + invalidParams.Add(aws.NewErrParamRequired("DashboardNames")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboardsOutput +type DeleteDashboardsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s DeleteDashboardsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDashboardsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DeleteDashboardsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmHistoryInput +type DescribeAlarmHistoryInput struct { + _ struct{} `type:"structure"` + + // The name of the alarm. + AlarmName *string `min:"1" type:"string"` + + // The ending date to retrieve alarm history. + EndDate *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The type of alarm histories to retrieve. + HistoryItemType HistoryItemType `type:"string" enum:"true"` + + // The maximum number of alarm history records to retrieve. + MaxRecords *int64 `min:"1" type:"integer"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `type:"string"` + + // The starting date to retrieve alarm history. + StartDate *time.Time `type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s DescribeAlarmHistoryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAlarmHistoryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeAlarmHistoryInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DescribeAlarmHistoryInput"} + if s.AlarmName != nil && len(*s.AlarmName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("AlarmName", 1)) + } + if s.MaxRecords != nil && *s.MaxRecords < 1 { + invalidParams.Add(aws.NewErrParamMinValue("MaxRecords", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmHistoryOutput +type DescribeAlarmHistoryOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The alarm histories, in JSON format. + AlarmHistoryItems []AlarmHistoryItem `type:"list"` + + // The token that marks the start of the next batch of returned results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeAlarmHistoryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAlarmHistoryOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DescribeAlarmHistoryOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmsForMetricInput +type DescribeAlarmsForMetricInput struct { + _ struct{} `type:"structure"` + + // The dimensions associated with the metric. If the metric has any associated + // dimensions, you must specify them in order for the call to succeed. + Dimensions []Dimension `type:"list"` + + // The percentile statistic for the metric. Specify a value between p0.0 and + // p100. + ExtendedStatistic *string `type:"string"` + + // The name of the metric. + // + // MetricName is a required field + MetricName *string `min:"1" type:"string" required:"true"` + + // The namespace of the metric. + // + // Namespace is a required field + Namespace *string `min:"1" type:"string" required:"true"` + + // The period, in seconds, over which the statistic is applied. + Period *int64 `min:"1" type:"integer"` + + // The statistic for the metric, other than percentiles. For percentile statistics, + // use ExtendedStatistics. + Statistic Statistic `type:"string" enum:"true"` + + // The unit for the metric. + Unit StandardUnit `type:"string" enum:"true"` +} + +// String returns the string representation +func (s DescribeAlarmsForMetricInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAlarmsForMetricInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeAlarmsForMetricInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DescribeAlarmsForMetricInput"} + + if s.MetricName == nil { + invalidParams.Add(aws.NewErrParamRequired("MetricName")) + } + if s.MetricName != nil && len(*s.MetricName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1)) + } + + if s.Namespace == nil { + invalidParams.Add(aws.NewErrParamRequired("Namespace")) + } + if s.Namespace != nil && len(*s.Namespace) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1)) + } + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(aws.NewErrParamMinValue("Period", 1)) + } + if s.Dimensions != nil { + for i, v := range s.Dimensions { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmsForMetricOutput +type DescribeAlarmsForMetricOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The information for each alarm with the specified metric. + MetricAlarms []MetricAlarm `type:"list"` +} + +// String returns the string representation +func (s DescribeAlarmsForMetricOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAlarmsForMetricOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DescribeAlarmsForMetricOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmsInput +type DescribeAlarmsInput struct { + _ struct{} `type:"structure"` + + // The action name prefix. + ActionPrefix *string `min:"1" type:"string"` + + // The alarm name prefix. If this parameter is specified, you cannot specify + // AlarmNames. + AlarmNamePrefix *string `min:"1" type:"string"` + + // The names of the alarms. + AlarmNames []string `type:"list"` + + // The maximum number of alarm descriptions to retrieve. + MaxRecords *int64 `min:"1" type:"integer"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `type:"string"` + + // The state value to be used in matching alarms. + StateValue StateValue `type:"string" enum:"true"` +} + +// String returns the string representation +func (s DescribeAlarmsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAlarmsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeAlarmsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DescribeAlarmsInput"} + if s.ActionPrefix != nil && len(*s.ActionPrefix) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("ActionPrefix", 1)) + } + if s.AlarmNamePrefix != nil && len(*s.AlarmNamePrefix) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("AlarmNamePrefix", 1)) + } + if s.MaxRecords != nil && *s.MaxRecords < 1 { + invalidParams.Add(aws.NewErrParamMinValue("MaxRecords", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmsOutput +type DescribeAlarmsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The information for the specified alarms. + MetricAlarms []MetricAlarm `type:"list"` + + // The token that marks the start of the next batch of returned results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeAlarmsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAlarmsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DescribeAlarmsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Expands the identity of a metric. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/Dimension +type Dimension struct { + _ struct{} `type:"structure"` + + // The name of the dimension. + // + // Name is a required field + Name *string `min:"1" type:"string" required:"true"` + + // The value representing the dimension measurement. + // + // Value is a required field + Value *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s Dimension) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Dimension) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Dimension) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "Dimension"} + + if s.Name == nil { + invalidParams.Add(aws.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Name", 1)) + } + + if s.Value == nil { + invalidParams.Add(aws.NewErrParamRequired("Value")) + } + if s.Value != nil && len(*s.Value) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Value", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Represents filters for a dimension. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DimensionFilter +type DimensionFilter struct { + _ struct{} `type:"structure"` + + // The dimension name to be matched. + // + // Name is a required field + Name *string `min:"1" type:"string" required:"true"` + + // The value of the dimension to be matched. + Value *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DimensionFilter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DimensionFilter) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DimensionFilter) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DimensionFilter"} + + if s.Name == nil { + invalidParams.Add(aws.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Name", 1)) + } + if s.Value != nil && len(*s.Value) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Value", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DisableAlarmActionsInput +type DisableAlarmActionsInput struct { + _ struct{} `type:"structure"` + + // The names of the alarms. + // + // AlarmNames is a required field + AlarmNames []string `type:"list" required:"true"` +} + +// String returns the string representation +func (s DisableAlarmActionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableAlarmActionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisableAlarmActionsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DisableAlarmActionsInput"} + + if s.AlarmNames == nil { + invalidParams.Add(aws.NewErrParamRequired("AlarmNames")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DisableAlarmActionsOutput +type DisableAlarmActionsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s DisableAlarmActionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableAlarmActionsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DisableAlarmActionsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/EnableAlarmActionsInput +type EnableAlarmActionsInput struct { + _ struct{} `type:"structure"` + + // The names of the alarms. + // + // AlarmNames is a required field + AlarmNames []string `type:"list" required:"true"` +} + +// String returns the string representation +func (s EnableAlarmActionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableAlarmActionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *EnableAlarmActionsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "EnableAlarmActionsInput"} + + if s.AlarmNames == nil { + invalidParams.Add(aws.NewErrParamRequired("AlarmNames")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/EnableAlarmActionsOutput +type EnableAlarmActionsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s EnableAlarmActionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableAlarmActionsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s EnableAlarmActionsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboardInput +type GetDashboardInput struct { + _ struct{} `type:"structure"` + + // The name of the dashboard to be described. + // + // DashboardName is a required field + DashboardName *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s GetDashboardInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDashboardInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetDashboardInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "GetDashboardInput"} + + if s.DashboardName == nil { + invalidParams.Add(aws.NewErrParamRequired("DashboardName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboardOutput +type GetDashboardOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The Amazon Resource Name (ARN) of the dashboard. + DashboardArn *string `type:"string"` + + // The detailed information about the dashboard, including what widgets are + // included and their location on the dashboard. For more information about + // the DashboardBody syntax, see CloudWatch-Dashboard-Body-Structure. + DashboardBody *string `type:"string"` + + // The name of the dashboard. + DashboardName *string `type:"string"` +} + +// String returns the string representation +func (s GetDashboardOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDashboardOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s GetDashboardOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricDataInput +type GetMetricDataInput struct { + _ struct{} `type:"structure"` + + // The time stamp indicating the latest data to be returned. + // + // EndTime is a required field + EndTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The maximum number of data points the request should return before paginating. + // If you omit this, the default of 100,800 is used. + MaxDatapoints *int64 `type:"integer"` + + // The metric queries to be returned. A single GetMetricData call can include + // as many as 100 MetricDataQuery structures. Each of these structures can specify + // either a metric to retrieve, or a math expression to perform on retrieved + // data. + // + // MetricDataQueries is a required field + MetricDataQueries []MetricDataQuery `type:"list" required:"true"` + + // Include this value, if it was returned by the previous call, to get the next + // set of data points. + NextToken *string `type:"string"` + + // The order in which data points should be returned. TimestampDescending returns + // the newest data first and paginates when the MaxDatapoints limit is reached. + // TimestampAscending returns the oldest data first and paginates when the MaxDatapoints + // limit is reached. + ScanBy ScanBy `type:"string" enum:"true"` + + // The time stamp indicating the earliest data to be returned. + // + // StartTime is a required field + StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` +} + +// String returns the string representation +func (s GetMetricDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetMetricDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetMetricDataInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "GetMetricDataInput"} + + if s.EndTime == nil { + invalidParams.Add(aws.NewErrParamRequired("EndTime")) + } + + if s.MetricDataQueries == nil { + invalidParams.Add(aws.NewErrParamRequired("MetricDataQueries")) + } + + if s.StartTime == nil { + invalidParams.Add(aws.NewErrParamRequired("StartTime")) + } + if s.MetricDataQueries != nil { + for i, v := range s.MetricDataQueries { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "MetricDataQueries", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricDataOutput +type GetMetricDataOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The metrics that are returned, including the metric name, namespace, and + // dimensions. + MetricDataResults []MetricDataResult `type:"list"` + + // A token that marks the next batch of returned results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetMetricDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetMetricDataOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s GetMetricDataOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatisticsInput +type GetMetricStatisticsInput struct { + _ struct{} `type:"structure"` + + // The dimensions. If the metric contains multiple dimensions, you must include + // a value for each dimension. CloudWatch treats each unique combination of + // dimensions as a separate metric. If a specific combination of dimensions + // was not published, you can't retrieve statistics for it. You must specify + // the same dimensions that were used when the metrics were created. For an + // example, see Dimension Combinations (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#dimension-combinations) + // in the Amazon CloudWatch User Guide. For more information about specifying + // dimensions, see Publishing Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html) + // in the Amazon CloudWatch User Guide. + Dimensions []Dimension `type:"list"` + + // The time stamp that determines the last data point to return. + // + // The value specified is exclusive; results include data points up to the specified + // time stamp. The time stamp must be in ISO 8601 UTC format (for example, 2016-10-10T23:00:00Z). + // + // EndTime is a required field + EndTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The percentile statistics. Specify values between p0.0 and p100. When calling + // GetMetricStatistics, you must specify either Statistics or ExtendedStatistics, + // but not both. + ExtendedStatistics []string `min:"1" type:"list"` + + // The name of the metric, with or without spaces. + // + // MetricName is a required field + MetricName *string `min:"1" type:"string" required:"true"` + + // The namespace of the metric, with or without spaces. + // + // Namespace is a required field + Namespace *string `min:"1" type:"string" required:"true"` + + // The granularity, in seconds, of the returned data points. For metrics with + // regular resolution, a period can be as short as one minute (60 seconds) and + // must be a multiple of 60. For high-resolution metrics that are collected + // at intervals of less than one minute, the period can be 1, 5, 10, 30, 60, + // or any multiple of 60. High-resolution metrics are those metrics stored by + // a PutMetricData call that includes a StorageResolution of 1 second. + // + // If the StartTime parameter specifies a time stamp that is greater than 3 + // hours ago, you must specify the period as follows or no data points in that + // time range is returned: + // + // * Start time between 3 hours and 15 days ago - Use a multiple of 60 seconds + // (1 minute). + // + // * Start time between 15 and 63 days ago - Use a multiple of 300 seconds + // (5 minutes). + // + // * Start time greater than 63 days ago - Use a multiple of 3600 seconds + // (1 hour). + // + // Period is a required field + Period *int64 `min:"1" type:"integer" required:"true"` + + // The time stamp that determines the first data point to return. Start times + // are evaluated relative to the time that CloudWatch receives the request. + // + // The value specified is inclusive; results include data points with the specified + // time stamp. The time stamp must be in ISO 8601 UTC format (for example, 2016-10-03T23:00:00Z). + // + // CloudWatch rounds the specified time stamp as follows: + // + // * Start time less than 15 days ago - Round down to the nearest whole minute. + // For example, 12:32:34 is rounded down to 12:32:00. + // + // * Start time between 15 and 63 days ago - Round down to the nearest 5-minute + // clock interval. For example, 12:32:34 is rounded down to 12:30:00. + // + // * Start time greater than 63 days ago - Round down to the nearest 1-hour + // clock interval. For example, 12:32:34 is rounded down to 12:00:00. + // + // If you set Period to 5, 10, or 30, the start time of your request is rounded + // down to the nearest time that corresponds to even 5-, 10-, or 30-second divisions + // of a minute. For example, if you make a query at (HH:mm:ss) 01:05:23 for + // the previous 10-second period, the start time of your request is rounded + // down and you receive data from 01:05:10 to 01:05:20. If you make a query + // at 15:07:17 for the previous 5 minutes of data, using a period of 5 seconds, + // you receive data timestamped between 15:02:15 and 15:07:15. + // + // StartTime is a required field + StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The metric statistics, other than percentile. For percentile statistics, + // use ExtendedStatistics. When calling GetMetricStatistics, you must specify + // either Statistics or ExtendedStatistics, but not both. + Statistics []Statistic `min:"1" type:"list"` + + // The unit for a given metric. Metrics may be reported in multiple units. Not + // supplying a unit results in all units being returned. If you specify only + // a unit that the metric does not report, the results of the call are null. + Unit StandardUnit `type:"string" enum:"true"` +} + +// String returns the string representation +func (s GetMetricStatisticsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetMetricStatisticsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetMetricStatisticsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "GetMetricStatisticsInput"} + + if s.EndTime == nil { + invalidParams.Add(aws.NewErrParamRequired("EndTime")) + } + if s.ExtendedStatistics != nil && len(s.ExtendedStatistics) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("ExtendedStatistics", 1)) + } + + if s.MetricName == nil { + invalidParams.Add(aws.NewErrParamRequired("MetricName")) + } + if s.MetricName != nil && len(*s.MetricName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1)) + } + + if s.Namespace == nil { + invalidParams.Add(aws.NewErrParamRequired("Namespace")) + } + if s.Namespace != nil && len(*s.Namespace) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1)) + } + + if s.Period == nil { + invalidParams.Add(aws.NewErrParamRequired("Period")) + } + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(aws.NewErrParamMinValue("Period", 1)) + } + + if s.StartTime == nil { + invalidParams.Add(aws.NewErrParamRequired("StartTime")) + } + if s.Statistics != nil && len(s.Statistics) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Statistics", 1)) + } + if s.Dimensions != nil { + for i, v := range s.Dimensions { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatisticsOutput +type GetMetricStatisticsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The data points for the specified metric. + Datapoints []Datapoint `type:"list"` + + // A label for the specified metric. + Label *string `type:"string"` +} + +// String returns the string representation +func (s GetMetricStatisticsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetMetricStatisticsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s GetMetricStatisticsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboardsInput +type ListDashboardsInput struct { + _ struct{} `type:"structure"` + + // If you specify this parameter, only the dashboards with names starting with + // the specified string are listed. The maximum length is 255, and valid characters + // are A-Z, a-z, 0-9, ".", "-", and "_". + DashboardNamePrefix *string `type:"string"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s ListDashboardsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListDashboardsInput) GoString() string { + return s.String() +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboardsOutput +type ListDashboardsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The list of matching dashboards. + DashboardEntries []DashboardEntry `type:"list"` + + // The token that marks the start of the next batch of returned results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s ListDashboardsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListDashboardsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s ListDashboardsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListMetricsInput +type ListMetricsInput struct { + _ struct{} `type:"structure"` + + // The dimensions to filter against. + Dimensions []DimensionFilter `type:"list"` + + // The name of the metric to filter against. + MetricName *string `min:"1" type:"string"` + + // The namespace to filter against. + Namespace *string `min:"1" type:"string"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s ListMetricsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListMetricsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListMetricsInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "ListMetricsInput"} + if s.MetricName != nil && len(*s.MetricName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1)) + } + if s.Namespace != nil && len(*s.Namespace) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1)) + } + if s.Dimensions != nil { + for i, v := range s.Dimensions { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListMetricsOutput +type ListMetricsOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The metrics. + Metrics []Metric `type:"list"` + + // The token that marks the start of the next batch of returned results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s ListMetricsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListMetricsOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s ListMetricsOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// A message returned by the GetMetricDataAPI, including a code and a description. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/MessageData +type MessageData struct { + _ struct{} `type:"structure"` + + // The error code or status code associated with the message. + Code *string `type:"string"` + + // The message text. + Value *string `type:"string"` +} + +// String returns the string representation +func (s MessageData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MessageData) GoString() string { + return s.String() +} + +// Represents a specific metric. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/Metric +type Metric struct { + _ struct{} `type:"structure"` + + // The dimensions for the metric. + Dimensions []Dimension `type:"list"` + + // The name of the metric. + MetricName *string `min:"1" type:"string"` + + // The namespace of the metric. + Namespace *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s Metric) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Metric) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Metric) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "Metric"} + if s.MetricName != nil && len(*s.MetricName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1)) + } + if s.Namespace != nil && len(*s.Namespace) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1)) + } + if s.Dimensions != nil { + for i, v := range s.Dimensions { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Represents an alarm. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/MetricAlarm +type MetricAlarm struct { + _ struct{} `type:"structure"` + + // Indicates whether actions should be executed during any changes to the alarm + // state. + ActionsEnabled *bool `type:"boolean"` + + // The actions to execute when this alarm transitions to the ALARM state from + // any other state. Each action is specified as an Amazon Resource Name (ARN). + AlarmActions []string `type:"list"` + + // The Amazon Resource Name (ARN) of the alarm. + AlarmArn *string `min:"1" type:"string"` + + // The time stamp of the last update to the alarm configuration. + AlarmConfigurationUpdatedTimestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The description of the alarm. + AlarmDescription *string `type:"string"` + + // The name of the alarm. + AlarmName *string `min:"1" type:"string"` + + // The arithmetic operation to use when comparing the specified statistic and + // threshold. The specified statistic value is used as the first operand. + ComparisonOperator ComparisonOperator `type:"string" enum:"true"` + + // The number of datapoints that must be breaching to trigger the alarm. + DatapointsToAlarm *int64 `min:"1" type:"integer"` + + // The dimensions for the metric associated with the alarm. + Dimensions []Dimension `type:"list"` + + // Used only for alarms based on percentiles. If ignore, the alarm state does + // not change during periods with too few data points to be statistically significant. + // If evaluate or this parameter is not used, the alarm is always evaluated + // and possibly changes state no matter how many data points are available. + EvaluateLowSampleCountPercentile *string `min:"1" type:"string"` + + // The number of periods over which data is compared to the specified threshold. + EvaluationPeriods *int64 `min:"1" type:"integer"` + + // The percentile statistic for the metric associated with the alarm. Specify + // a value between p0.0 and p100. + ExtendedStatistic *string `type:"string"` + + // The actions to execute when this alarm transitions to the INSUFFICIENT_DATA + // state from any other state. Each action is specified as an Amazon Resource + // Name (ARN). + InsufficientDataActions []string `type:"list"` + + // The name of the metric associated with the alarm. + MetricName *string `min:"1" type:"string"` + + // The namespace of the metric associated with the alarm. + Namespace *string `min:"1" type:"string"` + + // The actions to execute when this alarm transitions to the OK state from any + // other state. Each action is specified as an Amazon Resource Name (ARN). + OKActions []string `type:"list"` + + // The period, in seconds, over which the statistic is applied. + Period *int64 `min:"1" type:"integer"` + + // An explanation for the alarm state, in text format. + StateReason *string `type:"string"` + + // An explanation for the alarm state, in JSON format. + StateReasonData *string `type:"string"` + + // The time stamp of the last update to the alarm state. + StateUpdatedTimestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The state value for the alarm. + StateValue StateValue `type:"string" enum:"true"` + + // The statistic for the metric associated with the alarm, other than percentile. + // For percentile statistics, use ExtendedStatistic. + Statistic Statistic `type:"string" enum:"true"` + + // The value to compare with the specified statistic. + Threshold *float64 `type:"double"` + + // Sets how this alarm is to handle missing data points. If this parameter is + // omitted, the default behavior of missing is used. + TreatMissingData *string `min:"1" type:"string"` + + // The unit of the metric associated with the alarm. + Unit StandardUnit `type:"string" enum:"true"` +} + +// String returns the string representation +func (s MetricAlarm) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricAlarm) GoString() string { + return s.String() +} + +// This structure indicates the metric data to return, and whether this call +// is just retrieving a batch set of data for one metric, or is performing a +// math expression on metric data. A single GetMetricData call can include up +// to 100 MetricDataQuery structures. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/MetricDataQuery +type MetricDataQuery struct { + _ struct{} `type:"structure"` + + // The math expression to be performed on the returned data, if this structure + // is performing a math expression. For more information about metric math expressions, + // see Metric Math Syntax and Functions (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html#metric-math-syntax) + // in the Amazon CloudWatch User Guide. + // + // Within one MetricDataQuery structure, you must specify either Expression + // or MetricStat but not both. + Expression *string `min:"1" type:"string"` + + // A short name used to tie this structure to the results in the response. This + // name must be unique within a single call to GetMetricData. If you are performing + // math expressions on this set of data, this name represents that data and + // can serve as a variable in the mathematical expression. The valid characters + // are letters, numbers, and underscore. The first character must be a lowercase + // letter. + // + // Id is a required field + Id *string `min:"1" type:"string" required:"true"` + + // A human-readable label for this metric or expression. This is especially + // useful if this is an expression, so that you know what the value represents. + // If the metric or expression is shown in a CloudWatch dashboard widget, the + // label is shown. If Label is omitted, CloudWatch generates a default. + Label *string `type:"string"` + + // The metric to be returned, along with statistics, period, and units. Use + // this parameter only if this structure is performing a data retrieval and + // not performing a math expression on the returned data. + // + // Within one MetricDataQuery structure, you must specify either Expression + // or MetricStat but not both. + MetricStat *MetricStat `type:"structure"` + + // Indicates whether to return the time stamps and raw data values of this metric. + // If you are performing this call just to do math expressions and do not also + // need the raw data returned, you can specify False. If you omit this, the + // default of True is used. + ReturnData *bool `type:"boolean"` +} + +// String returns the string representation +func (s MetricDataQuery) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricDataQuery) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *MetricDataQuery) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "MetricDataQuery"} + if s.Expression != nil && len(*s.Expression) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Expression", 1)) + } + + if s.Id == nil { + invalidParams.Add(aws.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Id", 1)) + } + if s.MetricStat != nil { + if err := s.MetricStat.Validate(); err != nil { + invalidParams.AddNested("MetricStat", err.(aws.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// A GetMetricData call returns an array of MetricDataResult structures. Each +// of these structures includes the data points for that metric, along with +// the time stamps of those data points and other identifying information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/MetricDataResult +type MetricDataResult struct { + _ struct{} `type:"structure"` + + // The short name you specified to represent this metric. + Id *string `min:"1" type:"string"` + + // The human-readable label associated with the data. + Label *string `type:"string"` + + // A list of messages with additional information about the data returned. + Messages []MessageData `type:"list"` + + // The status of the returned data. Complete indicates that all data points + // in the requested time range were returned. PartialData means that an incomplete + // set of data points were returned. You can use the NextToken value that was + // returned and repeat your request to get more data points. NextToken is not + // returned if you are performing a math expression. InternalError indicates + // that an error occurred. Retry your request using NextToken, if present. + StatusCode StatusCode `type:"string" enum:"true"` + + // The time stamps for the data points, formatted in Unix timestamp format. + // The number of time stamps always matches the number of values and the value + // for Timestamps[x] is Values[x]. + Timestamps []time.Time `type:"list"` + + // The data points for the metric corresponding to Timestamps. The number of + // values always matches the number of time stamps and the time stamp for Values[x] + // is Timestamps[x]. + Values []float64 `type:"list"` +} + +// String returns the string representation +func (s MetricDataResult) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricDataResult) GoString() string { + return s.String() +} + +// Encapsulates the information sent to either create a metric or add new values +// to be aggregated into an existing metric. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/MetricDatum +type MetricDatum struct { + _ struct{} `type:"structure"` + + // The dimensions associated with the metric. + Dimensions []Dimension `type:"list"` + + // The name of the metric. + // + // MetricName is a required field + MetricName *string `min:"1" type:"string" required:"true"` + + // The statistical values for the metric. + StatisticValues *StatisticSet `type:"structure"` + + // Valid values are 1 and 60. Setting this to 1 specifies this metric as a high-resolution + // metric, so that CloudWatch stores the metric with sub-minute resolution down + // to one second. Setting this to 60 specifies this metric as a regular-resolution + // metric, which CloudWatch stores at 1-minute resolution. Currently, high resolution + // is available only for custom metrics. For more information about high-resolution + // metrics, see High-Resolution Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics) + // in the Amazon CloudWatch User Guide. + // + // This field is optional, if you do not specify it the default of 60 is used. + StorageResolution *int64 `min:"1" type:"integer"` + + // The time the metric data was received, expressed as the number of milliseconds + // since Jan 1, 1970 00:00:00 UTC. + Timestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The unit of the metric. + Unit StandardUnit `type:"string" enum:"true"` + + // The value for the metric. + // + // Although the parameter accepts numbers of type Double, CloudWatch rejects + // values that are either too small or too large. Values must be in the range + // of 8.515920e-109 to 1.174271e+108 (Base 10) or 2e-360 to 2e360 (Base 2). + // In addition, special values (for example, NaN, +Infinity, -Infinity) are + // not supported. + Value *float64 `type:"double"` +} + +// String returns the string representation +func (s MetricDatum) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricDatum) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *MetricDatum) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "MetricDatum"} + + if s.MetricName == nil { + invalidParams.Add(aws.NewErrParamRequired("MetricName")) + } + if s.MetricName != nil && len(*s.MetricName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1)) + } + if s.StorageResolution != nil && *s.StorageResolution < 1 { + invalidParams.Add(aws.NewErrParamMinValue("StorageResolution", 1)) + } + if s.Dimensions != nil { + for i, v := range s.Dimensions { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams)) + } + } + } + if s.StatisticValues != nil { + if err := s.StatisticValues.Validate(); err != nil { + invalidParams.AddNested("StatisticValues", err.(aws.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// This structure defines the metric to be returned, along with the statistics, +// period, and units. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/MetricStat +type MetricStat struct { + _ struct{} `type:"structure"` + + // The metric to return, including the metric name, namespace, and dimensions. + // + // Metric is a required field + Metric *Metric `type:"structure" required:"true"` + + // The period to use when retrieving the metric. + // + // Period is a required field + Period *int64 `min:"1" type:"integer" required:"true"` + + // The statistic to return. It can include any CloudWatch statistic or extended + // statistic. + // + // Stat is a required field + Stat *string `type:"string" required:"true"` + + // The unit to use for the returned data points. + Unit StandardUnit `type:"string" enum:"true"` +} + +// String returns the string representation +func (s MetricStat) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricStat) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *MetricStat) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "MetricStat"} + + if s.Metric == nil { + invalidParams.Add(aws.NewErrParamRequired("Metric")) + } + + if s.Period == nil { + invalidParams.Add(aws.NewErrParamRequired("Period")) + } + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(aws.NewErrParamMinValue("Period", 1)) + } + + if s.Stat == nil { + invalidParams.Add(aws.NewErrParamRequired("Stat")) + } + if s.Metric != nil { + if err := s.Metric.Validate(); err != nil { + invalidParams.AddNested("Metric", err.(aws.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboardInput +type PutDashboardInput struct { + _ struct{} `type:"structure"` + + // The detailed information about the dashboard in JSON format, including the + // widgets to include and their location on the dashboard. This parameter is + // required. + // + // For more information about the syntax, see CloudWatch-Dashboard-Body-Structure. + // + // DashboardBody is a required field + DashboardBody *string `type:"string" required:"true"` + + // The name of the dashboard. If a dashboard with this name already exists, + // this call modifies that dashboard, replacing its current contents. Otherwise, + // a new dashboard is created. The maximum length is 255, and valid characters + // are A-Z, a-z, 0-9, "-", and "_". This parameter is required. + // + // DashboardName is a required field + DashboardName *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s PutDashboardInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutDashboardInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutDashboardInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "PutDashboardInput"} + + if s.DashboardBody == nil { + invalidParams.Add(aws.NewErrParamRequired("DashboardBody")) + } + + if s.DashboardName == nil { + invalidParams.Add(aws.NewErrParamRequired("DashboardName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboardOutput +type PutDashboardOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // If the input for PutDashboard was correct and the dashboard was successfully + // created or modified, this result is empty. + // + // If this result includes only warning messages, then the input was valid enough + // for the dashboard to be created or modified, but some elements of the dashboard + // may not render. + // + // If this result includes error messages, the input was not valid and the operation + // failed. + DashboardValidationMessages []DashboardValidationMessage `type:"list"` +} + +// String returns the string representation +func (s PutDashboardOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutDashboardOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s PutDashboardOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricAlarmInput +type PutMetricAlarmInput struct { + _ struct{} `type:"structure"` + + // Indicates whether actions should be executed during any changes to the alarm + // state. + ActionsEnabled *bool `type:"boolean"` + + // The actions to execute when this alarm transitions to the ALARM state from + // any other state. Each action is specified as an Amazon Resource Name (ARN). + // + // Valid Values: arn:aws:automate:region:ec2:stop | arn:aws:automate:region:ec2:terminate + // | arn:aws:automate:region:ec2:recover | arn:aws:sns:region:account-id:sns-topic-name + // | arn:aws:autoscaling:region:account-id:scalingPolicy:policy-id autoScalingGroupName/group-friendly-name:policyName/policy-friendly-name + // + // Valid Values (for use with IAM roles): arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Stop/1.0 + // | arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Terminate/1.0 + // | arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Reboot/1.0 + AlarmActions []string `type:"list"` + + // The description for the alarm. + AlarmDescription *string `type:"string"` + + // The name for the alarm. This name must be unique within the AWS account. + // + // AlarmName is a required field + AlarmName *string `min:"1" type:"string" required:"true"` + + // The arithmetic operation to use when comparing the specified statistic and + // threshold. The specified statistic value is used as the first operand. + // + // ComparisonOperator is a required field + ComparisonOperator ComparisonOperator `type:"string" required:"true" enum:"true"` + + // The number of datapoints that must be breaching to trigger the alarm. This + // is used only if you are setting an "M out of N" alarm. In that case, this + // value is the M. For more information, see Evaluating an Alarm (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarm-evaluation) + // in the Amazon CloudWatch User Guide. + DatapointsToAlarm *int64 `min:"1" type:"integer"` + + // The dimensions for the metric associated with the alarm. + Dimensions []Dimension `type:"list"` + + // Used only for alarms based on percentiles. If you specify ignore, the alarm + // state does not change during periods with too few data points to be statistically + // significant. If you specify evaluate or omit this parameter, the alarm is + // always evaluated and possibly changes state no matter how many data points + // are available. For more information, see Percentile-Based CloudWatch Alarms + // and Low Data Samples (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#percentiles-with-low-samples). + // + // Valid Values: evaluate | ignore + EvaluateLowSampleCountPercentile *string `min:"1" type:"string"` + + // The number of periods over which data is compared to the specified threshold. + // If you are setting an alarm which requires that a number of consecutive data + // points be breaching to trigger the alarm, this value specifies that number. + // If you are setting an "M out of N" alarm, this value is the N. + // + // An alarm's total current evaluation period can be no longer than one day, + // so this number multiplied by Period cannot be more than 86,400 seconds. + // + // EvaluationPeriods is a required field + EvaluationPeriods *int64 `min:"1" type:"integer" required:"true"` + + // The percentile statistic for the metric associated with the alarm. Specify + // a value between p0.0 and p100. When you call PutMetricAlarm, you must specify + // either Statistic or ExtendedStatistic, but not both. + ExtendedStatistic *string `type:"string"` + + // The actions to execute when this alarm transitions to the INSUFFICIENT_DATA + // state from any other state. Each action is specified as an Amazon Resource + // Name (ARN). + // + // Valid Values: arn:aws:automate:region:ec2:stop | arn:aws:automate:region:ec2:terminate + // | arn:aws:automate:region:ec2:recover | arn:aws:sns:region:account-id:sns-topic-name + // | arn:aws:autoscaling:region:account-id:scalingPolicy:policy-id autoScalingGroupName/group-friendly-name:policyName/policy-friendly-name + // + // Valid Values (for use with IAM roles): arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Stop/1.0 + // | arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Terminate/1.0 + // | arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Reboot/1.0 + InsufficientDataActions []string `type:"list"` + + // The name for the metric associated with the alarm. + // + // MetricName is a required field + MetricName *string `min:"1" type:"string" required:"true"` + + // The namespace for the metric associated with the alarm. + // + // Namespace is a required field + Namespace *string `min:"1" type:"string" required:"true"` + + // The actions to execute when this alarm transitions to an OK state from any + // other state. Each action is specified as an Amazon Resource Name (ARN). + // + // Valid Values: arn:aws:automate:region:ec2:stop | arn:aws:automate:region:ec2:terminate + // | arn:aws:automate:region:ec2:recover | arn:aws:sns:region:account-id:sns-topic-name + // | arn:aws:autoscaling:region:account-id:scalingPolicy:policy-id autoScalingGroupName/group-friendly-name:policyName/policy-friendly-name + // + // Valid Values (for use with IAM roles): arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Stop/1.0 + // | arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Terminate/1.0 + // | arn:aws:swf:region:{account-id}:action/actions/AWS_EC2.InstanceId.Reboot/1.0 + OKActions []string `type:"list"` + + // The period, in seconds, over which the specified statistic is applied. Valid + // values are 10, 30, and any multiple of 60. + // + // Be sure to specify 10 or 30 only for metrics that are stored by a PutMetricData + // call with a StorageResolution of 1. If you specify a period of 10 or 30 for + // a metric that does not have sub-minute resolution, the alarm still attempts + // to gather data at the period rate that you specify. In this case, it does + // not receive data for the attempts that do not correspond to a one-minute + // data resolution, and the alarm may often lapse into INSUFFICENT_DATA status. + // Specifying 10 or 30 also sets this alarm as a high-resolution alarm, which + // has a higher charge than other alarms. For more information about pricing, + // see Amazon CloudWatch Pricing (https://aws.amazon.com/cloudwatch/pricing/). + // + // An alarm's total current evaluation period can be no longer than one day, + // so Period multiplied by EvaluationPeriods cannot be more than 86,400 seconds. + // + // Period is a required field + Period *int64 `min:"1" type:"integer" required:"true"` + + // The statistic for the metric associated with the alarm, other than percentile. + // For percentile statistics, use ExtendedStatistic. When you call PutMetricAlarm, + // you must specify either Statistic or ExtendedStatistic, but not both. + Statistic Statistic `type:"string" enum:"true"` + + // The value against which the specified statistic is compared. + // + // Threshold is a required field + Threshold *float64 `type:"double" required:"true"` + + // Sets how this alarm is to handle missing data points. If TreatMissingData + // is omitted, the default behavior of missing is used. For more information, + // see Configuring How CloudWatch Alarms Treats Missing Data (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data). + // + // Valid Values: breaching | notBreaching | ignore | missing + TreatMissingData *string `min:"1" type:"string"` + + // The unit of measure for the statistic. For example, the units for the Amazon + // EC2 NetworkIn metric are Bytes because NetworkIn tracks the number of bytes + // that an instance receives on all network interfaces. You can also specify + // a unit when you create a custom metric. Units help provide conceptual meaning + // to your data. Metric data points that specify a unit of measure, such as + // Percent, are aggregated separately. + // + // If you specify a unit, you must use a unit that is appropriate for the metric. + // Otherwise, the CloudWatch alarm can get stuck in the INSUFFICIENT DATA state. + Unit StandardUnit `type:"string" enum:"true"` +} + +// String returns the string representation +func (s PutMetricAlarmInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutMetricAlarmInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutMetricAlarmInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "PutMetricAlarmInput"} + + if s.AlarmName == nil { + invalidParams.Add(aws.NewErrParamRequired("AlarmName")) + } + if s.AlarmName != nil && len(*s.AlarmName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("AlarmName", 1)) + } + if len(s.ComparisonOperator) == 0 { + invalidParams.Add(aws.NewErrParamRequired("ComparisonOperator")) + } + if s.DatapointsToAlarm != nil && *s.DatapointsToAlarm < 1 { + invalidParams.Add(aws.NewErrParamMinValue("DatapointsToAlarm", 1)) + } + if s.EvaluateLowSampleCountPercentile != nil && len(*s.EvaluateLowSampleCountPercentile) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("EvaluateLowSampleCountPercentile", 1)) + } + + if s.EvaluationPeriods == nil { + invalidParams.Add(aws.NewErrParamRequired("EvaluationPeriods")) + } + if s.EvaluationPeriods != nil && *s.EvaluationPeriods < 1 { + invalidParams.Add(aws.NewErrParamMinValue("EvaluationPeriods", 1)) + } + + if s.MetricName == nil { + invalidParams.Add(aws.NewErrParamRequired("MetricName")) + } + if s.MetricName != nil && len(*s.MetricName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1)) + } + + if s.Namespace == nil { + invalidParams.Add(aws.NewErrParamRequired("Namespace")) + } + if s.Namespace != nil && len(*s.Namespace) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1)) + } + + if s.Period == nil { + invalidParams.Add(aws.NewErrParamRequired("Period")) + } + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(aws.NewErrParamMinValue("Period", 1)) + } + + if s.Threshold == nil { + invalidParams.Add(aws.NewErrParamRequired("Threshold")) + } + if s.TreatMissingData != nil && len(*s.TreatMissingData) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("TreatMissingData", 1)) + } + if s.Dimensions != nil { + for i, v := range s.Dimensions { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricAlarmOutput +type PutMetricAlarmOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s PutMetricAlarmOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutMetricAlarmOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s PutMetricAlarmOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricDataInput +type PutMetricDataInput struct { + _ struct{} `type:"structure"` + + // The data for the metric. + // + // MetricData is a required field + MetricData []MetricDatum `type:"list" required:"true"` + + // The namespace for the metric data. + // + // You cannot specify a namespace that begins with "AWS/". Namespaces that begin + // with "AWS/" are reserved for use by Amazon Web Services products. + // + // Namespace is a required field + Namespace *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s PutMetricDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutMetricDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutMetricDataInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "PutMetricDataInput"} + + if s.MetricData == nil { + invalidParams.Add(aws.NewErrParamRequired("MetricData")) + } + + if s.Namespace == nil { + invalidParams.Add(aws.NewErrParamRequired("Namespace")) + } + if s.Namespace != nil && len(*s.Namespace) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1)) + } + if s.MetricData != nil { + for i, v := range s.MetricData { + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "MetricData", i), err.(aws.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricDataOutput +type PutMetricDataOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s PutMetricDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutMetricDataOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s PutMetricDataOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/SetAlarmStateInput +type SetAlarmStateInput struct { + _ struct{} `type:"structure"` + + // The name for the alarm. This name must be unique within the AWS account. + // The maximum length is 255 characters. + // + // AlarmName is a required field + AlarmName *string `min:"1" type:"string" required:"true"` + + // The reason that this alarm is set to this specific state, in text format. + // + // StateReason is a required field + StateReason *string `type:"string" required:"true"` + + // The reason that this alarm is set to this specific state, in JSON format. + StateReasonData *string `type:"string"` + + // The value of the state. + // + // StateValue is a required field + StateValue StateValue `type:"string" required:"true" enum:"true"` +} + +// String returns the string representation +func (s SetAlarmStateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetAlarmStateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SetAlarmStateInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "SetAlarmStateInput"} + + if s.AlarmName == nil { + invalidParams.Add(aws.NewErrParamRequired("AlarmName")) + } + if s.AlarmName != nil && len(*s.AlarmName) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("AlarmName", 1)) + } + + if s.StateReason == nil { + invalidParams.Add(aws.NewErrParamRequired("StateReason")) + } + if len(s.StateValue) == 0 { + invalidParams.Add(aws.NewErrParamRequired("StateValue")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/SetAlarmStateOutput +type SetAlarmStateOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response +} + +// String returns the string representation +func (s SetAlarmStateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetAlarmStateOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s SetAlarmStateOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Represents a set of statistics that describes a specific metric. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/StatisticSet +type StatisticSet struct { + _ struct{} `type:"structure"` + + // The maximum value of the sample set. + // + // Maximum is a required field + Maximum *float64 `type:"double" required:"true"` + + // The minimum value of the sample set. + // + // Minimum is a required field + Minimum *float64 `type:"double" required:"true"` + + // The number of samples used for the statistic set. + // + // SampleCount is a required field + SampleCount *float64 `type:"double" required:"true"` + + // The sum of values for the sample set. + // + // Sum is a required field + Sum *float64 `type:"double" required:"true"` +} + +// String returns the string representation +func (s StatisticSet) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StatisticSet) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StatisticSet) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "StatisticSet"} + + if s.Maximum == nil { + invalidParams.Add(aws.NewErrParamRequired("Maximum")) + } + + if s.Minimum == nil { + invalidParams.Add(aws.NewErrParamRequired("Minimum")) + } + + if s.SampleCount == nil { + invalidParams.Add(aws.NewErrParamRequired("SampleCount")) + } + + if s.Sum == nil { + invalidParams.Add(aws.NewErrParamRequired("Sum")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type ComparisonOperator string + +// Enum values for ComparisonOperator +const ( + ComparisonOperatorGreaterThanOrEqualToThreshold ComparisonOperator = "GreaterThanOrEqualToThreshold" + ComparisonOperatorGreaterThanThreshold ComparisonOperator = "GreaterThanThreshold" + ComparisonOperatorLessThanThreshold ComparisonOperator = "LessThanThreshold" + ComparisonOperatorLessThanOrEqualToThreshold ComparisonOperator = "LessThanOrEqualToThreshold" +) + +func (enum ComparisonOperator) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum ComparisonOperator) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} + +type HistoryItemType string + +// Enum values for HistoryItemType +const ( + HistoryItemTypeConfigurationUpdate HistoryItemType = "ConfigurationUpdate" + HistoryItemTypeStateUpdate HistoryItemType = "StateUpdate" + HistoryItemTypeAction HistoryItemType = "Action" +) + +func (enum HistoryItemType) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum HistoryItemType) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} + +type ScanBy string + +// Enum values for ScanBy +const ( + ScanByTimestampDescending ScanBy = "TimestampDescending" + ScanByTimestampAscending ScanBy = "TimestampAscending" +) + +func (enum ScanBy) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum ScanBy) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} + +type StandardUnit string + +// Enum values for StandardUnit +const ( + StandardUnitSeconds StandardUnit = "Seconds" + StandardUnitMicroseconds StandardUnit = "Microseconds" + StandardUnitMilliseconds StandardUnit = "Milliseconds" + StandardUnitBytes StandardUnit = "Bytes" + StandardUnitKilobytes StandardUnit = "Kilobytes" + StandardUnitMegabytes StandardUnit = "Megabytes" + StandardUnitGigabytes StandardUnit = "Gigabytes" + StandardUnitTerabytes StandardUnit = "Terabytes" + StandardUnitBits StandardUnit = "Bits" + StandardUnitKilobits StandardUnit = "Kilobits" + StandardUnitMegabits StandardUnit = "Megabits" + StandardUnitGigabits StandardUnit = "Gigabits" + StandardUnitTerabits StandardUnit = "Terabits" + StandardUnitPercent StandardUnit = "Percent" + StandardUnitCount StandardUnit = "Count" + StandardUnitBytesSecond StandardUnit = "Bytes/Second" + StandardUnitKilobytesSecond StandardUnit = "Kilobytes/Second" + StandardUnitMegabytesSecond StandardUnit = "Megabytes/Second" + StandardUnitGigabytesSecond StandardUnit = "Gigabytes/Second" + StandardUnitTerabytesSecond StandardUnit = "Terabytes/Second" + StandardUnitBitsSecond StandardUnit = "Bits/Second" + StandardUnitKilobitsSecond StandardUnit = "Kilobits/Second" + StandardUnitMegabitsSecond StandardUnit = "Megabits/Second" + StandardUnitGigabitsSecond StandardUnit = "Gigabits/Second" + StandardUnitTerabitsSecond StandardUnit = "Terabits/Second" + StandardUnitCountSecond StandardUnit = "Count/Second" + StandardUnitNone StandardUnit = "None" +) + +func (enum StandardUnit) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum StandardUnit) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} + +type StateValue string + +// Enum values for StateValue +const ( + StateValueOk StateValue = "OK" + StateValueAlarm StateValue = "ALARM" + StateValueInsufficientData StateValue = "INSUFFICIENT_DATA" +) + +func (enum StateValue) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum StateValue) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} + +type Statistic string + +// Enum values for Statistic +const ( + StatisticSampleCount Statistic = "SampleCount" + StatisticAverage Statistic = "Average" + StatisticSum Statistic = "Sum" + StatisticMinimum Statistic = "Minimum" + StatisticMaximum Statistic = "Maximum" +) + +func (enum Statistic) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum Statistic) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} + +type StatusCode string + +// Enum values for StatusCode +const ( + StatusCodeComplete StatusCode = "Complete" + StatusCodeInternalError StatusCode = "InternalError" + StatusCodePartialData StatusCode = "PartialData" +) + +func (enum StatusCode) MarshalValue() (string, error) { + return string(enum), nil +} + +func (enum StatusCode) MarshalValueBuf(b []byte) ([]byte, error) { + b = b[0:0] + return append(b, enum...), nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/cloudwatchiface/interface.go b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/cloudwatchiface/interface.go new file mode 100644 index 000000000..f262750ba --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/cloudwatchiface/interface.go @@ -0,0 +1,102 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package cloudwatchiface provides an interface to enable mocking the Amazon CloudWatch service client +// for testing your code. +// +// It is important to note that this interface will have breaking changes +// when the service model is updated and adds new API operations, paginators, +// and waiters. +package cloudwatchiface + +import ( + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/cloudwatch" +) + +// CloudWatchAPI provides an interface to enable mocking the +// cloudwatch.CloudWatch service client's API operation, +// paginators, and waiters. This make unit testing your code that calls out +// to the SDK's service client's calls easier. +// +// The best way to use this interface is so the SDK's service client's calls +// can be stubbed out for unit testing your code with the SDK without needing +// to inject custom request handlers into the SDK's request pipeline. +// +// // myFunc uses an SDK service client to make a request to +// // Amazon CloudWatch. +// func myFunc(svc cloudwatchiface.CloudWatchAPI) bool { +// // Make svc.DeleteAlarms request +// } +// +// func main() { +// cfg, err := external.LoadDefaultAWSConfig() +// if err != nil { +// panic("failed to load config, " + err.Error()) +// } +// +// svc := cloudwatch.New(cfg) +// +// myFunc(svc) +// } +// +// In your _test.go file: +// +// // Define a mock struct to be used in your unit tests of myFunc. +// type mockCloudWatchClient struct { +// cloudwatchiface.CloudWatchAPI +// } +// func (m *mockCloudWatchClient) DeleteAlarms(input *cloudwatch.DeleteAlarmsInput) (*cloudwatch.DeleteAlarmsOutput, error) { +// // mock response/functionality +// } +// +// func TestMyFunc(t *testing.T) { +// // Setup Test +// mockSvc := &mockCloudWatchClient{} +// +// myfunc(mockSvc) +// +// // Verify myFunc's functionality +// } +// +// It is important to note that this interface will have breaking changes +// when the service model is updated and adds new API operations, paginators, +// and waiters. Its suggested to use the pattern above for testing, or using +// tooling to generate mocks to satisfy the interfaces. +type CloudWatchAPI interface { + DeleteAlarmsRequest(*cloudwatch.DeleteAlarmsInput) cloudwatch.DeleteAlarmsRequest + + DeleteDashboardsRequest(*cloudwatch.DeleteDashboardsInput) cloudwatch.DeleteDashboardsRequest + + DescribeAlarmHistoryRequest(*cloudwatch.DescribeAlarmHistoryInput) cloudwatch.DescribeAlarmHistoryRequest + + DescribeAlarmsRequest(*cloudwatch.DescribeAlarmsInput) cloudwatch.DescribeAlarmsRequest + + DescribeAlarmsForMetricRequest(*cloudwatch.DescribeAlarmsForMetricInput) cloudwatch.DescribeAlarmsForMetricRequest + + DisableAlarmActionsRequest(*cloudwatch.DisableAlarmActionsInput) cloudwatch.DisableAlarmActionsRequest + + EnableAlarmActionsRequest(*cloudwatch.EnableAlarmActionsInput) cloudwatch.EnableAlarmActionsRequest + + GetDashboardRequest(*cloudwatch.GetDashboardInput) cloudwatch.GetDashboardRequest + + GetMetricDataRequest(*cloudwatch.GetMetricDataInput) cloudwatch.GetMetricDataRequest + + GetMetricStatisticsRequest(*cloudwatch.GetMetricStatisticsInput) cloudwatch.GetMetricStatisticsRequest + + ListDashboardsRequest(*cloudwatch.ListDashboardsInput) cloudwatch.ListDashboardsRequest + + ListMetricsRequest(*cloudwatch.ListMetricsInput) cloudwatch.ListMetricsRequest + + PutDashboardRequest(*cloudwatch.PutDashboardInput) cloudwatch.PutDashboardRequest + + PutMetricAlarmRequest(*cloudwatch.PutMetricAlarmInput) cloudwatch.PutMetricAlarmRequest + + PutMetricDataRequest(*cloudwatch.PutMetricDataInput) cloudwatch.PutMetricDataRequest + + SetAlarmStateRequest(*cloudwatch.SetAlarmStateInput) cloudwatch.SetAlarmStateRequest + + WaitUntilAlarmExists(*cloudwatch.DescribeAlarmsInput) error + WaitUntilAlarmExistsWithContext(aws.Context, *cloudwatch.DescribeAlarmsInput, ...aws.WaiterOption) error +} + +var _ CloudWatchAPI = (*cloudwatch.CloudWatch)(nil) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/doc.go new file mode 100644 index 000000000..d3cb024a1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/doc.go @@ -0,0 +1,42 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package cloudwatch provides the client and types for making API +// requests to Amazon CloudWatch. +// +// Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the +// applications you run on AWS in real time. You can use CloudWatch to collect +// and track metrics, which are the variables you want to measure for your resources +// and applications. +// +// CloudWatch alarms send notifications or automatically change the resources +// you are monitoring based on rules that you define. For example, you can monitor +// the CPU usage and disk reads and writes of your Amazon EC2 instances. Then, +// use this data to determine whether you should launch additional instances +// to handle increased load. You can also use this data to stop under-used instances +// to save money. +// +// In addition to monitoring the built-in metrics that come with AWS, you can +// monitor your own custom metrics. With CloudWatch, you gain system-wide visibility +// into resource utilization, application performance, and operational health. +// +// See https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01 for more information on this service. +// +// See cloudwatch package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/cloudwatch/ +// +// Using the Client +// +// To Amazon CloudWatch with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon CloudWatch client CloudWatch for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/cloudwatch/#New +package cloudwatch diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/errors.go new file mode 100644 index 000000000..0029aa38f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/errors.go @@ -0,0 +1,66 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package cloudwatch + +const ( + + // ErrCodeDashboardInvalidInputError for service response error code + // "InvalidParameterInput". + // + // Some part of the dashboard data is invalid. + ErrCodeDashboardInvalidInputError = "InvalidParameterInput" + + // ErrCodeDashboardNotFoundError for service response error code + // "ResourceNotFound". + // + // The specified dashboard does not exist. + ErrCodeDashboardNotFoundError = "ResourceNotFound" + + // ErrCodeInternalServiceFault for service response error code + // "InternalServiceError". + // + // Request processing has failed due to some unknown error, exception, or failure. + ErrCodeInternalServiceFault = "InternalServiceError" + + // ErrCodeInvalidFormatFault for service response error code + // "InvalidFormat". + // + // Data was not syntactically valid JSON. + ErrCodeInvalidFormatFault = "InvalidFormat" + + // ErrCodeInvalidNextToken for service response error code + // "InvalidNextToken". + // + // The next token specified is invalid. + ErrCodeInvalidNextToken = "InvalidNextToken" + + // ErrCodeInvalidParameterCombinationException for service response error code + // "InvalidParameterCombination". + // + // Parameters were used together that cannot be used together. + ErrCodeInvalidParameterCombinationException = "InvalidParameterCombination" + + // ErrCodeInvalidParameterValueException for service response error code + // "InvalidParameterValue". + // + // The value of an input parameter is bad or out-of-range. + ErrCodeInvalidParameterValueException = "InvalidParameterValue" + + // ErrCodeLimitExceededFault for service response error code + // "LimitExceeded". + // + // The quota for alarms for this customer has already been reached. + ErrCodeLimitExceededFault = "LimitExceeded" + + // ErrCodeMissingRequiredParameterException for service response error code + // "MissingParameter". + // + // An input parameter that is required is missing. + ErrCodeMissingRequiredParameterException = "MissingParameter" + + // ErrCodeResourceNotFound for service response error code + // "ResourceNotFound". + // + // The named resource does not exist. + ErrCodeResourceNotFound = "ResourceNotFound" +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/service.go b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/service.go new file mode 100644 index 000000000..adb853d6a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/service.go @@ -0,0 +1,80 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package cloudwatch + +import ( + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/private/protocol/query" +) + +// CloudWatch provides the API operation methods for making requests to +// Amazon CloudWatch. See this package's package overview docs +// for details on the service. +// +// CloudWatch methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type CloudWatch struct { + *aws.Client +} + +// Used for custom client initialization logic +var initClient func(*CloudWatch) + +// Used for custom request initialization logic +var initRequest func(*CloudWatch, *aws.Request) + +// Service information constants +const ( + ServiceName = "monitoring" // Service endpoint prefix API calls made to. + EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. +) + +// New creates a new instance of the CloudWatch client with a config. +// +// Example: +// // Create a CloudWatch client from just a config. +// svc := cloudwatch.New(myConfig) +func New(config aws.Config) *CloudWatch { + var signingName string + signingRegion := config.Region + + svc := &CloudWatch{ + Client: aws.NewClient( + config, + aws.Metadata{ + ServiceName: ServiceName, + SigningName: signingName, + SigningRegion: signingRegion, + APIVersion: "2010-08-01", + }, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(query.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc) + } + + return svc +} + +// newRequest creates a new request for a CloudWatch operation and runs any +// custom request initialization. +func (c *CloudWatch) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(c, req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/waiters.go b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/waiters.go new file mode 100644 index 000000000..1b2fb9dec --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/cloudwatch/waiters.go @@ -0,0 +1,55 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package cloudwatch + +import ( + "time" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +// WaitUntilAlarmExists uses the CloudWatch API operation +// DescribeAlarms to wait for a condition to be met before returning. +// If the condition is not met within the max attempt window, an error will +// be returned. +func (c *CloudWatch) WaitUntilAlarmExists(input *DescribeAlarmsInput) error { + return c.WaitUntilAlarmExistsWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilAlarmExistsWithContext is an extended version of WaitUntilAlarmExists. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatch) WaitUntilAlarmExistsWithContext(ctx aws.Context, input *DescribeAlarmsInput, opts ...aws.WaiterOption) error { + w := aws.Waiter{ + Name: "WaitUntilAlarmExists", + MaxAttempts: 40, + Delay: aws.ConstantWaiterDelay(5 * time.Second), + Acceptors: []aws.WaiterAcceptor{ + { + State: aws.SuccessWaiterState, + Matcher: aws.PathWaiterMatch, Argument: "length(MetricAlarms[]) > `0`", + Expected: true, + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []aws.Option) (*aws.Request, error) { + var inCpy *DescribeAlarmsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req := c.DescribeAlarmsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req.Request, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt @@ -0,0 +1,202 @@ + + 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/github.com/aws/aws-sdk-go-v2/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api.go new file mode 100644 index 000000000..fad7e8b60 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api.go @@ -0,0 +1,1832 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +import ( + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/internal/awsutil" +) + +const opAssumeRole = "AssumeRole" + +// AssumeRoleRequest is a API request type for the AssumeRole API operation. +type AssumeRoleRequest struct { + *aws.Request + Input *AssumeRoleInput + Copy func(*AssumeRoleInput) AssumeRoleRequest +} + +// Send marshals and sends the AssumeRole API request. +func (r AssumeRoleRequest) Send() (*AssumeRoleOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*AssumeRoleOutput), nil +} + +// AssumeRoleRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Returns a set of temporary security credentials (consisting of an access +// key ID, a secret access key, and a security token) that you can use to access +// AWS resources that you might not normally have access to. Typically, you +// use AssumeRole for cross-account access or federation. For a comparison of +// AssumeRole with the other APIs that produce temporary credentials, see Requesting +// Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// Important: You cannot call AssumeRole by using AWS root account credentials; +// access is denied. You must use credentials for an IAM user or an IAM role +// to call AssumeRole. +// +// For cross-account access, imagine that you own multiple accounts and need +// to access resources in each account. You could create long-term credentials +// in each account to access those resources. However, managing all those credentials +// and remembering which one can access which account can be time consuming. +// Instead, you can create one set of long-term credentials in one account and +// then use temporary security credentials to access all the other accounts +// by assuming roles in those accounts. For more information about roles, see +// IAM Roles (Delegation and Federation) (http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html) +// in the IAM User Guide. +// +// For federation, you can, for example, grant single sign-on access to the +// AWS Management Console. If you already have an identity and authentication +// system in your corporate network, you don't have to recreate user identities +// in AWS in order to grant those user identities access to AWS. Instead, after +// a user has been authenticated, you call AssumeRole (and specify the role +// with the appropriate permissions) to get temporary security credentials for +// that user. With those temporary security credentials, you construct a sign-in +// URL that users can use to access the console. For more information, see Common +// Scenarios for Temporary Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html#sts-introduction) +// in the IAM User Guide. +// +// By default, the temporary security credentials created by AssumeRole last +// for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. You can provide a value from 900 +// seconds (15 minutes) up to the maximum session duration setting for the role. +// This setting can have a value from 1 hour to 12 hours. To learn how to view +// the maximum value for your role, see View the Maximum Session Duration Setting +// for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI operations but +// does not apply when you use those operations to create a console URL. For +// more information, see Using IAM Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRole can be used to make +// API calls to any AWS service with the following exception: you cannot call +// the STS service's GetFederationToken or GetSessionToken APIs. +// +// Optionally, you can pass an IAM access policy to this operation. If you choose +// not to pass a policy, the temporary security credentials that are 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) +// in the IAM User Guide. +// +// To assume a role, your AWS account must be trusted by the role. The trust +// relationship is defined in the role's trust policy when the role is created. +// That trust policy states which accounts are allowed to delegate access to +// this account's role. +// +// The user who wants to access the role must also have permissions delegated +// from the role's administrator. If the user is in a different account than +// the role, then the user's administrator must attach a policy that allows +// the user to call AssumeRole on the ARN of the role in the other account. +// If the user is in the same account as the role, then you can either attach +// a policy to the user (identical to the previous different account user), +// or you can add the user as a principal directly in the role's trust policy. +// In this case, the trust policy acts as the only resource-based policy in +// IAM, and users in the same account as the role do not need explicit permission +// to assume the role. For more information about trust policies and resource-based +// policies, see IAM Policies (http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) +// in the IAM User Guide. +// +// Using MFA with AssumeRole +// +// You can optionally include multi-factor authentication (MFA) information +// when you call AssumeRole. This is useful for cross-account scenarios in which +// you want to make sure that the user who is assuming the role has been authenticated +// using an AWS MFA device. In that scenario, the trust policy of the role being +// assumed includes a condition that tests for MFA authentication; if the caller +// does not include valid MFA information, the request to assume the role is +// denied. The condition in a trust policy that tests for MFA authentication +// might look like the following example. +// +// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}} +// +// For more information, see Configuring MFA-Protected API Access (http://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html) +// in the IAM User Guide guide. +// +// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode +// parameters. The SerialNumber value identifies the user's hardware or virtual +// MFA device. The TokenCode is the time-based one-time password (TOTP) that +// the MFA devices produces. +// +// // Example sending a request using the AssumeRoleRequest method. +// req := client.AssumeRoleRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) AssumeRoleRequest { + op := &aws.Operation{ + Name: opAssumeRole, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleInput{} + } + + output := &AssumeRoleOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return AssumeRoleRequest{Request: req, Input: input, Copy: c.AssumeRoleRequest} +} + +const opAssumeRoleWithSAML = "AssumeRoleWithSAML" + +// AssumeRoleWithSAMLRequest is a API request type for the AssumeRoleWithSAML API operation. +type AssumeRoleWithSAMLRequest struct { + *aws.Request + Input *AssumeRoleWithSAMLInput + Copy func(*AssumeRoleWithSAMLInput) AssumeRoleWithSAMLRequest +} + +// Send marshals and sends the AssumeRoleWithSAML API request. +func (r AssumeRoleWithSAMLRequest) Send() (*AssumeRoleWithSAMLOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*AssumeRoleWithSAMLOutput), nil +} + +// AssumeRoleWithSAMLRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Returns a set of temporary security credentials for users who have been authenticated +// via a SAML authentication response. This operation provides a mechanism for +// tying an enterprise identity store or directory to role-based AWS access +// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML +// with the other APIs that produce temporary credentials, see Requesting Temporary +// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this operation consist of +// an access key ID, a secret access key, and a security token. Applications +// can use these temporary security credentials to sign calls to AWS services. +// +// By default, the temporary security credentials created by AssumeRoleWithSAML +// last for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. Your role session lasts for the +// duration that you specify, or until the time specified in the SAML authentication +// response's SessionNotOnOrAfter value, whichever is shorter. You can provide +// a DurationSeconds value from 900 seconds (15 minutes) up to the maximum session +// duration setting for the role. This setting can have a value from 1 hour +// to 12 hours. To learn how to view the maximum value for your role, see View +// the Maximum Session Duration Setting for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI operations but +// does not apply when you use those operations to create a console URL. For +// more information, see Using IAM Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRoleWithSAML can be used +// to make API calls to any AWS service with the following exception: you cannot +// call the STS service's GetFederationToken or GetSessionToken APIs. +// +// Optionally, you can pass an IAM access policy to this operation. If you choose +// not to pass a policy, the temporary security credentials that are 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 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 your +// SAML identity provider (IdP) to issue the claims required by AWS. Additionally, +// you must use AWS Identity and Access Management (IAM) to create a SAML provider +// entity in your AWS account that represents your identity provider, and create +// an IAM role that specifies this SAML provider in its trust policy. +// +// Calling AssumeRoleWithSAML does not require the use of AWS security credentials. +// The identity of the caller is validated by using keys in the metadata document +// that is uploaded for the SAML provider entity for your identity provider. +// +// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail +// logs. The entry includes the value in the NameID element of the SAML assertion. +// We recommend that you use a NameIDType that is not associated with any personally +// identifiable information (PII). For example, you could instead use the Persistent +// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent). +// +// For more information, see the following resources: +// +// * About SAML 2.0-based Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) +// in the IAM User Guide. +// +// * Creating SAML Identity Providers (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) +// in the IAM User Guide. +// +// * Configuring a Relying Party and Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html) +// in the IAM User Guide. +// +// * Creating a Role for SAML 2.0 Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html) +// in the IAM User Guide. +// +// // Example sending a request using the AssumeRoleWithSAMLRequest method. +// req := client.AssumeRoleWithSAMLRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) AssumeRoleWithSAMLRequest { + op := &aws.Operation{ + Name: opAssumeRoleWithSAML, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithSAMLInput{} + } + + output := &AssumeRoleWithSAMLOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return AssumeRoleWithSAMLRequest{Request: req, Input: input, Copy: c.AssumeRoleWithSAMLRequest} +} + +const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity" + +// AssumeRoleWithWebIdentityRequest is a API request type for the AssumeRoleWithWebIdentity API operation. +type AssumeRoleWithWebIdentityRequest struct { + *aws.Request + Input *AssumeRoleWithWebIdentityInput + Copy func(*AssumeRoleWithWebIdentityInput) AssumeRoleWithWebIdentityRequest +} + +// Send marshals and sends the AssumeRoleWithWebIdentity API request. +func (r AssumeRoleWithWebIdentityRequest) Send() (*AssumeRoleWithWebIdentityOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*AssumeRoleWithWebIdentityOutput), nil +} + +// AssumeRoleWithWebIdentityRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Returns a set of temporary security credentials for users who have been authenticated +// in a mobile or web application with a web identity provider, such as Amazon +// Cognito, Login with Amazon, Facebook, Google, or any OpenID Connect-compatible +// identity provider. +// +// For mobile applications, we recommend that you use Amazon Cognito. You can +// use Amazon Cognito with the AWS SDK for iOS (http://aws.amazon.com/sdkforios/) +// and the AWS SDK for Android (http://aws.amazon.com/sdkforandroid/) to uniquely +// identify a user and supply the user with a consistent identity throughout +// the lifetime of an application. +// +// To learn more about Amazon Cognito, see Amazon Cognito Overview (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840) +// in the AWS SDK for Android Developer Guide guide and Amazon Cognito Overview +// (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664) +// in the AWS SDK for iOS Developer Guide. +// +// Calling AssumeRoleWithWebIdentity does not require the use of AWS security +// credentials. Therefore, you can distribute an application (for example, on +// mobile devices) that requests temporary security credentials without including +// long-term AWS credentials in the application, and without deploying server-based +// proxy services that use long-term AWS credentials. Instead, the identity +// of the caller is validated by using a token from the web identity provider. +// For a comparison of AssumeRoleWithWebIdentity with the other APIs that produce +// temporary credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this API consist of an access +// key ID, a secret access key, and a security token. Applications can use these +// temporary security credentials to sign calls to AWS service APIs. +// +// By default, the temporary security credentials created by AssumeRoleWithWebIdentity +// last for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. You can provide a value from 900 +// seconds (15 minutes) up to the maximum session duration setting for the role. +// This setting can have a value from 1 hour to 12 hours. To learn how to view +// the maximum value for your role, see View the Maximum Session Duration Setting +// for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI operations but +// does not apply when you use those operations to create a console URL. For +// more information, see Using IAM Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRoleWithWebIdentity can +// be used to make API calls to any AWS service with the following exception: +// you cannot call the STS service's GetFederationToken or GetSessionToken APIs. +// +// Optionally, you can pass an IAM access policy to this operation. If you choose +// not to pass a policy, the temporary security credentials that are 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) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithWebIdentity, you must have +// an identity token from a supported identity provider and create a role that +// the application can assume. The role that your application assumes must trust +// the identity provider that is associated with the identity token. In other +// words, the identity provider must be specified in the role's trust policy. +// +// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail +// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims) +// of the provided Web Identity Token. We recommend that you avoid using any +// personally identifiable information (PII) in this field. For example, you +// could instead use a GUID or a pairwise identifier, as suggested in the OIDC +// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes). +// +// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity +// API, see the following resources: +// +// * Using Web Identity Federation APIs for Mobile Apps (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html) +// and Federation Through a Web-based Identity Provider (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// +// * Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html). +// This interactive website lets you walk through the process of authenticating +// via Login with Amazon, Facebook, or Google, getting temporary security +// credentials, and then using those credentials to make a request to AWS. +// +// +// * AWS SDK for iOS (http://aws.amazon.com/sdkforios/) and AWS SDK for Android +// (http://aws.amazon.com/sdkforandroid/). These toolkits contain sample +// apps that show how to invoke the identity providers, and then how to use +// the information from these providers to get and use temporary security +// credentials. +// +// * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications). +// This article discusses web identity federation and shows an example of +// how to use web identity federation to get access to content in Amazon +// S3. +// +// // Example sending a request using the AssumeRoleWithWebIdentityRequest method. +// req := client.AssumeRoleWithWebIdentityRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) AssumeRoleWithWebIdentityRequest { + op := &aws.Operation{ + Name: opAssumeRoleWithWebIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithWebIdentityInput{} + } + + output := &AssumeRoleWithWebIdentityOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return AssumeRoleWithWebIdentityRequest{Request: req, Input: input, Copy: c.AssumeRoleWithWebIdentityRequest} +} + +const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage" + +// DecodeAuthorizationMessageRequest is a API request type for the DecodeAuthorizationMessage API operation. +type DecodeAuthorizationMessageRequest struct { + *aws.Request + Input *DecodeAuthorizationMessageInput + Copy func(*DecodeAuthorizationMessageInput) DecodeAuthorizationMessageRequest +} + +// Send marshals and sends the DecodeAuthorizationMessage API request. +func (r DecodeAuthorizationMessageRequest) Send() (*DecodeAuthorizationMessageOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*DecodeAuthorizationMessageOutput), nil +} + +// DecodeAuthorizationMessageRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Decodes additional information about the authorization status of a request +// from an encoded message returned in response to an AWS request. +// +// For example, if a user is not authorized to perform an action that he or +// she has requested, the request returns a Client.UnauthorizedOperation response +// (an HTTP 403 response). Some AWS actions additionally return an encoded message +// that can provide details about this authorization failure. +// +// Only certain AWS actions return an encoded authorization message. The documentation +// for an individual action indicates whether that action returns an encoded +// message in addition to returning an HTTP code. +// +// The message is encoded because the details of the authorization status can +// constitute privileged information that the user who requested the action +// should not see. To decode an authorization status message, a user must be +// granted permissions via an IAM policy to request the DecodeAuthorizationMessage +// (sts:DecodeAuthorizationMessage) action. +// +// The decoded message includes the following type of information: +// +// * Whether the request was denied due to an explicit deny or due to the +// absence of an explicit allow. For more information, see Determining Whether +// a Request is Allowed or Denied (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow) +// in the IAM User Guide. +// +// * The principal who made the request. +// +// * The requested action. +// +// * The requested resource. +// +// * The values of condition keys in the context of the user's request. +// +// // Example sending a request using the DecodeAuthorizationMessageRequest method. +// req := client.DecodeAuthorizationMessageRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) DecodeAuthorizationMessageRequest { + op := &aws.Operation{ + Name: opDecodeAuthorizationMessage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DecodeAuthorizationMessageInput{} + } + + output := &DecodeAuthorizationMessageOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return DecodeAuthorizationMessageRequest{Request: req, Input: input, Copy: c.DecodeAuthorizationMessageRequest} +} + +const opGetCallerIdentity = "GetCallerIdentity" + +// GetCallerIdentityRequest is a API request type for the GetCallerIdentity API operation. +type GetCallerIdentityRequest struct { + *aws.Request + Input *GetCallerIdentityInput + Copy func(*GetCallerIdentityInput) GetCallerIdentityRequest +} + +// Send marshals and sends the GetCallerIdentity API request. +func (r GetCallerIdentityRequest) Send() (*GetCallerIdentityOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*GetCallerIdentityOutput), nil +} + +// GetCallerIdentityRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Returns details about the IAM identity whose credentials are used to call +// the API. +// +// // Example sending a request using the GetCallerIdentityRequest method. +// req := client.GetCallerIdentityRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) GetCallerIdentityRequest { + op := &aws.Operation{ + Name: opGetCallerIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetCallerIdentityInput{} + } + + output := &GetCallerIdentityOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return GetCallerIdentityRequest{Request: req, Input: input, Copy: c.GetCallerIdentityRequest} +} + +const opGetFederationToken = "GetFederationToken" + +// GetFederationTokenRequest is a API request type for the GetFederationToken API operation. +type GetFederationTokenRequest struct { + *aws.Request + Input *GetFederationTokenInput + Copy func(*GetFederationTokenInput) GetFederationTokenRequest +} + +// Send marshals and sends the GetFederationToken API request. +func (r GetFederationTokenRequest) Send() (*GetFederationTokenOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*GetFederationTokenOutput), nil +} + +// GetFederationTokenRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Returns a set of temporary security credentials (consisting of an access +// key ID, a secret access key, and a security token) for a federated user. +// A typical use is in a proxy application that gets temporary security credentials +// on behalf of distributed applications inside a corporate network. Because +// you must call the GetFederationToken action using the long-term security +// credentials of an IAM user, this call is appropriate in contexts where those +// credentials can be safely stored, usually in a server-based application. +// For a comparison of GetFederationToken with the other APIs that produce temporary +// credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// If you are creating a mobile-based or browser-based app that can authenticate +// users using a web identity provider like Login with Amazon, Facebook, Google, +// or an OpenID Connect-compatible identity provider, we recommend that you +// use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity. +// For more information, see Federation Through a Web-based Identity Provider +// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// The GetFederationToken action must be called by using the long-term AWS security +// credentials of an IAM user. You can also call GetFederationToken using the +// security credentials of an AWS root account, but we do not recommended it. +// Instead, we recommend that you create an IAM user for the purpose of the +// proxy application and then attach a policy to the IAM user that limits federated +// users to only the actions and resources that they need access to. For more +// information, see IAM Best Practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) +// in the IAM User Guide. +// +// The temporary security credentials that are obtained by using the long-term +// credentials of an IAM user are valid for the specified duration, from 900 +// seconds (15 minutes) up to a maximium of 129600 seconds (36 hours). The default +// is 43200 seconds (12 hours). Temporary credentials that are obtained by using +// AWS root account credentials have a maximum duration of 3600 seconds (1 hour). +// +// The temporary security credentials created by GetFederationToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// * You cannot use these credentials to call any IAM APIs. +// +// * You cannot call any STS APIs except GetCallerIdentity. +// +// Permissions +// +// The permissions for the temporary security credentials returned by GetFederationToken +// are determined by a combination of the following: +// +// * The policy or policies that are attached to the IAM user whose credentials +// are used to call GetFederationToken. +// +// * The policy that is passed as a parameter in the call. +// +// The passed policy is attached to the temporary security credentials that +// result from the GetFederationToken API call--that is, to the federated user. +// When the federated user makes an AWS request, AWS evaluates the policy attached +// to the federated user in combination with the policy or policies attached +// to the IAM user whose credentials were used to call GetFederationToken. AWS +// allows the federated user's request only when both the federated user and +// the IAM user are explicitly allowed to perform the requested action. The +// passed policy cannot grant more permissions than those that are defined in +// the IAM user policy. +// +// A typical use case is that the permissions of the IAM user whose credentials +// are used to call GetFederationToken are designed to allow access to all the +// actions and resources that any federated user will need. Then, for individual +// users, you pass a policy to the operation that scopes down the permissions +// to a level that's appropriate to that individual user, using a policy that +// allows only a subset of permissions that are granted to the IAM user. +// +// If you do not pass a policy, the resulting temporary security credentials +// have no effective permissions. The only exception is when the temporary security +// credentials are used to access a resource that has a resource-based policy +// that specifically allows the federated user to access the resource. +// +// For more information about how permissions work, see Permissions for GetFederationToken +// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html). +// For information about using GetFederationToken to create temporary security +// credentials, see GetFederationToken—Federation Through a Custom Identity +// Broker (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken). +// +// // Example sending a request using the GetFederationTokenRequest method. +// req := client.GetFederationTokenRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) GetFederationTokenRequest { + op := &aws.Operation{ + Name: opGetFederationToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetFederationTokenInput{} + } + + output := &GetFederationTokenOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return GetFederationTokenRequest{Request: req, Input: input, Copy: c.GetFederationTokenRequest} +} + +const opGetSessionToken = "GetSessionToken" + +// GetSessionTokenRequest is a API request type for the GetSessionToken API operation. +type GetSessionTokenRequest struct { + *aws.Request + Input *GetSessionTokenInput + Copy func(*GetSessionTokenInput) GetSessionTokenRequest +} + +// Send marshals and sends the GetSessionToken API request. +func (r GetSessionTokenRequest) Send() (*GetSessionTokenOutput, error) { + err := r.Request.Send() + if err != nil { + return nil, err + } + + return r.Request.Data.(*GetSessionTokenOutput), nil +} + +// GetSessionTokenRequest returns a request value for making API operation for +// AWS Security Token Service. +// +// Returns a set of temporary credentials for an AWS account or IAM user. The +// credentials consist of an access key ID, a secret access key, and a security +// token. Typically, you use GetSessionToken if you want to use MFA to protect +// programmatic calls to specific AWS APIs like Amazon EC2 StopInstances. MFA-enabled +// IAM users would need to call GetSessionToken and submit an MFA code that +// is associated with their MFA device. Using the temporary security credentials +// that are returned from the call, IAM users can then make programmatic calls +// to APIs that require MFA authentication. If you do not supply a correct MFA +// code, then the API returns an access denied error. For a comparison of GetSessionToken +// with the other APIs that produce temporary credentials, see Requesting Temporary +// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The GetSessionToken action must be called by using the long-term AWS security +// credentials of the AWS account or an IAM user. Credentials that are created +// by IAM users are valid for the duration that you specify, from 900 seconds +// (15 minutes) up to a maximum of 129600 seconds (36 hours), with a default +// of 43200 seconds (12 hours); credentials that are created by using account +// credentials can range from 900 seconds (15 minutes) up to a maximum of 3600 +// seconds (1 hour), with a default of 1 hour. +// +// The temporary security credentials created by GetSessionToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// * You cannot call any IAM APIs unless MFA authentication information is +// included in the request. +// +// * You cannot call any STS API exceptAssumeRole or GetCallerIdentity. +// +// We recommend that you do not call GetSessionToken with root account credentials. +// Instead, follow our best practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users) +// by creating one or more IAM users, giving them the necessary permissions, +// and using IAM users for everyday interaction with AWS. +// +// The permissions associated with the temporary security credentials returned +// by GetSessionToken are based on the permissions associated with account or +// IAM user whose credentials are used to call the action. If GetSessionToken +// is called using root account credentials, the temporary credentials have +// root account permissions. Similarly, if GetSessionToken is called using the +// credentials of an IAM user, the temporary credentials have the same permissions +// as the IAM user. +// +// For more information about using GetSessionToken to create temporary credentials, +// go to Temporary Credentials for Users in Untrusted Environments (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken) +// in the IAM User Guide. +// +// // Example sending a request using the GetSessionTokenRequest method. +// req := client.GetSessionTokenRequest(params) +// resp, err := req.Send() +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) GetSessionTokenRequest { + op := &aws.Operation{ + Name: opGetSessionToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetSessionTokenInput{} + } + + output := &GetSessionTokenOutput{} + req := c.newRequest(op, input, output) + output.responseMetadata = aws.Response{Request: req} + + return GetSessionTokenRequest{Request: req, Input: input, Copy: c.GetSessionTokenRequest} +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest +type AssumeRoleInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) up to the maximum session duration setting for the role. + // This setting can have a value from 1 hour to 12 hours. If you specify a value + // higher than this setting, the operation fails. For example, if you specify + // a session duration of 12 hours, but your administrator set the maximum session + // duration to 6 hours, your operation fails. To learn how to view the maximum + // value for your role, see View the Maximum Session Duration Setting for a + // Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter 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. 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 + // their customers' accounts. For each role that the third party can assume, + // they should instruct their customers to ensure the role's trust policy checks + // for the external ID that the third party generated. Each time the third party + // assumes the role, they should pass the customer's external ID. The external + // ID is useful in order to help third parties bind a role to the customer who + // created it. For more information about the external ID, see How to Use an + // External ID When Granting Access to Your AWS Resources to a Third Party (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) + // in the IAM User Guide. + // + // The regex used to validated this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric 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. + // + // This parameter is optional. If you pass a policy, the temporary security + // credentials that are returned by the operation have the permissions that + // are allowed by both (the intersection of) 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) + // in the IAM User Guide. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // 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 `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) of the role to assume. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. + // + // Use the role session name to uniquely identify a session when the same role + // is assumed by different principals or for different reasons. In cross-account + // scenarios, the role session name is visible to, and can be logged by the + // account that owns the role. The role session name is also used in the ARN + // of the assumed role principal. This means that subsequent cross-account API + // requests using the temporary security credentials will expose the role session + // name to the external account in their CloudTrail logs. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // RoleSessionName is a required field + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The identification number of the MFA device that is associated with the user + // 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). + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric 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 + // 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. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "AssumeRoleInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(aws.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.ExternalId != nil && len(*s.ExternalId) < 2 { + invalidParams.Add(aws.NewErrParamMinLen("ExternalId", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Policy", 1)) + } + + if s.RoleArn == nil { + invalidParams.Add(aws.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(aws.NewErrParamMinLen("RoleArn", 20)) + } + + if s.RoleSessionName == nil { + invalidParams.Add(aws.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(aws.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(aws.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(aws.NewErrParamMinLen("TokenCode", 6)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful AssumeRole request, including temporary +// AWS credentials that can be used to make AWS requests. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse +type AssumeRoleOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. We + // strongly recommend that you make no assumptions about the maximum size. As + // of this writing, the typical size is less than 4096 bytes, but that can vary. + // Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s AssumeRoleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s AssumeRoleOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest +type AssumeRoleWithSAMLInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. Your role session lasts for + // the duration that you specify for the DurationSeconds parameter, or until + // the time specified in the SAML authentication response's SessionNotOnOrAfter + // value, whichever is shorter. You can provide a DurationSeconds value from + // 900 seconds (15 minutes) up to the maximum session duration setting for the + // role. This setting can have a value from 1 hour to 12 hours. If you specify + // a value higher than this setting, the operation fails. For example, if you + // specify a session duration of 12 hours, but your administrator set the maximum + // session duration to 6 hours, your operation fails. To learn how to view the + // maximum value for your role, see View the Maximum Session Duration Setting + // for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter 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. 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. + // + // The policy parameter is optional. If you pass a policy, 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, + // 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. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // 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 `min:"1" type:"string"` + + // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes + // the IdP. + // + // PrincipalArn is a required field + PrincipalArn *string `min:"20" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // The base-64 encoded SAML authentication response provided by the IdP. + // + // For more information, see Configuring a Relying Party and Adding Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html) + // in the Using IAM guide. + // + // SAMLAssertion is a required field + SAMLAssertion *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithSAMLInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(aws.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Policy", 1)) + } + + if s.PrincipalArn == nil { + invalidParams.Add(aws.NewErrParamRequired("PrincipalArn")) + } + if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 { + invalidParams.Add(aws.NewErrParamMinLen("PrincipalArn", 20)) + } + + if s.RoleArn == nil { + invalidParams.Add(aws.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(aws.NewErrParamMinLen("RoleArn", 20)) + } + + if s.SAMLAssertion == nil { + invalidParams.Add(aws.NewErrParamRequired("SAMLAssertion")) + } + if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 { + invalidParams.Add(aws.NewErrParamMinLen("SAMLAssertion", 4)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful AssumeRoleWithSAML request, including +// temporary AWS credentials that can be used to make AWS requests. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse +type AssumeRoleWithSAMLOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The identifiers for the temporary security credentials that the operation + // returns. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The value of the Recipient attribute of the SubjectConfirmationData element + // of the SAML assertion. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. We + // strongly recommend that you make no assumptions about the maximum size. As + // of this writing, the typical size is less than 4096 bytes, but that can vary. + // Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // The value of the Issuer element of the SAML assertion. + Issuer *string `type:"string"` + + // A hash value based on the concatenation of the Issuer response value, the + // AWS account ID, and the friendly name (the last part of the ARN) of the SAML + // provider in IAM. The combination of NameQualifier and Subject can be used + // to uniquely identify a federated user. + // + // The following pseudocode shows how the hash value is calculated: + // + // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP" + // ) ) + NameQualifier *string `type:"string"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The value of the NameID element in the Subject element of the SAML assertion. + Subject *string `type:"string"` + + // The format of the name ID, as defined by the Format attribute in the NameID + // element of the SAML assertion. Typical examples of the format are transient + // or persistent. + // + // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format, + // that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient + // is returned as transient. If the format includes any other prefix, the format + // is returned with no modifications. + SubjectType *string `type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s AssumeRoleWithSAMLOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest +type AssumeRoleWithWebIdentityInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) up to the maximum session duration setting for the role. + // This setting can have a value from 1 hour to 12 hours. If you specify a value + // higher than this setting, the operation fails. For example, if you specify + // a session duration of 12 hours, but your administrator set the maximum session + // duration to 6 hours, your operation fails. To learn how to view the maximum + // value for your role, see View the Maximum Session Duration Setting for a + // Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter 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. 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. + // + // The policy parameter is optional. If you pass a policy, 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 AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) + // in the IAM User Guide. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // 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 `min:"1" type:"string"` + + // The fully qualified host component of the domain name of the identity provider. + // + // Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com + // and graph.facebook.com are the only supported identity providers for OAuth + // 2.0 access tokens. Do not include URL schemes and port numbers. + // + // Do not specify this value for OpenID Connect ID tokens. + ProviderId *string `min:"4" type:"string"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. Typically, you pass the name + // or identifier that is associated with the user who is using your application. + // That way, the temporary security credentials that your application will use + // are associated with that user. This session name is included as part of the + // ARN and assumed role ID in the AssumedRoleUser response element. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // RoleSessionName is a required field + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The OAuth 2.0 access token or OpenID Connect ID token that is provided by + // the identity provider. Your application must get this token by authenticating + // the user who is using your application with a web identity provider before + // the application makes an AssumeRoleWithWebIdentity call. + // + // WebIdentityToken is a required field + WebIdentityToken *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithWebIdentityInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(aws.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Policy", 1)) + } + if s.ProviderId != nil && len(*s.ProviderId) < 4 { + invalidParams.Add(aws.NewErrParamMinLen("ProviderId", 4)) + } + + if s.RoleArn == nil { + invalidParams.Add(aws.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(aws.NewErrParamMinLen("RoleArn", 20)) + } + + if s.RoleSessionName == nil { + invalidParams.Add(aws.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(aws.NewErrParamMinLen("RoleSessionName", 2)) + } + + if s.WebIdentityToken == nil { + invalidParams.Add(aws.NewErrParamRequired("WebIdentityToken")) + } + if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 { + invalidParams.Add(aws.NewErrParamMinLen("WebIdentityToken", 4)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful AssumeRoleWithWebIdentity request, +// including temporary AWS credentials that can be used to make AWS requests. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse +type AssumeRoleWithWebIdentityOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The intended audience (also known as client ID) of the web identity token. + // This is traditionally the client identifier issued to the application that + // requested the web identity token. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security token. + // + // Note: The size of the security token that STS APIs return is not fixed. We + // strongly recommend that you make no assumptions about the maximum size. As + // of this writing, the typical size is less than 4096 bytes, but that can vary. + // Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The issuing authority of the web identity token presented. For OpenID Connect + // ID Tokens this contains the value of the iss field. For OAuth 2.0 access + // tokens, this contains the value of the ProviderId parameter that was passed + // in the AssumeRoleWithWebIdentity request. + Provider *string `type:"string"` + + // The unique user identifier that is returned by the identity provider. This + // identifier is associated with the WebIdentityToken that was submitted with + // the AssumeRoleWithWebIdentity call. The identifier is typically unique to + // the user and the application that acquired the WebIdentityToken (pairwise + // identifier). For OpenID Connect ID tokens, this field contains the value + // returned by the identity provider as the token's sub (Subject) claim. + SubjectFromWebIdentityToken *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s AssumeRoleWithWebIdentityOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// The identifiers for the temporary security credentials that the operation +// returns. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser +type AssumedRoleUser struct { + _ struct{} `type:"structure"` + + // The ARN of the temporary security credentials that are returned from the + // AssumeRole action. For more information about ARNs and how to use them in + // policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + // + // Arn is a required field + Arn *string `min:"20" type:"string" required:"true"` + + // A unique identifier that contains the role ID and the role session name of + // the role that is being assumed. The role ID is generated by AWS when the + // role is created. + // + // AssumedRoleId is a required field + AssumedRoleId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumedRoleUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumedRoleUser) GoString() string { + return s.String() +} + +// AWS credentials for API authentication. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials +type Credentials struct { + _ struct{} `type:"structure"` + + // The access key ID that identifies the temporary security credentials. + // + // AccessKeyId is a required field + AccessKeyId *string `min:"16" type:"string" required:"true"` + + // The date on which the current credentials expire. + // + // Expiration is a required field + Expiration *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + + // The secret access key that can be used to sign requests. + // + // SecretAccessKey is a required field + SecretAccessKey *string `type:"string" required:"true"` + + // The token that users must pass to the service API to use the temporary credentials. + // + // SessionToken is a required field + SessionToken *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s Credentials) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Credentials) GoString() string { + return s.String() +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest +type DecodeAuthorizationMessageInput struct { + _ struct{} `type:"structure"` + + // The encoded message that was returned with the response. + // + // EncodedMessage is a required field + EncodedMessage *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DecodeAuthorizationMessageInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"} + + if s.EncodedMessage == nil { + invalidParams.Add(aws.NewErrParamRequired("EncodedMessage")) + } + if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("EncodedMessage", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// A document that contains additional information about the authorization status +// of a request from an encoded message that is returned in response to an AWS +// request. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse +type DecodeAuthorizationMessageOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // An XML document that contains the decoded message. + DecodedMessage *string `type:"string"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s DecodeAuthorizationMessageOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Identifiers for the federated user that is associated with the credentials. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser +type FederatedUser struct { + _ struct{} `type:"structure"` + + // The ARN that specifies the federated user that is associated with the credentials. + // For more information about ARNs and how to use them in policies, see IAM + // Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + // + // Arn is a required field + Arn *string `min:"20" type:"string" required:"true"` + + // The string that identifies the federated user associated with the credentials, + // similar to the unique ID of an IAM user. + // + // FederatedUserId is a required field + FederatedUserId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s FederatedUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FederatedUser) GoString() string { + return s.String() +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest +type GetCallerIdentityInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetCallerIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityInput) GoString() string { + return s.String() +} + +// Contains the response to a successful GetCallerIdentity request, including +// information about the entity making the request. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse +type GetCallerIdentityOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The AWS account ID number of the account that owns or contains the calling + // entity. + Account *string `type:"string"` + + // The AWS ARN associated with the calling entity. + Arn *string `min:"20" type:"string"` + + // The unique identifier of the calling entity. The exact value depends on the + // type of entity making the call. The values returned are those listed in the + // aws:userid column in the Principal table (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable) + // found on the Policy Variables reference page in the IAM User Guide. + UserId *string `type:"string"` +} + +// String returns the string representation +func (s GetCallerIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s GetCallerIdentityOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest +type GetFederationTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the session should last. Acceptable durations + // for federation sessions range from 900 seconds (15 minutes) to 129600 seconds + // (36 hours), with 43200 seconds (12 hours) as the default. Sessions obtained + // using AWS account (root) credentials are restricted to a maximum of 3600 + // seconds (one hour). If the specified duration is longer than one hour, the + // session obtained by using AWS account (root) credentials defaults to one + // hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The name of the federated user. The name is used as an identifier for the + // temporary security credentials (such as Bob). For example, you can reference + // the federated user name in a resource-based policy, such as in an Amazon + // S3 bucket policy. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // Name is a required field + Name *string `min:"2" type:"string" required:"true"` + + // An IAM policy in JSON format that is passed with the GetFederationToken call + // and evaluated along with the policy or policies that are attached to the + // IAM user whose credentials are used to call GetFederationToken. The passed + // policy is used to scope down the permissions that are available to the IAM + // user, by allowing only a subset of the permissions that are granted to the + // IAM user. The passed policy cannot grant more permissions than those granted + // to the IAM user. The final permissions for the federated user are the most + // restrictive set based on the intersection of the passed policy and the IAM + // user policy. + // + // If you do not pass a policy, the resulting temporary security credentials + // have no effective permissions. The only exception is when the temporary security + // credentials are used to access a resource that has a resource-based policy + // that specifically allows the federated user to access the resource. + // + // The format for this parameter, as described by its regex pattern, is a string + // of characters up to 2048 characters in length. The characters can be any + // ASCII character from the space character to the end of the valid character + // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // 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. + // + // For more information about how permissions work, see Permissions for GetFederationToken + // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html). + Policy *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s GetFederationTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetFederationTokenInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "GetFederationTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(aws.NewErrParamMinValue("DurationSeconds", 900)) + } + + if s.Name == nil { + invalidParams.Add(aws.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 2 { + invalidParams.Add(aws.NewErrParamMinLen("Name", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(aws.NewErrParamMinLen("Policy", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful GetFederationToken request, including +// temporary AWS credentials that can be used to make AWS requests. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse +type GetFederationTokenOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. We + // strongly recommend that you make no assumptions about the maximum size. As + // of this writing, the typical size is less than 4096 bytes, but that can vary. + // Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` + + // Identifiers for the federated user associated with the credentials (such + // as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You + // can use the federated user's ARN in your resource-based policies, such as + // an Amazon S3 bucket policy. + FederatedUser *FederatedUser `type:"structure"` + + // A percentage value indicating the size of the policy in packed form. The + // service rejects policies for which the packed size is greater than 100 percent + // of the allowed value. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s GetFederationTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s GetFederationTokenOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest +type GetSessionTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the credentials should remain valid. Acceptable + // durations for IAM user sessions range from 900 seconds (15 minutes) to 129600 + // seconds (36 hours), with 43200 seconds (12 hours) as the default. Sessions + // for AWS account owners are restricted to a maximum of 3600 seconds (one hour). + // If the duration is longer than one hour, the session for AWS account owners + // defaults to one hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The identification number of the MFA device that is associated with the IAM + // user who is making the GetSessionToken call. Specify this value if the IAM + // user has a policy 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). + // You can find the device for an IAM user by going to the AWS Management Console + // and viewing the user's security credentials. + // + // The regex used to validated this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric 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 + // the IAM user to submit an MFA code, specify this value. If MFA authentication + // is required, and the user does not provide a code when requesting a set of + // temporary security credentials, the user will receive an "access denied" + // response when requesting resources that require MFA authentication. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s GetSessionTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetSessionTokenInput) Validate() error { + invalidParams := aws.ErrInvalidParams{Context: "GetSessionTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(aws.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(aws.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(aws.NewErrParamMinLen("TokenCode", 6)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Contains the response to a successful GetSessionToken request, including +// temporary AWS credentials that can be used to make AWS requests. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse +type GetSessionTokenOutput struct { + _ struct{} `type:"structure"` + + responseMetadata aws.Response + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // Note: The size of the security token that STS APIs return is not fixed. We + // strongly recommend that you make no assumptions about the maximum size. As + // of this writing, the typical size is less than 4096 bytes, but that can vary. + // Also, future updates to AWS might require larger sizes. + Credentials *Credentials `type:"structure"` +} + +// String returns the string representation +func (s GetSessionTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenOutput) GoString() string { + return s.String() +} + +// SDKResponseMetdata return sthe response metadata for the API. +func (s GetSessionTokenOutput) SDKResponseMetadata() aws.Response { + return s.responseMetadata +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/customizations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/customizations.go new file mode 100644 index 000000000..488324c3a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/customizations.go @@ -0,0 +1,12 @@ +package sts + +import request "github.com/aws/aws-sdk-go-v2/aws" + +func init() { + initRequest = func(c *STS, r *request.Request) { + switch r.Operation.Name { + case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity: + r.Handlers.Sign.Clear() // these operations are unsigned + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go new file mode 100644 index 000000000..a43fa8055 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go @@ -0,0 +1,72 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package sts provides the client and types for making API +// requests to AWS Security Token Service. +// +// The AWS Security Token Service (STS) is a web service that enables you to +// request temporary, limited-privilege credentials for AWS Identity and Access +// Management (IAM) users or for users that you authenticate (federated users). +// This guide provides descriptions of the STS API. For more detailed information +// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). +// +// As an alternative to using the API, you can use one of the AWS SDKs, which +// consist of libraries and sample code for various programming languages and +// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient +// way to create programmatic access to STS. For example, the SDKs take care +// of cryptographically signing requests, managing errors, and retrying requests +// automatically. For information about the AWS SDKs, including how to download +// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/). +// +// For information about setting up signatures and authorization through the +// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) +// in the AWS General Reference. For general information about the Query API, +// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) +// in Using IAM. For information about using security tokens with other AWS +// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) +// in the IAM User Guide. +// +// If you're new to AWS and need additional technical information about a specific +// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ +// (http://aws.amazon.com/documentation/). +// +// Endpoints +// +// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com +// that maps to the US East (N. Virginia) region. Additional regions are available +// and are activated by default. For more information, see Activating and Deactivating +// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region) +// in the AWS General Reference. +// +// Recording API requests +// +// STS supports AWS CloudTrail, which is a service that records AWS calls for +// your AWS account and delivers log files to an Amazon S3 bucket. By using +// information collected by CloudTrail, you can determine what requests were +// successfully made to STS, who made the request, when it was made, and so +// on. To learn more about CloudTrail, including how to turn it on and find +// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). +// +// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service. +// +// See sts package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/ +// +// Using the Client +// +// To AWS Security Token Service with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the AWS Security Token Service client STS for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#New +package sts diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/errors.go new file mode 100644 index 000000000..e24884ef3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/errors.go @@ -0,0 +1,73 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +const ( + + // ErrCodeExpiredTokenException for service response error code + // "ExpiredTokenException". + // + // The web identity token that was passed is expired or is not valid. Get a + // new identity token from the identity provider and then retry the request. + ErrCodeExpiredTokenException = "ExpiredTokenException" + + // ErrCodeIDPCommunicationErrorException for service response error code + // "IDPCommunicationError". + // + // The request could not be fulfilled because the non-AWS identity provider + // (IDP) that was asked to verify the incoming identity token could not be reached. + // This is often a transient error caused by network conditions. Retry the request + // a limited number of times so that you don't exceed the request rate. If the + // error persists, the non-AWS identity provider might be down or not responding. + ErrCodeIDPCommunicationErrorException = "IDPCommunicationError" + + // ErrCodeIDPRejectedClaimException for service response error code + // "IDPRejectedClaim". + // + // The identity provider (IdP) reported that authentication failed. This might + // be because the claim is invalid. + // + // If this error is returned for the AssumeRoleWithWebIdentity operation, it + // can also mean that the claim has expired or has been explicitly revoked. + ErrCodeIDPRejectedClaimException = "IDPRejectedClaim" + + // ErrCodeInvalidAuthorizationMessageException for service response error code + // "InvalidAuthorizationMessageException". + // + // The error returned if the message passed to DecodeAuthorizationMessage was + // invalid. This can happen if the token contains invalid characters, such as + // linebreaks. + ErrCodeInvalidAuthorizationMessageException = "InvalidAuthorizationMessageException" + + // ErrCodeInvalidIdentityTokenException for service response error code + // "InvalidIdentityToken". + // + // The web identity token that was passed could not be validated by AWS. Get + // a new identity token from the identity provider and then retry the request. + ErrCodeInvalidIdentityTokenException = "InvalidIdentityToken" + + // ErrCodeMalformedPolicyDocumentException for service response error code + // "MalformedPolicyDocument". + // + // The request was rejected because the policy document was malformed. The error + // message describes the specific error. + ErrCodeMalformedPolicyDocumentException = "MalformedPolicyDocument" + + // ErrCodePackedPolicyTooLargeException for service response error code + // "PackedPolicyTooLarge". + // + // The request was rejected because the policy document was too large. The error + // message describes how big the policy document is, in packed form, as a percentage + // of what the API allows. + ErrCodePackedPolicyTooLargeException = "PackedPolicyTooLarge" + + // ErrCodeRegionDisabledException for service response error code + // "RegionDisabledException". + // + // STS is not activated in the requested region for the account that is being + // asked to generate credentials. The account administrator must use the IAM + // console to activate STS in that region. For more information, see Activating + // and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) + // in the IAM User Guide. + ErrCodeRegionDisabledException = "RegionDisabledException" +) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/service.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/service.go new file mode 100644 index 000000000..79775f71f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/service.go @@ -0,0 +1,80 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +import ( + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/private/protocol/query" +) + +// STS provides the API operation methods for making requests to +// AWS Security Token Service. See this package's package overview docs +// for details on the service. +// +// STS methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type STS struct { + *aws.Client +} + +// Used for custom client initialization logic +var initClient func(*STS) + +// Used for custom request initialization logic +var initRequest func(*STS, *aws.Request) + +// Service information constants +const ( + ServiceName = "sts" // Service endpoint prefix API calls made to. + EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. +) + +// New creates a new instance of the STS client with a config. +// +// Example: +// // Create a STS client from just a config. +// svc := sts.New(myConfig) +func New(config aws.Config) *STS { + var signingName string + signingRegion := config.Region + + svc := &STS{ + Client: aws.NewClient( + config, + aws.Metadata{ + ServiceName: ServiceName, + SigningName: signingName, + SigningRegion: signingRegion, + APIVersion: "2011-06-15", + }, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(query.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc) + } + + return svc +} + +// newRequest creates a new request for a STS operation and runs any +// custom request initialization. +func (c *STS) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(c, req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/stsiface/interface.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/stsiface/interface.go new file mode 100644 index 000000000..3466ce887 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/stsiface/interface.go @@ -0,0 +1,80 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package stsiface provides an interface to enable mocking the AWS Security Token Service service client +// for testing your code. +// +// It is important to note that this interface will have breaking changes +// when the service model is updated and adds new API operations, paginators, +// and waiters. +package stsiface + +import ( + "github.com/aws/aws-sdk-go-v2/service/sts" +) + +// STSAPI provides an interface to enable mocking the +// sts.STS service client's API operation, +// paginators, and waiters. This make unit testing your code that calls out +// to the SDK's service client's calls easier. +// +// The best way to use this interface is so the SDK's service client's calls +// can be stubbed out for unit testing your code with the SDK without needing +// to inject custom request handlers into the SDK's request pipeline. +// +// // myFunc uses an SDK service client to make a request to +// // AWS Security Token Service. +// func myFunc(svc stsiface.STSAPI) bool { +// // Make svc.AssumeRole request +// } +// +// func main() { +// cfg, err := external.LoadDefaultAWSConfig() +// if err != nil { +// panic("failed to load config, " + err.Error()) +// } +// +// svc := sts.New(cfg) +// +// myFunc(svc) +// } +// +// In your _test.go file: +// +// // Define a mock struct to be used in your unit tests of myFunc. +// type mockSTSClient struct { +// stsiface.STSAPI +// } +// func (m *mockSTSClient) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) { +// // mock response/functionality +// } +// +// func TestMyFunc(t *testing.T) { +// // Setup Test +// mockSvc := &mockSTSClient{} +// +// myfunc(mockSvc) +// +// // Verify myFunc's functionality +// } +// +// It is important to note that this interface will have breaking changes +// when the service model is updated and adds new API operations, paginators, +// and waiters. Its suggested to use the pattern above for testing, or using +// tooling to generate mocks to satisfy the interfaces. +type STSAPI interface { + AssumeRoleRequest(*sts.AssumeRoleInput) sts.AssumeRoleRequest + + AssumeRoleWithSAMLRequest(*sts.AssumeRoleWithSAMLInput) sts.AssumeRoleWithSAMLRequest + + AssumeRoleWithWebIdentityRequest(*sts.AssumeRoleWithWebIdentityInput) sts.AssumeRoleWithWebIdentityRequest + + DecodeAuthorizationMessageRequest(*sts.DecodeAuthorizationMessageInput) sts.DecodeAuthorizationMessageRequest + + GetCallerIdentityRequest(*sts.GetCallerIdentityInput) sts.GetCallerIdentityRequest + + GetFederationTokenRequest(*sts.GetFederationTokenInput) sts.GetFederationTokenRequest + + GetSessionTokenRequest(*sts.GetSessionTokenInput) sts.GetSessionTokenRequest +} + +var _ STSAPI = (*sts.STS)(nil) diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/LICENSE.md b/vendor/github.com/cactus/go-statsd-client/statsd/LICENSE.md new file mode 100644 index 000000000..56bee4f27 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2012-2016 Eli Janssen + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/buffer_pool.go b/vendor/github.com/cactus/go-statsd-client/statsd/buffer_pool.go new file mode 100644 index 000000000..2ffa05376 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/buffer_pool.go @@ -0,0 +1,31 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "bytes" + "sync" +) + +type bufferPool struct { + *sync.Pool +} + +func newBufferPool() *bufferPool { + return &bufferPool{ + &sync.Pool{New: func() interface{} { + return bytes.NewBuffer(make([]byte, 0, 1700)) + }}, + } +} + +func (bp *bufferPool) Get() *bytes.Buffer { + return (bp.Pool.Get()).(*bytes.Buffer) +} + +func (bp *bufferPool) Put(b *bytes.Buffer) { + b.Truncate(0) + bp.Pool.Put(b) +} diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/client.go b/vendor/github.com/cactus/go-statsd-client/statsd/client.go new file mode 100644 index 000000000..3cd251d96 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/client.go @@ -0,0 +1,327 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "fmt" + "math/rand" + "strconv" + "strings" + "time" +) + +var bufPool = newBufferPool() + +// The StatSender interface wraps all the statsd metric methods +type StatSender interface { + Inc(string, int64, float32) error + Dec(string, int64, float32) error + Gauge(string, int64, float32) error + GaugeDelta(string, int64, float32) error + Timing(string, int64, float32) error + TimingDuration(string, time.Duration, float32) error + Set(string, string, float32) error + SetInt(string, int64, float32) error + Raw(string, string, float32) error +} + +// The Statter interface defines the behavior of a stat client +type Statter interface { + StatSender + NewSubStatter(string) SubStatter + SetPrefix(string) + Close() error +} + +// The SubStatter interface defines the behavior of a stat child/subclient +type SubStatter interface { + StatSender + SetSamplerFunc(SamplerFunc) + NewSubStatter(string) SubStatter +} + +// The SamplerFunc type defines a function that can serve +// as a Client sampler function. +type SamplerFunc func(float32) bool + +// DefaultSampler is the default rate sampler function +func DefaultSampler(rate float32) bool { + if rate < 1 { + return rand.Float32() < rate + } + return true +} + +// A Client is a statsd client. +type Client struct { + // prefix for statsd name + prefix string + // packet sender + sender Sender + // sampler method + sampler SamplerFunc +} + +// Close closes the connection and cleans up. +func (s *Client) Close() error { + if s == nil { + return nil + } + + err := s.sender.Close() + return err +} + +// Inc increments a statsd count type. +// stat is a string name for the metric. +// value is the integer value +// rate is the sample rate (0.0 to 1.0) +func (s *Client) Inc(stat string, value int64, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", value, "|c", rate) +} + +// Dec decrements a statsd count type. +// stat is a string name for the metric. +// value is the integer value. +// rate is the sample rate (0.0 to 1.0). +func (s *Client) Dec(stat string, value int64, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", -value, "|c", rate) +} + +// Gauge submits/updates a statsd gauge type. +// stat is a string name for the metric. +// value is the integer value. +// rate is the sample rate (0.0 to 1.0). +func (s *Client) Gauge(stat string, value int64, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", value, "|g", rate) +} + +// GaugeDelta submits a delta to a statsd gauge. +// stat is the string name for the metric. +// value is the (positive or negative) change. +// rate is the sample rate (0.0 to 1.0). +func (s *Client) GaugeDelta(stat string, value int64, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + // if negative, the submit formatter will prefix with a - already + // so only special case the positive value + if value >= 0 { + return s.submit(stat, "+", value, "|g", rate) + } + return s.submit(stat, "", value, "|g", rate) +} + +// Timing submits a statsd timing type. +// stat is a string name for the metric. +// delta is the time duration value in milliseconds +// rate is the sample rate (0.0 to 1.0). +func (s *Client) Timing(stat string, delta int64, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", delta, "|ms", rate) +} + +// TimingDuration submits a statsd timing type. +// stat is a string name for the metric. +// delta is the timing value as time.Duration +// rate is the sample rate (0.0 to 1.0). +func (s *Client) TimingDuration(stat string, delta time.Duration, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + ms := float64(delta) / float64(time.Millisecond) + return s.submit(stat, "", ms, "|ms", rate) +} + +// Set submits a stats set type +// stat is a string name for the metric. +// value is the string value +// rate is the sample rate (0.0 to 1.0). +func (s *Client) Set(stat string, value string, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", value, "|s", rate) +} + +// SetInt submits a number as a stats set type. +// stat is a string name for the metric. +// value is the integer value +// rate is the sample rate (0.0 to 1.0). +func (s *Client) SetInt(stat string, value int64, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", value, "|s", rate) +} + +// Raw submits a preformatted value. +// stat is the string name for the metric. +// value is a preformatted "raw" value string. +// rate is the sample rate (0.0 to 1.0). +func (s *Client) Raw(stat string, value string, rate float32) error { + if !s.includeStat(rate) { + return nil + } + + return s.submit(stat, "", value, "", rate) +} + +// SetSamplerFunc sets a sampler function to something other than the default +// sampler is a function that determines whether the metric is +// to be accepted, or discarded. +// An example use case is for submitted pre-sampled metrics. +func (s *Client) SetSamplerFunc(sampler SamplerFunc) { + s.sampler = sampler +} + +// submit an already sampled raw stat +func (s *Client) submit(stat, vprefix string, value interface{}, suffix string, rate float32) error { + data := bufPool.Get() + defer bufPool.Put(data) + + if s.prefix != "" { + data.WriteString(s.prefix) + data.WriteString(".") + } + + data.WriteString(stat) + data.WriteString(":") + + if vprefix != "" { + data.WriteString(vprefix) + } + + // sadly, no way to jam this back into the bytes.Buffer without + // doing a few allocations... avoiding those is the whole point here... + // so from here on out just use it as a raw []byte + b := data.Bytes() + + switch v := value.(type) { + case string: + b = append(b, v...) + case int64: + b = strconv.AppendInt(b, v, 10) + case float64: + b = strconv.AppendFloat(b, v, 'f', -1, 64) + default: + return fmt.Errorf("No matching type format") + } + + if suffix != "" { + b = append(b, suffix...) + } + + if rate < 1 { + b = append(b, "|@"...) + b = strconv.AppendFloat(b, float64(rate), 'f', 6, 32) + } + + _, err := s.sender.Send(b) + return err +} + +// check for nil client, and perform sampling calculation +func (s *Client) includeStat(rate float32) bool { + if s == nil { + return false + } + + // test for nil in case someone builds their own + // client without calling new (result is nil sampler) + if s.sampler != nil { + return s.sampler(rate) + } + return DefaultSampler(rate) +} + +// SetPrefix sets/updates the statsd client prefix. +// Note: Does not change the prefix of any SubStatters. +func (s *Client) SetPrefix(prefix string) { + if s == nil { + return + } + + s.prefix = prefix +} + +// NewSubStatter returns a SubStatter with appended prefix +func (s *Client) NewSubStatter(prefix string) SubStatter { + var c *Client + if s != nil { + c = &Client{ + prefix: joinPathComp(s.prefix, prefix), + sender: s.sender, + sampler: s.sampler, + } + } + return c +} + +// NewClient returns a pointer to a new Client, and an error. +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +// +// prefix is the statsd client prefix. Can be "" if no prefix is desired. +func NewClient(addr, prefix string) (Statter, error) { + sender, err := NewSimpleSender(addr) + if err != nil { + return nil, err + } + + return &Client{prefix: prefix, sender: sender}, nil +} + +// NewClientWithSender returns a pointer to a new Client and an error. +// +// sender is an instance of a statsd.Sender interface and may not be nil +// +// prefix is the stastd client prefix. Can be "" if no prefix is desired. +func NewClientWithSender(sender Sender, prefix string) (Statter, error) { + if sender == nil { + return nil, fmt.Errorf("Client sender may not be nil") + } + + return &Client{prefix: prefix, sender: sender}, nil +} + +// joinPathComp is a helper that ensures we combine path components with a dot +// when it's appropriate to do so; prefix is the existing prefix and suffix is +// the new component being added. +// +// It returns the joined prefix. +func joinPathComp(prefix, suffix string) string { + suffix = strings.TrimLeft(suffix, ".") + if prefix != "" && suffix != "" { + return prefix + "." + suffix + } + return prefix + suffix +} + +// Dial is a compatibility alias for NewClient +var Dial = NewClient + +// New is a compatibility alias for NewClient +var New = NewClient diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/client_buffered.go b/vendor/github.com/cactus/go-statsd-client/statsd/client_buffered.go new file mode 100644 index 000000000..960db3dc9 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/client_buffered.go @@ -0,0 +1,48 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import "time" + +// NewBufferedClient returns a new BufferedClient +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +// +// prefix is the statsd client prefix. Can be "" if no prefix is desired. +// +// flushInterval is a time.Duration, and specifies the maximum interval for +// packet sending. Note that if you send lots of metrics, you will send more +// often. This is just a maximal threshold. +// +// If flushInterval is 0ms, defaults to 300ms. +// +// flushBytes specifies the maximum udp packet size you wish to send. If adding +// a metric would result in a larger packet than flushBytes, the packet will +// first be send, then the new data will be added to the next packet. +// +// If flushBytes is 0, defaults to 1432 bytes, which is considered safe +// for local traffic. If sending over the public internet, 512 bytes is +// the recommended value. +func NewBufferedClient(addr, prefix string, flushInterval time.Duration, flushBytes int) (Statter, error) { + if flushBytes <= 0 { + // https://github.com/etsy/statsd/blob/master/docs/metric_types.md#multi-metric-packets + flushBytes = 1432 + } + if flushInterval <= time.Duration(0) { + flushInterval = 300 * time.Millisecond + } + sender, err := NewBufferedSender(addr, flushInterval, flushBytes) + if err != nil { + return nil, err + } + + client := &Client{ + prefix: prefix, + sender: sender, + } + + return client, nil +} diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/client_noop.go b/vendor/github.com/cactus/go-statsd-client/statsd/client_noop.go new file mode 100644 index 000000000..1bdde0882 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/client_noop.go @@ -0,0 +1,111 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import "time" + +// A NoopClient is a client that does nothing. +type NoopClient struct{} + +// Close closes the connection and cleans up. +func (s *NoopClient) Close() error { + return nil +} + +// Inc increments a statsd count type. +// stat is a string name for the metric. +// value is the integer value +// rate is the sample rate (0.0 to 1.0) +func (s *NoopClient) Inc(stat string, value int64, rate float32) error { + return nil +} + +// Dec decrements a statsd count type. +// stat is a string name for the metric. +// value is the integer value. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Dec(stat string, value int64, rate float32) error { + return nil +} + +// Gauge submits/Updates a statsd gauge type. +// stat is a string name for the metric. +// value is the integer value. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Gauge(stat string, value int64, rate float32) error { + return nil +} + +// GaugeDelta submits a delta to a statsd gauge. +// stat is the string name for the metric. +// value is the (positive or negative) change. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) GaugeDelta(stat string, value int64, rate float32) error { + return nil +} + +// Timing submits a statsd timing type. +// stat is a string name for the metric. +// delta is the time duration value in milliseconds +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Timing(stat string, delta int64, rate float32) error { + return nil +} + +// TimingDuration submits a statsd timing type. +// stat is a string name for the metric. +// delta is the timing value as time.Duration +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) TimingDuration(stat string, delta time.Duration, rate float32) error { + return nil +} + +// Set submits a stats set type. +// stat is a string name for the metric. +// value is the string value +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Set(stat string, value string, rate float32) error { + return nil +} + +// SetInt submits a number as a stats set type. +// convenience method for Set with number. +// stat is a string name for the metric. +// value is the integer value +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) SetInt(stat string, value int64, rate float32) error { + return nil +} + +// Raw formats the statsd event data, handles sampling, prepares it, +// and sends it to the server. +// stat is the string name for the metric. +// value is the preformatted "raw" value string. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Raw(stat string, value string, rate float32) error { + return nil +} + +// SetPrefix sets/updates the statsd client prefix +func (s *NoopClient) SetPrefix(prefix string) {} + +// NewSubStatter returns a SubStatter with appended prefix +func (s *NoopClient) NewSubStatter(prefix string) SubStatter { + return &NoopClient{} +} + +// SetSamplerFunc sets the sampler function +func (s *NoopClient) SetSamplerFunc(sampler SamplerFunc) {} + +// NewNoopClient returns a pointer to a new NoopClient, and an error (always +// nil, just supplied to support api convention). +// Use variadic arguments to support identical format as NewClient, or a more +// conventional no argument form. +func NewNoopClient(a ...interface{}) (Statter, error) { + return &NoopClient{}, nil +} + +// NewNoop is a compatibility alias for NewNoopClient +var NewNoop = NewNoopClient diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/doc.go b/vendor/github.com/cactus/go-statsd-client/statsd/doc.go new file mode 100644 index 000000000..e9e0e577c --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/doc.go @@ -0,0 +1,29 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +/* +Package statsd provides a StatsD client implementation that is safe for +concurrent use by multiple goroutines and for efficiency can be created and +reused. + +Example usage: + + // first create a client + client, err := statsd.NewClient("127.0.0.1:8125", "test-client") + // handle any errors + if err != nil { + log.Fatal(err) + } + // make sure to clean up + defer client.Close() + + // Send a stat + err = client.Inc("stat1", 42, 1.0) + // handle any errors + if err != nil { + log.Printf("Error sending metric: %+v", err) + } + +*/ +package statsd diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/sender.go b/vendor/github.com/cactus/go-statsd-client/statsd/sender.go new file mode 100644 index 000000000..d4f4cb599 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/sender.go @@ -0,0 +1,69 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "errors" + "net" +) + +// The Sender interface wraps a Send and Close +type Sender interface { + Send(data []byte) (int, error) + Close() error +} + +// SimpleSender provides a socket send interface. +type SimpleSender struct { + // underlying connection + c net.PacketConn + // resolved udp address + ra *net.UDPAddr +} + +// Send sends the data to the server endpoint. +func (s *SimpleSender) Send(data []byte) (int, error) { + // no need for locking here, as the underlying fdNet + // already serialized writes + n, err := s.c.(*net.UDPConn).WriteToUDP(data, s.ra) + if err != nil { + return 0, err + } + if n == 0 { + return n, errors.New("Wrote no bytes") + } + return n, nil +} + +// Close closes the SimpleSender +func (s *SimpleSender) Close() error { + err := s.c.Close() + return err +} + +// NewSimpleSender returns a new SimpleSender for sending to the supplied +// addresss. +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +func NewSimpleSender(addr string) (Sender, error) { + c, err := net.ListenPacket("udp", ":0") + if err != nil { + return nil, err + } + + ra, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + c.Close() + return nil, err + } + + sender := &SimpleSender{ + c: c, + ra: ra, + } + + return sender, nil +} diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/sender_buffered.go b/vendor/github.com/cactus/go-statsd-client/statsd/sender_buffered.go new file mode 100644 index 000000000..b2e386e1c --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/sender_buffered.go @@ -0,0 +1,175 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "bytes" + "fmt" + "sync" + "time" +) + +var senderPool = newBufferPool() + +// BufferedSender provides a buffered statsd udp, sending multiple +// metrics, where possible. +type BufferedSender struct { + sender Sender + flushBytes int + flushInterval time.Duration + // buffers + bufmx sync.Mutex + buffer *bytes.Buffer + bufs chan *bytes.Buffer + // lifecycle + runmx sync.RWMutex + shutdown chan chan error + running bool +} + +// Send bytes. +func (s *BufferedSender) Send(data []byte) (int, error) { + s.runmx.RLock() + if !s.running { + s.runmx.RUnlock() + return 0, fmt.Errorf("BufferedSender is not running") + } + + s.withBufferLock(func() { + blen := s.buffer.Len() + if blen > 0 && blen+len(data)+1 >= s.flushBytes { + s.swapnqueue() + } + + s.buffer.Write(data) + s.buffer.WriteByte('\n') + + if s.buffer.Len() >= s.flushBytes { + s.swapnqueue() + } + }) + s.runmx.RUnlock() + return len(data), nil +} + +// Close Buffered Sender +func (s *BufferedSender) Close() error { + // since we are running, write lock during cleanup + s.runmx.Lock() + defer s.runmx.Unlock() + if !s.running { + return nil + } + + errChan := make(chan error) + s.running = false + s.shutdown <- errChan + return <-errChan +} + +// Start Buffered Sender +// Begins ticker and read loop +func (s *BufferedSender) Start() { + // write lock to start running + s.runmx.Lock() + defer s.runmx.Unlock() + if s.running { + return + } + + s.running = true + s.bufs = make(chan *bytes.Buffer, 32) + go s.run() +} + +func (s *BufferedSender) withBufferLock(fn func()) { + s.bufmx.Lock() + fn() + s.bufmx.Unlock() +} + +func (s *BufferedSender) swapnqueue() { + if s.buffer.Len() == 0 { + return + } + ob := s.buffer + nb := senderPool.Get() + s.buffer = nb + s.bufs <- ob +} + +func (s *BufferedSender) run() { + ticker := time.NewTicker(s.flushInterval) + defer ticker.Stop() + + doneChan := make(chan bool) + go func() { + for buf := range s.bufs { + s.flush(buf) + senderPool.Put(buf) + } + doneChan <- true + }() + + for { + select { + case <-ticker.C: + s.withBufferLock(func() { + s.swapnqueue() + }) + case errChan := <-s.shutdown: + s.withBufferLock(func() { + s.swapnqueue() + }) + close(s.bufs) + <-doneChan + errChan <- s.sender.Close() + return + } + } +} + +// send to remove endpoint and truncate buffer +func (s *BufferedSender) flush(b *bytes.Buffer) (int, error) { + bb := b.Bytes() + bbl := len(bb) + if bb[bbl-1] == '\n' { + bb = bb[:bbl-1] + } + //n, err := s.sender.Send(bytes.TrimSuffix(b.Bytes(), []byte("\n"))) + n, err := s.sender.Send(bb) + b.Truncate(0) // clear the buffer + return n, err +} + +// NewBufferedSender returns a new BufferedSender +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +// +// flushInterval is a time.Duration, and specifies the maximum interval for +// packet sending. Note that if you send lots of metrics, you will send more +// often. This is just a maximal threshold. +// +// flushBytes specifies the maximum udp packet size you wish to send. If adding +// a metric would result in a larger packet than flushBytes, the packet will +// first be send, then the new data will be added to the next packet. +func NewBufferedSender(addr string, flushInterval time.Duration, flushBytes int) (Sender, error) { + simpleSender, err := NewSimpleSender(addr) + if err != nil { + return nil, err + } + + sender := &BufferedSender{ + flushBytes: flushBytes, + flushInterval: flushInterval, + sender: simpleSender, + buffer: senderPool.Get(), + shutdown: make(chan chan error), + } + + sender.Start() + return sender, nil +} diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/recorder.go b/vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/recorder.go new file mode 100644 index 000000000..df3ba32d7 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/recorder.go @@ -0,0 +1,79 @@ +package statsdtest + +import ( + "errors" + "sync" +) + +// RecordingSender implements statsd.Sender but parses individual Stats into a +// buffer that can be later inspected instead of sending to some server. It +// should constructed with NewRecordingSender(). +type RecordingSender struct { + m sync.Mutex + buffer Stats + closed bool +} + +// NewRecordingSender creates a new RecordingSender for use by a statsd.Client. +func NewRecordingSender() *RecordingSender { + rs := &RecordingSender{} + rs.buffer = make(Stats, 0) + return rs +} + +// GetSent returns the stats that have been sent. Locks and copies the current +// state of the sent Stats. +// +// The entire buffer of Stat objects (including Stat.Raw is copied). +func (rs *RecordingSender) GetSent() Stats { + rs.m.Lock() + defer rs.m.Unlock() + + results := make(Stats, len(rs.buffer)) + for i, e := range rs.buffer { + results[i] = e + results[i].Raw = make([]byte, len(e.Raw)) + copy(results[i].Raw, e.Raw) + } + + return results +} + +// ClearSent locks the sender and clears any Stats that have been recorded. +func (rs *RecordingSender) ClearSent() { + rs.m.Lock() + defer rs.m.Unlock() + + rs.buffer = rs.buffer[:0] +} + +// Send parses the provided []byte into stat objects and then appends these to +// the buffer of sent stats. Buffer operations are synchronized so it is safe +// to call this from multiple goroutines (though contenion will impact +// performance so don't use this during a benchmark). Send treats '\n' as a +// delimiter between multiple sats in the same []byte. +// +// Calling after the Sender has been closed will return an error (and not +// mutate the buffer). +func (rs *RecordingSender) Send(data []byte) (int, error) { + sent := ParseStats(data) + + rs.m.Lock() + defer rs.m.Unlock() + if rs.closed { + return 0, errors.New("writing to a closed sender") + } + + rs.buffer = append(rs.buffer, sent...) + return len(data), nil +} + +// Close marks this sender as closed. Subsequent attempts to Send stats will +// result in an error. +func (rs *RecordingSender) Close() error { + rs.m.Lock() + defer rs.m.Unlock() + + rs.closed = true + return nil +} diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/stat.go b/vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/stat.go new file mode 100644 index 000000000..0d10c96d6 --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/statsdtest/stat.go @@ -0,0 +1,139 @@ +package statsdtest + +import ( + "bytes" + "fmt" + "strings" +) + +// Stat contains the raw and extracted stat information from a stat that was +// sent by the RecordingSender. Raw will always have the content that was +// consumed for this specific stat and Parsed will be set if no errors were hit +// pulling information out of it. +type Stat struct { + Raw []byte + Stat string + Value string + Tag string + Rate string + Parsed bool +} + +// String fulfils the stringer interface +func (s *Stat) String() string { + return fmt.Sprintf("%s %s %s", s.Stat, s.Value, s.Rate) +} + +// ParseStats takes a sequence of bytes destined for a Statsd server and parses +// it out into one or more Stat structs. Each struct includes both the raw +// bytes (copied, so the src []byte may be reused if desired) as well as each +// component it was able to parse out. If parsing was incomplete Stat.Parsed +// will be set to false but no error is returned / kept. +func ParseStats(src []byte) Stats { + d := make([]byte, len(src)) + copy(d, src) + + // standard protocol indicates one stat per line + entries := bytes.Split(d, []byte{'\n'}) + + result := make(Stats, len(entries)) + + for i, e := range entries { + result[i] = Stat{Raw: e} + ss := &result[i] + + // : deliniates the stat name from the stat data + marker := bytes.IndexByte(e, ':') + if marker == -1 { + continue + } + ss.Stat = string(e[0:marker]) + + // stat data folows ':' with the form {value}|{type tag}[|@{sample rate}] + e = e[marker+1:] + marker = bytes.IndexByte(e, '|') + if marker == -1 { + continue + } + + ss.Value = string(e[:marker]) + + e = e[marker+1:] + marker = bytes.IndexByte(e, '|') + if marker == -1 { + // no sample rate + ss.Tag = string(e) + } else { + ss.Tag = string(e[:marker]) + e = e[marker+1:] + if len(e) == 0 || e[0] != '@' { + // sample rate should be prefixed with '@'; bail otherwise + continue + } + ss.Rate = string(e[1:]) + } + + ss.Parsed = true + } + + return result +} + +// Stats is a slice of Stat +type Stats []Stat + +// Unparsed returns any stats that were unable to be completely parsed. +func (s Stats) Unparsed() Stats { + var r Stats + for _, e := range s { + if !e.Parsed { + r = append(r, e) + } + } + + return r +} + +// CollectNamed returns all data sent for a given stat name. +func (s Stats) CollectNamed(statName string) Stats { + return s.Collect(func(e Stat) bool { + return e.Stat == statName + }) +} + +// Collect gathers all stats that make some predicate true. +func (s Stats) Collect(pred func(Stat) bool) Stats { + var r Stats + for _, e := range s { + if pred(e) { + r = append(r, e) + } + } + return r +} + +// Values returns the values associated with this Stats object. +func (s Stats) Values() []string { + if len(s) == 0 { + return nil + } + + r := make([]string, len(s)) + for i, e := range s { + r[i] = e.Value + } + return r +} + +// String fulfils the stringer interface +func (s Stats) String() string { + if len(s) == 0 { + return "" + } + + r := make([]string, len(s)) + for i, e := range s { + r[i] = e.String() + } + return strings.Join(r, "\n") +} diff --git a/vendor/github.com/cactus/go-statsd-client/statsd/validator.go b/vendor/github.com/cactus/go-statsd-client/statsd/validator.go new file mode 100644 index 000000000..a022510dd --- /dev/null +++ b/vendor/github.com/cactus/go-statsd-client/statsd/validator.go @@ -0,0 +1,26 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "fmt" + "regexp" +) + +// The ValidatorFunc type defines a function that can serve +// as a stat name validation function. +type ValidatorFunc func(string) error + +var safeName = regexp.MustCompile(`^[a-zA-Z0-9\-_.]+$`) + +// CheckName may be used to validate whether a stat name contains invalid +// characters. If invalid characters are found, the function will return an +// error. +func CheckName(stat string) error { + if !safeName.MatchString(stat) { + return fmt.Errorf("invalid stat name: %s", stat) + } + return nil +} diff --git a/vendor/github.com/codahale/hdrhistogram/LICENSE b/vendor/github.com/codahale/hdrhistogram/LICENSE new file mode 100644 index 000000000..f9835c241 --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Coda Hale + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/codahale/hdrhistogram/hdr.go b/vendor/github.com/codahale/hdrhistogram/hdr.go new file mode 100644 index 000000000..c97842926 --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/hdr.go @@ -0,0 +1,564 @@ +// Package hdrhistogram provides an implementation of Gil Tene's HDR Histogram +// data structure. The HDR Histogram allows for fast and accurate analysis of +// the extreme ranges of data with non-normal distributions, like latency. +package hdrhistogram + +import ( + "fmt" + "math" +) + +// A Bracket is a part of a cumulative distribution. +type Bracket struct { + Quantile float64 + Count, ValueAt int64 +} + +// A Snapshot is an exported view of a Histogram, useful for serializing them. +// A Histogram can be constructed from it by passing it to Import. +type Snapshot struct { + LowestTrackableValue int64 + HighestTrackableValue int64 + SignificantFigures int64 + Counts []int64 +} + +// A Histogram is a lossy data structure used to record the distribution of +// non-normally distributed data (like latency) with a high degree of accuracy +// and a bounded degree of precision. +type Histogram struct { + lowestTrackableValue int64 + highestTrackableValue int64 + unitMagnitude int64 + significantFigures int64 + subBucketHalfCountMagnitude int32 + subBucketHalfCount int32 + subBucketMask int64 + subBucketCount int32 + bucketCount int32 + countsLen int32 + totalCount int64 + counts []int64 +} + +// New returns a new Histogram instance capable of tracking values in the given +// range and with the given amount of precision. +func New(minValue, maxValue int64, sigfigs int) *Histogram { + if sigfigs < 1 || 5 < sigfigs { + panic(fmt.Errorf("sigfigs must be [1,5] (was %d)", sigfigs)) + } + + largestValueWithSingleUnitResolution := 2 * math.Pow10(sigfigs) + subBucketCountMagnitude := int32(math.Ceil(math.Log2(float64(largestValueWithSingleUnitResolution)))) + + subBucketHalfCountMagnitude := subBucketCountMagnitude + if subBucketHalfCountMagnitude < 1 { + subBucketHalfCountMagnitude = 1 + } + subBucketHalfCountMagnitude-- + + unitMagnitude := int32(math.Floor(math.Log2(float64(minValue)))) + if unitMagnitude < 0 { + unitMagnitude = 0 + } + + subBucketCount := int32(math.Pow(2, float64(subBucketHalfCountMagnitude)+1)) + + subBucketHalfCount := subBucketCount / 2 + subBucketMask := int64(subBucketCount-1) << uint(unitMagnitude) + + // determine exponent range needed to support the trackable value with no + // overflow: + smallestUntrackableValue := int64(subBucketCount) << uint(unitMagnitude) + bucketsNeeded := int32(1) + for smallestUntrackableValue < maxValue { + smallestUntrackableValue <<= 1 + bucketsNeeded++ + } + + bucketCount := bucketsNeeded + countsLen := (bucketCount + 1) * (subBucketCount / 2) + + return &Histogram{ + lowestTrackableValue: minValue, + highestTrackableValue: maxValue, + unitMagnitude: int64(unitMagnitude), + significantFigures: int64(sigfigs), + subBucketHalfCountMagnitude: subBucketHalfCountMagnitude, + subBucketHalfCount: subBucketHalfCount, + subBucketMask: subBucketMask, + subBucketCount: subBucketCount, + bucketCount: bucketCount, + countsLen: countsLen, + totalCount: 0, + counts: make([]int64, countsLen), + } +} + +// ByteSize returns an estimate of the amount of memory allocated to the +// histogram in bytes. +// +// N.B.: This does not take into account the overhead for slices, which are +// small, constant, and specific to the compiler version. +func (h *Histogram) ByteSize() int { + return 6*8 + 5*4 + len(h.counts)*8 +} + +// Merge merges the data stored in the given histogram with the receiver, +// returning the number of recorded values which had to be dropped. +func (h *Histogram) Merge(from *Histogram) (dropped int64) { + i := from.rIterator() + for i.next() { + v := i.valueFromIdx + c := i.countAtIdx + + if h.RecordValues(v, c) != nil { + dropped += c + } + } + + return +} + +// TotalCount returns total number of values recorded. +func (h *Histogram) TotalCount() int64 { + return h.totalCount +} + +// Max returns the approximate maximum recorded value. +func (h *Histogram) Max() int64 { + var max int64 + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 { + max = i.highestEquivalentValue + } + } + return h.highestEquivalentValue(max) +} + +// Min returns the approximate minimum recorded value. +func (h *Histogram) Min() int64 { + var min int64 + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 && min == 0 { + min = i.highestEquivalentValue + break + } + } + return h.lowestEquivalentValue(min) +} + +// Mean returns the approximate arithmetic mean of the recorded values. +func (h *Histogram) Mean() float64 { + if h.totalCount == 0 { + return 0 + } + var total int64 + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 { + total += i.countAtIdx * h.medianEquivalentValue(i.valueFromIdx) + } + } + return float64(total) / float64(h.totalCount) +} + +// StdDev returns the approximate standard deviation of the recorded values. +func (h *Histogram) StdDev() float64 { + if h.totalCount == 0 { + return 0 + } + + mean := h.Mean() + geometricDevTotal := 0.0 + + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 { + dev := float64(h.medianEquivalentValue(i.valueFromIdx)) - mean + geometricDevTotal += (dev * dev) * float64(i.countAtIdx) + } + } + + return math.Sqrt(geometricDevTotal / float64(h.totalCount)) +} + +// Reset deletes all recorded values and restores the histogram to its original +// state. +func (h *Histogram) Reset() { + h.totalCount = 0 + for i := range h.counts { + h.counts[i] = 0 + } +} + +// RecordValue records the given value, returning an error if the value is out +// of range. +func (h *Histogram) RecordValue(v int64) error { + return h.RecordValues(v, 1) +} + +// RecordCorrectedValue records the given value, correcting for stalls in the +// recording process. This only works for processes which are recording values +// at an expected interval (e.g., doing jitter analysis). Processes which are +// recording ad-hoc values (e.g., latency for incoming requests) can't take +// advantage of this. +func (h *Histogram) RecordCorrectedValue(v, expectedInterval int64) error { + if err := h.RecordValue(v); err != nil { + return err + } + + if expectedInterval <= 0 || v <= expectedInterval { + return nil + } + + missingValue := v - expectedInterval + for missingValue >= expectedInterval { + if err := h.RecordValue(missingValue); err != nil { + return err + } + missingValue -= expectedInterval + } + + return nil +} + +// RecordValues records n occurrences of the given value, returning an error if +// the value is out of range. +func (h *Histogram) RecordValues(v, n int64) error { + idx := h.countsIndexFor(v) + if idx < 0 || int(h.countsLen) <= idx { + return fmt.Errorf("value %d is too large to be recorded", v) + } + h.counts[idx] += n + h.totalCount += n + + return nil +} + +// ValueAtQuantile returns the recorded value at the given quantile (0..100). +func (h *Histogram) ValueAtQuantile(q float64) int64 { + if q > 100 { + q = 100 + } + + total := int64(0) + countAtPercentile := int64(((q / 100) * float64(h.totalCount)) + 0.5) + + i := h.iterator() + for i.next() { + total += i.countAtIdx + if total >= countAtPercentile { + return h.highestEquivalentValue(i.valueFromIdx) + } + } + + return 0 +} + +// CumulativeDistribution returns an ordered list of brackets of the +// distribution of recorded values. +func (h *Histogram) CumulativeDistribution() []Bracket { + var result []Bracket + + i := h.pIterator(1) + for i.next() { + result = append(result, Bracket{ + Quantile: i.percentile, + Count: i.countToIdx, + ValueAt: i.highestEquivalentValue, + }) + } + + return result +} + +// SignificantFigures returns the significant figures used to create the +// histogram +func (h *Histogram) SignificantFigures() int64 { + return h.significantFigures +} + +// LowestTrackableValue returns the lower bound on values that will be added +// to the histogram +func (h *Histogram) LowestTrackableValue() int64 { + return h.lowestTrackableValue +} + +// HighestTrackableValue returns the upper bound on values that will be added +// to the histogram +func (h *Histogram) HighestTrackableValue() int64 { + return h.highestTrackableValue +} + +// Histogram bar for plotting +type Bar struct { + From, To, Count int64 +} + +// Pretty print as csv for easy plotting +func (b Bar) String() string { + return fmt.Sprintf("%v, %v, %v\n", b.From, b.To, b.Count) +} + +// Distribution returns an ordered list of bars of the +// distribution of recorded values, counts can be normalized to a probability +func (h *Histogram) Distribution() (result []Bar) { + i := h.iterator() + for i.next() { + result = append(result, Bar{ + Count: i.countAtIdx, + From: h.lowestEquivalentValue(i.valueFromIdx), + To: i.highestEquivalentValue, + }) + } + + return result +} + +// Equals returns true if the two Histograms are equivalent, false if not. +func (h *Histogram) Equals(other *Histogram) bool { + switch { + case + h.lowestTrackableValue != other.lowestTrackableValue, + h.highestTrackableValue != other.highestTrackableValue, + h.unitMagnitude != other.unitMagnitude, + h.significantFigures != other.significantFigures, + h.subBucketHalfCountMagnitude != other.subBucketHalfCountMagnitude, + h.subBucketHalfCount != other.subBucketHalfCount, + h.subBucketMask != other.subBucketMask, + h.subBucketCount != other.subBucketCount, + h.bucketCount != other.bucketCount, + h.countsLen != other.countsLen, + h.totalCount != other.totalCount: + return false + default: + for i, c := range h.counts { + if c != other.counts[i] { + return false + } + } + } + return true +} + +// Export returns a snapshot view of the Histogram. This can be later passed to +// Import to construct a new Histogram with the same state. +func (h *Histogram) Export() *Snapshot { + return &Snapshot{ + LowestTrackableValue: h.lowestTrackableValue, + HighestTrackableValue: h.highestTrackableValue, + SignificantFigures: h.significantFigures, + Counts: append([]int64(nil), h.counts...), // copy + } +} + +// Import returns a new Histogram populated from the Snapshot data (which the +// caller must stop accessing). +func Import(s *Snapshot) *Histogram { + h := New(s.LowestTrackableValue, s.HighestTrackableValue, int(s.SignificantFigures)) + h.counts = s.Counts + totalCount := int64(0) + for i := int32(0); i < h.countsLen; i++ { + countAtIndex := h.counts[i] + if countAtIndex > 0 { + totalCount += countAtIndex + } + } + h.totalCount = totalCount + return h +} + +func (h *Histogram) iterator() *iterator { + return &iterator{ + h: h, + subBucketIdx: -1, + } +} + +func (h *Histogram) rIterator() *rIterator { + return &rIterator{ + iterator: iterator{ + h: h, + subBucketIdx: -1, + }, + } +} + +func (h *Histogram) pIterator(ticksPerHalfDistance int32) *pIterator { + return &pIterator{ + iterator: iterator{ + h: h, + subBucketIdx: -1, + }, + ticksPerHalfDistance: ticksPerHalfDistance, + } +} + +func (h *Histogram) sizeOfEquivalentValueRange(v int64) int64 { + bucketIdx := h.getBucketIndex(v) + subBucketIdx := h.getSubBucketIdx(v, bucketIdx) + adjustedBucket := bucketIdx + if subBucketIdx >= h.subBucketCount { + adjustedBucket++ + } + return int64(1) << uint(h.unitMagnitude+int64(adjustedBucket)) +} + +func (h *Histogram) valueFromIndex(bucketIdx, subBucketIdx int32) int64 { + return int64(subBucketIdx) << uint(int64(bucketIdx)+h.unitMagnitude) +} + +func (h *Histogram) lowestEquivalentValue(v int64) int64 { + bucketIdx := h.getBucketIndex(v) + subBucketIdx := h.getSubBucketIdx(v, bucketIdx) + return h.valueFromIndex(bucketIdx, subBucketIdx) +} + +func (h *Histogram) nextNonEquivalentValue(v int64) int64 { + return h.lowestEquivalentValue(v) + h.sizeOfEquivalentValueRange(v) +} + +func (h *Histogram) highestEquivalentValue(v int64) int64 { + return h.nextNonEquivalentValue(v) - 1 +} + +func (h *Histogram) medianEquivalentValue(v int64) int64 { + return h.lowestEquivalentValue(v) + (h.sizeOfEquivalentValueRange(v) >> 1) +} + +func (h *Histogram) getCountAtIndex(bucketIdx, subBucketIdx int32) int64 { + return h.counts[h.countsIndex(bucketIdx, subBucketIdx)] +} + +func (h *Histogram) countsIndex(bucketIdx, subBucketIdx int32) int32 { + bucketBaseIdx := (bucketIdx + 1) << uint(h.subBucketHalfCountMagnitude) + offsetInBucket := subBucketIdx - h.subBucketHalfCount + return bucketBaseIdx + offsetInBucket +} + +func (h *Histogram) getBucketIndex(v int64) int32 { + pow2Ceiling := bitLen(v | h.subBucketMask) + return int32(pow2Ceiling - int64(h.unitMagnitude) - + int64(h.subBucketHalfCountMagnitude+1)) +} + +func (h *Histogram) getSubBucketIdx(v int64, idx int32) int32 { + return int32(v >> uint(int64(idx)+int64(h.unitMagnitude))) +} + +func (h *Histogram) countsIndexFor(v int64) int { + bucketIdx := h.getBucketIndex(v) + subBucketIdx := h.getSubBucketIdx(v, bucketIdx) + return int(h.countsIndex(bucketIdx, subBucketIdx)) +} + +type iterator struct { + h *Histogram + bucketIdx, subBucketIdx int32 + countAtIdx, countToIdx, valueFromIdx int64 + highestEquivalentValue int64 +} + +func (i *iterator) next() bool { + if i.countToIdx >= i.h.totalCount { + return false + } + + // increment bucket + i.subBucketIdx++ + if i.subBucketIdx >= i.h.subBucketCount { + i.subBucketIdx = i.h.subBucketHalfCount + i.bucketIdx++ + } + + if i.bucketIdx >= i.h.bucketCount { + return false + } + + i.countAtIdx = i.h.getCountAtIndex(i.bucketIdx, i.subBucketIdx) + i.countToIdx += i.countAtIdx + i.valueFromIdx = i.h.valueFromIndex(i.bucketIdx, i.subBucketIdx) + i.highestEquivalentValue = i.h.highestEquivalentValue(i.valueFromIdx) + + return true +} + +type rIterator struct { + iterator + countAddedThisStep int64 +} + +func (r *rIterator) next() bool { + for r.iterator.next() { + if r.countAtIdx != 0 { + r.countAddedThisStep = r.countAtIdx + return true + } + } + return false +} + +type pIterator struct { + iterator + seenLastValue bool + ticksPerHalfDistance int32 + percentileToIteratorTo float64 + percentile float64 +} + +func (p *pIterator) next() bool { + if !(p.countToIdx < p.h.totalCount) { + if p.seenLastValue { + return false + } + + p.seenLastValue = true + p.percentile = 100 + + return true + } + + if p.subBucketIdx == -1 && !p.iterator.next() { + return false + } + + var done = false + for !done { + currentPercentile := (100.0 * float64(p.countToIdx)) / float64(p.h.totalCount) + if p.countAtIdx != 0 && p.percentileToIteratorTo <= currentPercentile { + p.percentile = p.percentileToIteratorTo + halfDistance := math.Trunc(math.Pow(2, math.Trunc(math.Log2(100.0/(100.0-p.percentileToIteratorTo)))+1)) + percentileReportingTicks := float64(p.ticksPerHalfDistance) * halfDistance + p.percentileToIteratorTo += 100.0 / percentileReportingTicks + return true + } + done = !p.iterator.next() + } + + return true +} + +func bitLen(x int64) (n int64) { + for ; x >= 0x8000; x >>= 16 { + n += 16 + } + if x >= 0x80 { + x >>= 8 + n += 8 + } + if x >= 0x8 { + x >>= 4 + n += 4 + } + if x >= 0x2 { + x >>= 2 + n += 2 + } + if x >= 0x1 { + n++ + } + return +} diff --git a/vendor/github.com/codahale/hdrhistogram/window.go b/vendor/github.com/codahale/hdrhistogram/window.go new file mode 100644 index 000000000..dc43612a4 --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/window.go @@ -0,0 +1,45 @@ +package hdrhistogram + +// A WindowedHistogram combines histograms to provide windowed statistics. +type WindowedHistogram struct { + idx int + h []Histogram + m *Histogram + + Current *Histogram +} + +// NewWindowed creates a new WindowedHistogram with N underlying histograms with +// the given parameters. +func NewWindowed(n int, minValue, maxValue int64, sigfigs int) *WindowedHistogram { + w := WindowedHistogram{ + idx: -1, + h: make([]Histogram, n), + m: New(minValue, maxValue, sigfigs), + } + + for i := range w.h { + w.h[i] = *New(minValue, maxValue, sigfigs) + } + w.Rotate() + + return &w +} + +// Merge returns a histogram which includes the recorded values from all the +// sections of the window. +func (w *WindowedHistogram) Merge() *Histogram { + w.m.Reset() + for _, h := range w.h { + w.m.Merge(&h) + } + return w.m +} + +// Rotate resets the oldest histogram and rotates it to be used as the current +// histogram. +func (w *WindowedHistogram) Rotate() { + w.idx++ + w.Current = &w.h[w.idx%len(w.h)] + w.Current.Reset() +} diff --git a/vendor/github.com/crossdock/crossdock-go/LICENSE b/vendor/github.com/crossdock/crossdock-go/LICENSE new file mode 100644 index 000000000..2a25a2cd7 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/crossdock/crossdock-go/assert/assertion_forward.go b/vendor/github.com/crossdock/crossdock-go/assert/assertion_forward.go new file mode 100644 index 000000000..ca06fe3da --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/assert/assertion_forward.go @@ -0,0 +1,387 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/crossdock/crossdock-go/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND +*/ + +package assert + +import ( + + http "net/http" + url "net/url" + time "time" +) + + +// Condition uses a Comparison to assert a complex condition. +func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { + return Condition(a.t, comp, msgAndArgs...) +} + + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") +// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + return Contains(a.t, s, contains, msgAndArgs...) +} + + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Empty(obj) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + return Empty(a.t, object, msgAndArgs...) +} + + +// Equal asserts that two objects are equal. +// +// a.Equal(123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return Equal(a.t, expected, actual, msgAndArgs...) +} + + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + return EqualError(a.t, theError, errString, msgAndArgs...) +} + + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return EqualValues(a.t, expected, actual, msgAndArgs...) +} + + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Error(err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { + return Error(a.t, err, msgAndArgs...) +} + + +// Exactly asserts that two objects are equal is value and type. +// +// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return Exactly(a.t, expected, actual, msgAndArgs...) +} + + +// Fail reports a failure through +func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + return Fail(a.t, failureMessage, msgAndArgs...) +} + + +// FailNow fails test +func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { + return FailNow(a.t, failureMessage, msgAndArgs...) +} + + +// False asserts that the specified value is false. +// +// a.False(myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { + return False(a.t, value, msgAndArgs...) +} + + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { + return HTTPBodyContains(a.t, handler, method, url, values, str) +} + + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { + return HTTPBodyNotContains(a.t, handler, method, url, values, str) +} + + +// HTTPError asserts that a specified handler returns an error status code. +// +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool { + return HTTPError(a.t, handler, method, url, values) +} + + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool { + return HTTPRedirect(a.t, handler, method, url, values) +} + + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool { + return HTTPSuccess(a.t, handler, method, url, values) +} + + +// Implements asserts that an object is implemented by the specified interface. +// +// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") +func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + return Implements(a.t, interfaceObject, object, msgAndArgs...) +} + + +// InDelta asserts that the two numerals are within delta of each other. +// +// a.InDelta(math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InDelta(a.t, expected, actual, delta, msgAndArgs...) +} + + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) +} + + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) +} + + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) +} + + +// IsType asserts that the specified objects are of the same type. +func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + return IsType(a.t, expectedType, object, msgAndArgs...) +} + + +// JSONEq asserts that two JSON strings are equivalent. +// +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { + return JSONEq(a.t, expected, actual, msgAndArgs...) +} + + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// a.Len(mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + return Len(a.t, object, length, msgAndArgs...) +} + + +// Nil asserts that the specified object is nil. +// +// a.Nil(err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + return Nil(a.t, object, msgAndArgs...) +} + + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { + return NoError(a.t, err, msgAndArgs...) +} + + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + return NotContains(a.t, s, contains, msgAndArgs...) +} + + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + return NotEmpty(a.t, object, msgAndArgs...) +} + + +// NotEqual asserts that the specified values are NOT equal. +// +// a.NotEqual(obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + return NotEqual(a.t, expected, actual, msgAndArgs...) +} + + +// NotNil asserts that the specified object is not nil. +// +// a.NotNil(err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + return NotNil(a.t, object, msgAndArgs...) +} + + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanics(func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + return NotPanics(a.t, f, msgAndArgs...) +} + + +// NotRegexp asserts that a specified regexp does not match a string. +// +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + return NotRegexp(a.t, rx, str, msgAndArgs...) +} + + +// NotZero asserts that i is not the zero value for its type and returns the truth. +func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { + return NotZero(a.t, i, msgAndArgs...) +} + + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panics(func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + return Panics(a.t, f, msgAndArgs...) +} + + +// Regexp asserts that a specified regexp matches a string. +// +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + return Regexp(a.t, rx, str, msgAndArgs...) +} + + +// True asserts that the specified value is true. +// +// a.True(myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { + return True(a.t, value, msgAndArgs...) +} + + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) +} + + +// Zero asserts that i is the zero value for its type and returns the truth. +func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { + return Zero(a.t, i, msgAndArgs...) +} diff --git a/vendor/github.com/crossdock/crossdock-go/assert/assertions.go b/vendor/github.com/crossdock/crossdock-go/assert/assertions.go new file mode 100644 index 000000000..04660ee8c --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/assert/assertions.go @@ -0,0 +1,1072 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +package assert + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "math" + "reflect" + "regexp" + "runtime" + "strings" + "time" + "unicode" + "unicode/utf8" + + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" +) + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +// Comparison a custom function that returns true on success and false on failure +type Comparison func() (success bool) + +/* + Helper functions +*/ + +// ObjectsAreEqual determines if two objects are considered equal. +// +// This function does no assertion of any kind. +func ObjectsAreEqual(expected, actual interface{}) bool { + + if expected == nil || actual == nil { + return expected == actual + } + + return reflect.DeepEqual(expected, actual) + +} + +// ObjectsAreEqualValues gets whether two objects are equal, or if their +// values are equal. +func ObjectsAreEqualValues(expected, actual interface{}) bool { + if ObjectsAreEqual(expected, actual) { + return true + } + + actualType := reflect.TypeOf(actual) + if actualType == nil { + return false + } + expectedValue := reflect.ValueOf(expected) + if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { + // Attempt comparison after type conversion + return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) + } + + return false +} + +/* CallerInfo is necessary because the assert functions use the testing object +internally, causing it to print the file:line of the assert method, rather than +where the problem actually occurred in calling code.*/ + +// CallerInfo returns an array of strings containing the file and line number +// of each stack frame leading from the assert call that failed back to the +// current test entry point. +func CallerInfo() []string { + // Our package name, we use this to find stacktraces boundaries. + const ourPackage = "github.com/crossdock/crossdock-go" + + // 16 is how many traces we want to collect, its the call stack between + // CallerInfo and up toward the program entry point. As there is about 7 + // frames above CallerInfo() until the usercode, this leaves about 8 frames + // for the returned stacktrace. The goal is to provide an informative error + // msg, not a scrolling game. + st := make([]uintptr, 16) + + // And here we already skip 2 stack frames, the Callers function frame and + // our own CallerInfo frame. + stDepth := runtime.Callers(2, st) + + var callers []string + stIndex := 0 + + // We walk up the stack until we are outside our package. + for ; stIndex < stDepth; stIndex++ { + pc := st[stIndex] + + f := runtime.FuncForPC(pc) + if f == nil { // can't do much without infos. + continue + } + fname := f.Name() + + // Ignoring this. + if fname == "" { + continue + } + + // As long as we are in our package, we continue. + if strings.Contains(fname, ourPackage) { + continue + } + + break + } + + // We walk up the stack until we reach the entry point of the current test, + // collecting traces on the way. + for ; stIndex < stDepth; stIndex++ { + pc := st[stIndex] + f := runtime.FuncForPC(pc) + if f == nil { // can't do much without infos. + continue + } + + fname := f.Name() + + // The program counter here is in fact the return pc right after the + // call. If we want the location of the call itself we have to back up + // the pc inside the boundary of the call instruction. The exception is + // if the previous pc (st[stIndex-1]) is the sigpanic function, in this + // case pc is the program counter of the faulting instruction, but we + // should not have this case here (and go doen't make it easy to get + // the address of the sigpanic function anyway). + if pc > f.Entry() { + pc-- + } + + file, line := f.FileLine(pc) + + // If we are back in our package, we stop, as we are most likely the + // entry point calling the user test function. + if strings.Contains(fname, ourPackage) { + break + } + + // We get rid of the fully qualified package name. + fname = fname[strings.LastIndexByte(fname, '.')+1:] + + // We can happily collect the trace. + callers = append(callers, fmt.Sprintf("%s() %s:%d", fname, file, line)) + + // If it looks like a test function, we stop the walk here. + if isTest(fname, "Test") || + isTest(fname, "Benchmark") || + isTest(fname, "Example") { + break + } + } + return callers +} + +// Stolen from the `go test` tool. +// isTest tells whether name looks like a test (or benchmark, according to prefix). +// It is a Test (say) if there is a character after Test that is not a lower-case letter. +// We don't want TesticularCancer. +func isTest(name, prefix string) bool { + if !strings.HasPrefix(name, prefix) { + return false + } + if len(name) == len(prefix) { // "Test" is ok + return true + } + rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) + return !unicode.IsLower(rune) +} + +// getWhitespaceString returns a string that is long enough to overwrite the default +// output from the go testing framework. +func getWhitespaceString() string { + + _, file, line, ok := runtime.Caller(1) + if !ok { + return "" + } + parts := strings.Split(file, "/") + file = parts[len(parts)-1] + + return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) + +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + return msgAndArgs[0].(string) + } + if len(msgAndArgs) > 1 { + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) + } + return "" +} + +// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's +// test printing (see inner comment for specifics) +func indentMessageLines(message string, tabs int) string { + outBuf := new(bytes.Buffer) + + for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { + if i != 0 { + outBuf.WriteRune('\n') + } + for ii := 0; ii < tabs; ii++ { + outBuf.WriteRune('\t') + // Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter + // by 1 prematurely. + if ii == 0 && i > 0 { + ii++ + } + } + outBuf.WriteString(scanner.Text()) + } + + return outBuf.String() +} + +type failNower interface { + FailNow() +} + +// FailNow fails test +func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + Fail(t, failureMessage, msgAndArgs...) + + // We cannot extend TestingT with FailNow() and + // maintain backwards compatibility, so we fallback + // to panicking when FailNow is not available in + // TestingT. + // See issue #263 + + if t, ok := t.(failNower); ok { + t.FailNow() + } else { + panic("test failed and t is missing `FailNow()`") + } + return false +} + +// Fail reports a failure through +func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + + errorTrace := strings.Join(CallerInfo(), "\n\r\t\t\t") + if len(message) > 0 { + t.Errorf("\r%s\r\tError Trace:\t%s\n"+ + "\r\tError:%s\n"+ + "\r\tMessages:\t%s\n\r", + getWhitespaceString(), + errorTrace, + indentMessageLines(failureMessage, 2), + message) + } else { + t.Errorf("\r%s\r\tError Trace:\t%s\n"+ + "\r\tError:%s\n\r", + getWhitespaceString(), + errorTrace, + indentMessageLines(failureMessage, 2)) + } + + return false +} + +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") +func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + + interfaceType := reflect.TypeOf(interfaceObject).Elem() + + if !reflect.TypeOf(object).Implements(interfaceType) { + return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) + } + + return true + +} + +// IsType asserts that the specified objects are of the same type. +func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { + return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) + } + + return true +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqual(expected, actual) { + diff := diff(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)%s", expected, actual, diff), msgAndArgs...) + } + + return true + +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqualValues(expected, actual) { + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)", expected, actual), msgAndArgs...) + } + + return true + +} + +// Exactly asserts that two objects are equal is value and type. +// +// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...) + } + + return Equal(t, expected, actual, msgAndArgs...) + +} + +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(t, err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if !isNil(object) { + return true + } + return Fail(t, "Expected value not to be nil.", msgAndArgs...) +} + +// isNil checks if a specified object is nil or not, without Failing. +func isNil(object interface{}) bool { + if object == nil { + return true + } + + value := reflect.ValueOf(object) + kind := value.Kind() + if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + return true + } + + return false +} + +// Nil asserts that the specified object is nil. +// +// assert.Nil(t, err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if isNil(object) { + return true + } + return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) +} + +var numericZeros = []interface{}{ + int(0), + int8(0), + int16(0), + int32(0), + int64(0), + uint(0), + uint8(0), + uint16(0), + uint32(0), + uint64(0), + float32(0), + float64(0), +} + +// isEmpty gets whether the specified object is considered empty or not. +func isEmpty(object interface{}) bool { + + if object == nil { + return true + } else if object == "" { + return true + } else if object == false { + return true + } + + for _, v := range numericZeros { + if object == v { + return true + } + } + + objValue := reflect.ValueOf(object) + + switch objValue.Kind() { + case reflect.Map: + fallthrough + case reflect.Slice, reflect.Chan: + { + return (objValue.Len() == 0) + } + case reflect.Struct: + switch object.(type) { + case time.Time: + return object.(time.Time).IsZero() + } + case reflect.Ptr: + { + if objValue.IsNil() { + return true + } + switch object.(type) { + case *time.Time: + return object.(*time.Time).IsZero() + default: + return false + } + } + } + return false +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Empty(t, obj) +// +// Returns whether the assertion was successful (true) or not (false). +func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + pass := isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + + pass := !isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// getLen try to get length of object. +// return (false, 0) if impossible. +func getLen(x interface{}) (ok bool, length int) { + v := reflect.ValueOf(x) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + return true, v.Len() +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(t, mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { + ok, l := getLen(object) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) + } + + if l != length { + return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + } + return true +} + +// True asserts that the specified value is true. +// +// assert.True(t, myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { + + if value != true { + return Fail(t, "Should be true", msgAndArgs...) + } + + return true + +} + +// False asserts that the specified value is false. +// +// assert.False(t, myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { + + if value != false { + return Fail(t, "Should be false", msgAndArgs...) + } + + return true + +} + +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if ObjectsAreEqual(expected, actual) { + return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + } + + return true + +} + +// containsElement try loop over the list check if the list includes the element. +// return (false, false) if impossible. +// return (true, false) if element was not found. +// return (true, true) if element was found. +func includeElement(list interface{}, element interface{}) (ok, found bool) { + + listValue := reflect.ValueOf(list) + elementValue := reflect.ValueOf(element) + defer func() { + if e := recover(); e != nil { + ok = false + found = false + } + }() + + if reflect.TypeOf(list).Kind() == reflect.String { + return true, strings.Contains(listValue.String(), elementValue.String()) + } + + if reflect.TypeOf(list).Kind() == reflect.Map { + mapKeys := listValue.MapKeys() + for i := 0; i < len(mapKeys); i++ { + if ObjectsAreEqual(mapKeys[i].Interface(), element) { + return true, true + } + } + return true, false + } + + for i := 0; i < listValue.Len(); i++ { + if ObjectsAreEqual(listValue.Index(i).Interface(), element) { + return true, true + } + } + return true, false + +} + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") +// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") +// +// Returns whether the assertion was successful (true) or not (false). +func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if found { + return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// Condition uses a Comparison to assert a complex condition. +func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { + result := comp() + if !result { + Fail(t, "Condition failed!", msgAndArgs...) + } + return result +} + +// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics +// methods, and represents a simple func that takes no arguments, and returns nothing. +type PanicTestFunc func() + +// didPanic returns true if the function passed to it panics. Otherwise, it returns false. +func didPanic(f PanicTestFunc) (bool, interface{}) { + + didPanic := false + var message interface{} + func() { + + defer func() { + if message = recover(); message != nil { + didPanic = true + } + }() + + // call the target function + f() + + }() + + return didPanic, message + +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(t, func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(t, func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + if funcDidPanic, panicValue := didPanic(f); funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + + dt := expected.Sub(actual) + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +func toFloat(x interface{}) (float64, bool) { + var xf float64 + xok := true + + switch xn := x.(type) { + case uint8: + xf = float64(xn) + case uint16: + xf = float64(xn) + case uint32: + xf = float64(xn) + case uint64: + xf = float64(xn) + case int: + xf = float64(xn) + case int8: + xf = float64(xn) + case int16: + xf = float64(xn) + case int32: + xf = float64(xn) + case int64: + xf = float64(xn) + case float32: + xf = float64(xn) + case float64: + xf = float64(xn) + default: + xok = false + } + + return xf, xok +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + + af, aok := toFloat(expected) + bf, bok := toFloat(actual) + + if !aok || !bok { + return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) + } + + if math.IsNaN(af) { + return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...) + } + + if math.IsNaN(bf) { + return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) + } + + dt := af - bf + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta) + if !result { + return result + } + } + + return true +} + +func calcRelativeError(expected, actual interface{}) (float64, error) { + af, aok := toFloat(expected) + if !aok { + return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) + } + if af == 0 { + return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") + } + bf, bok := toFloat(actual) + if !bok { + return 0, fmt.Errorf("expected value %q cannot be converted to float", actual) + } + + return math.Abs(af-bf) / math.Abs(af), nil +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + actualEpsilon, err := calcRelativeError(expected, actual) + if err != nil { + return Fail(t, err.Error(), msgAndArgs...) + } + if actualEpsilon > epsilon { + return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ + " < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...) + } + + return true +} + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) + if !result { + return result + } + } + + return true +} + +/* + Errors +*/ + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { + if err != nil { + return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...) + } + + return true +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + if err == nil { + return Fail(t, "An error is expected but got nil. %s", message) + } + + return true +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { + + message := messageFromMsgAndArgs(msgAndArgs...) + if !NotNil(t, theError, "An error is expected but got nil. %s", message) { + return false + } + s := "An error with value \"%s\" is expected but got \"%s\". %s" + return Equal(t, errString, theError.Error(), + s, errString, theError.Error(), message) +} + +// matchRegexp return true if a specified regexp matches a string. +func matchRegexp(rx interface{}, str interface{}) bool { + + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr + } else { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + + return (r.FindStringIndex(fmt.Sprint(str)) != nil) + +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + + match := matchRegexp(rx, str) + + if !match { + Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) + } + + return match +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + match := matchRegexp(rx, str) + + if match { + Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) + } + + return !match + +} + +// Zero asserts that i is the zero value for its type and returns the truth. +func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// NotZero asserts that i is not the zero value for its type and returns the truth. +func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// JSONEq asserts that two JSON strings are equivalent. +// +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Returns whether the assertion was successful (true) or not (false). +func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { + var expectedJSONAsInterface, actualJSONAsInterface interface{} + + if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) + } + + if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) + } + + return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) +} + +func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { + t := reflect.TypeOf(v) + k := t.Kind() + + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() + } + return t, k +} + +// diff returns a diff of both values as long as both are of the same type and +// are a struct, map, slice or array. Otherwise it returns an empty string. +func diff(expected interface{}, actual interface{}) string { + if expected == nil || actual == nil { + return "" + } + + et, ek := typeAndKind(expected) + at, _ := typeAndKind(actual) + + if et != at { + return "" + } + + if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array { + return "" + } + + spew.Config.SortKeys = true + e := spew.Sdump(expected) + a := spew.Sdump(actual) + + diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(e), + B: difflib.SplitLines(a), + FromFile: "Expected", + FromDate: "", + ToFile: "Actual", + ToDate: "", + Context: 1, + }) + + return "\n\nDiff:\n" + diff +} diff --git a/vendor/github.com/crossdock/crossdock-go/assert/doc.go b/vendor/github.com/crossdock/crossdock-go/assert/doc.go new file mode 100644 index 000000000..a3081bcb1 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/assert/doc.go @@ -0,0 +1,68 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. +// +// Example Usage +// +// The following is a complete example using assert in a standard test function: +// import ( +// "testing" +// "github.com/crossdock/crossdock-go/assert" +// ) +// +// func TestSomething(t *testing.T) { +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } +// +// if you assert many times, use the format below: +// +// import ( +// "testing" +// "github.com/crossdock/crossdock-go/assert" +// ) +// +// func TestSomething(t *testing.T) { +// assert := assert.New(t) +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(a, b, "The two words should be the same.") +// } +// +// Assertions +// +// Assertions allow you to easily write test code, and are global funcs in the `assert` package. +// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// testing framework. This allows the assertion funcs to write the failings and other details to +// the correct place. +// +// Every assertion function also takes an optional string message as the final argument, +// allowing custom error messages to be appended to the message the assertion method outputs. +package assert diff --git a/vendor/github.com/crossdock/crossdock-go/assert/errors.go b/vendor/github.com/crossdock/crossdock-go/assert/errors.go new file mode 100644 index 000000000..fbd62a261 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/assert/errors.go @@ -0,0 +1,33 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +package assert + +import ( + "errors" +) + +// AnError is an error instance useful for testing. If the code does not care +// about error specifics, and only needs to return the error for example, this +// error should be used to make the test code more readable. +var AnError = errors.New("assert.AnError general error for testing") diff --git a/vendor/github.com/crossdock/crossdock-go/assert/forward_assertions.go b/vendor/github.com/crossdock/crossdock-go/assert/forward_assertions.go new file mode 100644 index 000000000..369aeee56 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/assert/forward_assertions.go @@ -0,0 +1,39 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +package assert + +// Assertions provides assertion methods around the +// TestingT interface. +type Assertions struct { + t TestingT +} + +// New makes a new Assertions object for the specified TestingT. +func New(t TestingT) *Assertions { + return &Assertions{ + t: t, + } +} + +//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl diff --git a/vendor/github.com/crossdock/crossdock-go/assert/http_assertions.go b/vendor/github.com/crossdock/crossdock-go/assert/http_assertions.go new file mode 100644 index 000000000..799bd0ea4 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/assert/http_assertions.go @@ -0,0 +1,129 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +package assert + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" +) + +// httpCode is a helper that returns HTTP code of the response. It returns -1 +// if building a new request fails. +func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) + if err != nil { + return -1 + } + handler(w, req) + return w.Code +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { + code := httpCode(handler, method, url, values) + if code == -1 { + return false + } + return code >= http.StatusOK && code <= http.StatusPartialContent +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { + code := httpCode(handler, method, url, values) + if code == -1 { + return false + } + return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { + code := httpCode(handler, method, url, values) + if code == -1 { + return false + } + return code >= http.StatusBadRequest +} + +// HTTPBody is a helper that returns HTTP body of the response. It returns +// empty string if building a new request fails. +func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) + if err != nil { + return "" + } + handler(w, req) + return w.Body.String() +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if !contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return contains +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if contains { + Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) + } + + return !contains +} diff --git a/vendor/github.com/crossdock/crossdock-go/call.go b/vendor/github.com/crossdock/crossdock-go/call.go new file mode 100644 index 000000000..7d6369d24 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/call.go @@ -0,0 +1,65 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import ( + "encoding/json" + "log" + "net/url" + "testing" + "time" + + "github.com/crossdock/crossdock-go/require" + "golang.org/x/net/context" + "golang.org/x/net/context/ctxhttp" +) + +// Call makes a GET request to the client +func Call(t *testing.T, clientURL string, behavior string, args url.Values) { + args.Set("behavior", behavior) + u, err := url.Parse(clientURL) + require.NoError(t, err, "failed to parse URL") + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + u.RawQuery = args.Encode() + log.Println("GET", u.String()) + res, err := ctxhttp.Get(ctx, nil, u.String()) + + require.NoError(t, err, "request %v failed", args) + defer res.Body.Close() + + var results []Entry + require.NoError(t, json.NewDecoder(res.Body).Decode(&results), + "failed to decode response for %v", args) + + for _, result := range results { + if result.Status() != Passed && result.Status() != Skipped { + output := result.Output() + + delete(result, statusKey) + delete(result, outputKey) + + t.Errorf("request %v failed: tags: %v; output: %s", args, result, output) + } + } +} diff --git a/vendor/github.com/crossdock/crossdock-go/client.go b/vendor/github.com/crossdock/crossdock-go/client.go new file mode 100644 index 000000000..2fcbc3580 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/client.go @@ -0,0 +1,91 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import ( + "encoding/json" + "log" + "net/http" + "net/url" +) + +// BehaviorFunc executes a set of tests against T +type BehaviorFunc func(t T) + +// Behaviors is a map of BehaviorFuncs to dispatch to +type Behaviors map[string]BehaviorFunc + +// BehaviorParam is the url param representing the test to run +const BehaviorParam = "behavior" + +// Start begins a blocking Crossdock client +func Start(behaviors Behaviors) { + http.Handle("/", Handler(behaviors, false)) + log.Fatal(http.ListenAndServe(":8080", nil)) +} + +// Handler returns an http.Handler that dispatches to functions defined in behaviors map. +// If failOnUnknown is true, a behavior that is not in the behaviors map will cause the +// handler to return an error status. Otherwise, the handler returns skipped status. +func Handler(behaviors Behaviors, failOnUnknown bool) http.Handler { + return requestHandler{behaviors: behaviors, failOnUnknown: failOnUnknown} +} + +type requestHandler struct { + behaviors Behaviors + failOnUnknown bool +} + +func (h requestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if r.Method == "HEAD" { + w.Header().Add("Content-Length", "0") + return + } + params := extractParams(r.URL.Query()) + entries := Run(params, func(t T) { + behavior := h.behaviors[t.Behavior()] + if behavior == nil { + if h.failOnUnknown { + t.Errorf("unknown behavior %q", t.Behavior()) + } else { + t.Skipf("unknown behavior %q", t.Behavior()) + } + return + } + behavior(t) + }) + + enc := json.NewEncoder(w) + if err := enc.Encode(entries); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +// extractParams returns a map of params from url values +func extractParams(p url.Values) Params { + params := Params{} + for k, l := range p { + for _, v := range l { + params[k] = v + } + } + return params +} diff --git a/vendor/github.com/crossdock/crossdock-go/combinations.go b/vendor/github.com/crossdock/crossdock-go/combinations.go new file mode 100644 index 000000000..f3d8b118e --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/combinations.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import "sort" + +// Combinations takes a map from axis name to list of values for that axis and +// returns a collection of entries which contain all combinations of each axis +// value with every other axis' values. +func Combinations(axes map[string][]string) []map[string]string { + // sort the names to get deterministic ordering + names := make([]string, 0, len(axes)) + for name := range axes { + names = append(names, name) + } + sort.Strings(names) + + var xs []axis + for _, name := range names { + xs = append(xs, axis{name, axes[name]}) + } + return axisCombinations(xs) +} + +func axisCombinations(axes []axis) []map[string]string { + if len(axes) == 0 { + return nil + } + + if len(axes) == 1 { + return axes[0].entries() + } + + var entries []map[string]string + for _, remaining := range axisCombinations(axes[1:]) { + for _, entry := range axes[0].entries() { + for k, v := range remaining { + entry[k] = v + } + entries = append(entries, entry) + } + } + + return entries +} + +type axis struct { + name string + values []string +} + +func (x axis) entries() []map[string]string { + items := make([]map[string]string, len(x.values)) + for i, value := range x.values { + items[i] = map[string]string{x.name: value} + } + return items +} diff --git a/vendor/github.com/crossdock/crossdock-go/doc.go b/vendor/github.com/crossdock/crossdock-go/doc.go new file mode 100644 index 000000000..c6d716061 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/doc.go @@ -0,0 +1,37 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Package crossdock implements the machinery for writing behaviors in a way +// similar to unit tests. +// +// func MyBehavior(s behavior.Sink, p behavior.Params) { +// if p.Param("something") != "foo" { +// behavior.Failf(s, "expected foo, got %v", p.Param("something")) +// } +// behavior.Successf(s, "success") +// } +// +// Sinks can be obtained using the Run function. Sinks are not valid outside +// the Run context. +// +// entries := behavior.Run(func(s Sink) { +// MyBehavior(s, someParams) +// }) +package crossdock diff --git a/vendor/github.com/crossdock/crossdock-go/entry.go b/vendor/github.com/crossdock/crossdock-go/entry.go new file mode 100644 index 000000000..779ecbd3f --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/entry.go @@ -0,0 +1,62 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import "fmt" + +// Status represents the result of running a behavior. +type Status string + +// Different valid Statuses. +const ( + Passed Status = "passed" + Skipped Status = "skipped" + Failed Status = "failed" +) + +const ( + statusKey = "status" + outputKey = "output" +) + +// Entry is the most basic form of a test result. +type Entry map[string]interface{} + +// Status returns the Status stored in the Entry. +func (e Entry) Status() Status { + switch v := e[statusKey].(type) { + case string: + return Status(v) + case Status: + return v + default: + panic(fmt.Sprintf("invalid status: %v", v)) + } +} + +// Output returns the output attached to the entry. +func (e Entry) Output() string { + s, ok := e[outputKey].(string) + if ok { + return s + } + return "" +} diff --git a/vendor/github.com/crossdock/crossdock-go/require/doc.go b/vendor/github.com/crossdock/crossdock-go/require/doc.go new file mode 100644 index 000000000..0da254c91 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/require/doc.go @@ -0,0 +1,51 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Package require implements the same assertions as the `assert` package but +// stops test execution when a test fails. +// +// Example Usage +// +// The following is a complete example using require in a standard test function: +// import ( +// "testing" +// "github.com/crossdock/crossdock-go/require" +// ) +// +// func TestSomething(t *testing.T) { +// +// var a string = "Hello" +// var b string = "Hello" +// +// require.Equal(t, a, b, "The two words should be the same.") +// +// } +// +// Assertions +// +// The `require` package have same global functions as in the `assert` package, +// but instead of returning a boolean result they call `t.FailNow()`. +// +// Every assertion function also takes an optional string message as the final argument, +// allowing custom error messages to be appended to the message the assertion method outputs. +package require diff --git a/vendor/github.com/crossdock/crossdock-go/require/forward_requirements.go b/vendor/github.com/crossdock/crossdock-go/require/forward_requirements.go new file mode 100644 index 000000000..3a25b246f --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/require/forward_requirements.go @@ -0,0 +1,39 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +package require + +// Assertions provides assertion methods around the +// TestingT interface. +type Assertions struct { + t TestingT +} + +// New makes a new Assertions object for the specified TestingT. +func New(t TestingT) *Assertions { + return &Assertions{ + t: t, + } +} + +//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl diff --git a/vendor/github.com/crossdock/crossdock-go/require/require.go b/vendor/github.com/crossdock/crossdock-go/require/require.go new file mode 100644 index 000000000..e099ec2c8 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/require/require.go @@ -0,0 +1,1338 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/crossdock/crossdock-go/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND +*/ + +package require + +import ( + + assert "github.com/crossdock/crossdock-go/assert" + http "net/http" + url "net/url" + time "time" +) + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Condition uses a Comparison to assert a complex condition. +func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { + if !assert.Condition(t, comp, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") +// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") +// +// Returns whether the assertion was successful (true) or not (false). +func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { + if !assert.Contains(t, s, contains, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Empty(t, obj) +// +// Returns whether the assertion was successful (true) or not (false). +func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if !assert.Empty(t, object, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if !assert.Equal(t, expected, actual, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { + if !assert.EqualError(t, theError, errString, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if !assert.EqualValues(t, expected, actual, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func Error(t TestingT, err error, msgAndArgs ...interface{}) { + if !assert.Error(t, err, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Exactly asserts that two objects are equal is value and type. +// +// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if !assert.Exactly(t, expected, actual, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Fail reports a failure through +func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { + if !assert.Fail(t, failureMessage, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// FailNow fails test +func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { + if !assert.FailNow(t, failureMessage, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// False asserts that the specified value is false. +// +// assert.False(t, myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func False(t TestingT, value bool, msgAndArgs ...interface{}) { + if !assert.False(t, value, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { + if !assert.HTTPBodyContains(t, handler, method, url, values, str) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { + if !assert.HTTPBodyNotContains(t, handler, method, url, values, str) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) { + if !assert.HTTPError(t, handler, method, url, values) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) { + if !assert.HTTPRedirect(t, handler, method, url, values) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) { + if !assert.HTTPSuccess(t, handler, method, url, values) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") +func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { + if !assert.Implements(t, interfaceObject, object, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { + if !assert.InDelta(t, expected, actual, delta, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// InDeltaSlice is the same as InDelta, except it compares two slices. +func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { + if !assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { + if !assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { + if !assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// IsType asserts that the specified objects are of the same type. +func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { + if !assert.IsType(t, expectedType, object, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// JSONEq asserts that two JSON strings are equivalent. +// +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Returns whether the assertion was successful (true) or not (false). +func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { + if !assert.JSONEq(t, expected, actual, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(t, mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { + if !assert.Len(t, object, length, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Nil asserts that the specified object is nil. +// +// assert.Nil(t, err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if !assert.Nil(t, object, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NoError(t TestingT, err error, msgAndArgs ...interface{}) { + if !assert.NoError(t, err, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { + if !assert.NotContains(t, s, contains, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if !assert.NotEmpty(t, object, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if !assert.NotEqual(t, expected, actual, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(t, err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { + if !assert.NotNil(t, object, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(t, func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + if !assert.NotPanics(t, f, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { + if !assert.NotRegexp(t, rx, str, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// NotZero asserts that i is not the zero value for its type and returns the truth. +func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { + if !assert.NotZero(t, i, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(t, func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { + if !assert.Panics(t, f, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { + if !assert.Regexp(t, rx, str, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// True asserts that the specified value is true. +// +// assert.True(t, myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func True(t TestingT, value bool, msgAndArgs ...interface{}) { + if !assert.True(t, value, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { + if !assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) { + t.FailNow() + } +} + + +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Zero asserts that i is the zero value for its type and returns the truth. +func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { + if !assert.Zero(t, i, msgAndArgs...) { + t.FailNow() + } +} diff --git a/vendor/github.com/crossdock/crossdock-go/require/require_forward.go b/vendor/github.com/crossdock/crossdock-go/require/require_forward.go new file mode 100644 index 000000000..800970628 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/require/require_forward.go @@ -0,0 +1,388 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/crossdock/crossdock-go/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND +*/ + +package require + +import ( + + assert "github.com/crossdock/crossdock-go/assert" + http "net/http" + url "net/url" + time "time" +) + + +// Condition uses a Comparison to assert a complex condition. +func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) { + Condition(a.t, comp, msgAndArgs...) +} + + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") +// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") +// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { + Contains(a.t, s, contains, msgAndArgs...) +} + + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Empty(obj) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { + Empty(a.t, object, msgAndArgs...) +} + + +// Equal asserts that two objects are equal. +// +// a.Equal(123, 123, "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + Equal(a.t, expected, actual, msgAndArgs...) +} + + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) { + EqualError(a.t, theError, errString, msgAndArgs...) +} + + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + EqualValues(a.t, expected, actual, msgAndArgs...) +} + + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Error(err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Error(err error, msgAndArgs ...interface{}) { + Error(a.t, err, msgAndArgs...) +} + + +// Exactly asserts that two objects are equal is value and type. +// +// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + Exactly(a.t, expected, actual, msgAndArgs...) +} + + +// Fail reports a failure through +func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) { + Fail(a.t, failureMessage, msgAndArgs...) +} + + +// FailNow fails test +func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) { + FailNow(a.t, failureMessage, msgAndArgs...) +} + + +// False asserts that the specified value is false. +// +// a.False(myBool, "myBool should be false") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { + False(a.t, value, msgAndArgs...) +} + + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { + HTTPBodyContains(a.t, handler, method, url, values, str) +} + + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { + HTTPBodyNotContains(a.t, handler, method, url, values, str) +} + + +// HTTPError asserts that a specified handler returns an error status code. +// +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) { + HTTPError(a.t, handler, method, url, values) +} + + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) { + HTTPRedirect(a.t, handler, method, url, values) +} + + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) { + HTTPSuccess(a.t, handler, method, url, values) +} + + +// Implements asserts that an object is implemented by the specified interface. +// +// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") +func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { + Implements(a.t, interfaceObject, object, msgAndArgs...) +} + + +// InDelta asserts that the two numerals are within delta of each other. +// +// a.InDelta(math.Pi, (22 / 7.0), 0.01) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { + InDelta(a.t, expected, actual, delta, msgAndArgs...) +} + + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { + InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) +} + + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { + InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) +} + + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { + InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) +} + + +// IsType asserts that the specified objects are of the same type. +func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { + IsType(a.t, expectedType, object, msgAndArgs...) +} + + +// JSONEq asserts that two JSON strings are equivalent. +// +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) { + JSONEq(a.t, expected, actual, msgAndArgs...) +} + + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// a.Len(mySlice, 3, "The size of slice is not 3") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) { + Len(a.t, object, length, msgAndArgs...) +} + + +// Nil asserts that the specified object is nil. +// +// a.Nil(err, "err should be nothing") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { + Nil(a.t, object, msgAndArgs...) +} + + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, actualObj, expectedObj) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { + NoError(a.t, err, msgAndArgs...) +} + + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") +// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") +// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { + NotContains(a.t, s, contains, msgAndArgs...) +} + + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { + NotEmpty(a.t, object, msgAndArgs...) +} + + +// NotEqual asserts that the specified values are NOT equal. +// +// a.NotEqual(obj1, obj2, "two objects shouldn't be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + NotEqual(a.t, expected, actual, msgAndArgs...) +} + + +// NotNil asserts that the specified object is not nil. +// +// a.NotNil(err, "err should be something") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { + NotNil(a.t, object, msgAndArgs...) +} + + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanics(func(){ +// RemainCalm() +// }, "Calling RemainCalm() should NOT panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { + NotPanics(a.t, f, msgAndArgs...) +} + + +// NotRegexp asserts that a specified regexp does not match a string. +// +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { + NotRegexp(a.t, rx, str, msgAndArgs...) +} + + +// NotZero asserts that i is not the zero value for its type and returns the truth. +func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) { + NotZero(a.t, i, msgAndArgs...) +} + + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panics(func(){ +// GoCrazy() +// }, "Calling GoCrazy() should panic") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { + Panics(a.t, f, msgAndArgs...) +} + + +// Regexp asserts that a specified regexp matches a string. +// +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { + Regexp(a.t, rx, str, msgAndArgs...) +} + + +// True asserts that the specified value is true. +// +// a.True(myBool, "myBool should be true") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { + True(a.t, value, msgAndArgs...) +} + + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { + WithinDuration(a.t, expected, actual, delta, msgAndArgs...) +} + + +// Zero asserts that i is the zero value for its type and returns the truth. +func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) { + Zero(a.t, i, msgAndArgs...) +} diff --git a/vendor/github.com/crossdock/crossdock-go/require/requirements.go b/vendor/github.com/crossdock/crossdock-go/require/requirements.go new file mode 100644 index 000000000..09c482fab --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/require/requirements.go @@ -0,0 +1,32 @@ +// Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell +// +// Please consider promoting this project if you find it useful. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +package require + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Errorf(format string, args ...interface{}) + FailNow() +} + +//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl diff --git a/vendor/github.com/crossdock/crossdock-go/run.go b/vendor/github.com/crossdock/crossdock-go/run.go new file mode 100644 index 000000000..bd4ff3347 --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/run.go @@ -0,0 +1,80 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import ( + "runtime" + "runtime/debug" +) + +// Run the given function inside a behavior context and return the entries +// logged by it. +// +// Functions like Fatalf won't work if the behavior is not executed inside a +// Run context. +func Run(params Params, f func(T)) []Entry { + behavior := params[BehaviorParam] + delete(params, BehaviorParam) + t := entryT{ + params: params, + behavior: behavior, + } + + done := make(chan struct{}) + + // We run the function inside a goroutine so that Fatalf can simply call + // runtime.Goexit to stop execution. + go func() { + defer func() { + if err := recover(); err != nil { + t.Errorf("%v\n%s", err, string(debug.Stack())) + } + close(done) + }() + + if runtime.Version() == "go1.5" { + // Gnarly workaround for https://github.com/golang/go/issues/12253 + // + // In short: A bug in Go 1.5 causes a specific form of comparison + // (runtime.assertE2T2) to leave an invalid pointer on the stack instead + // of zeroing it out. Usually, this isn't a problem because the function + // returns afterwards. However, we're consistently hitting a case where + // another function call is causing the stack to be grown while the + // pointer is still invalid. The scanner responsible for copying the + // stack as part of growing it runs into the invalid pointer and + // crashes. + // + // To work around this, we grow the stack significantly beforehand to + // reduce the likelihood of another growth attempt while the pointer is + // invalid. + growStack([1024]int64{}) + } + + f(&t) + }() + + <-done + return t.entries +} + +func growStack([1024]int64) { + // Nothing to do +} diff --git a/vendor/github.com/crossdock/crossdock-go/t.go b/vendor/github.com/crossdock/crossdock-go/t.go new file mode 100644 index 000000000..db05b190b --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/t.go @@ -0,0 +1,145 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import ( + "fmt" + "runtime" +) + +// T records the result of calling different behaviors. +type T interface { + Behavior() string + + // Look up a behavior parameter. + Param(key string) string + + // Tag adds the given key-value pair to all entries emitted by this T from + // this point onwards. + // + // If a key with the same name already exists, it will be overwritten. + // If value is empty, the tag will be deleted from all entries that follow. + // + // key MUST NOT be "stauts" or "output". + Tag(key, value string) + + // Log a failure and continue running the behavior. + Errorf(format string, args ...interface{}) + + // Log a skipped test and continue running the behavior. + Skipf(format string, args ...interface{}) + + // Log a success and continue running the behavior. + Successf(format string, args ...interface{}) + + // Log a failure and stop executing this behavior immediately. + Fatalf(format string, args ...interface{}) + + // Stop executing this behavior immediately. + FailNow() + + // Put logs an entry with the given status and output. Usually, you'll want + // to use Errorf, Skipf, Successf or Fatalf instead. + Put(status Status, output string) +} + +// Params represents args to a test +type Params map[string]string + +// entryT is a sink that keeps track of entries in-order +type entryT struct { + behavior string + params Params + tags map[string]string + entries []Entry +} + +// Behavior returns the test to dispatch on +func (t entryT) Behavior() string { + return t.behavior +} + +// Param gets a key out of the params map +func (t entryT) Param(key string) string { + return t.params[key] +} + +func (t *entryT) Tag(key, value string) { + if key == statusKey || key == outputKey { + panic(fmt.Sprintf("tag %q is reserved", key)) + } + + if t.tags == nil { + t.tags = make(map[string]string) + } + + if value == "" { + delete(t.tags, key) + } else { + t.tags[key] = value + } +} + +func (t *entryT) Put(status Status, output string) { + e := make(Entry) + e[statusKey] = status + e[outputKey] = output + for k, v := range t.tags { + e[k] = v + } + + t.entries = append(t.entries, e) +} + +func (*entryT) FailNow() { + // Exit this goroutine and call any deferred functions + runtime.Goexit() +} + +// Skipf records a skipped test. +// +// This may be called multiple times if multiple tests inside a behavior were +// skipped. +func (t *entryT) Skipf(format string, args ...interface{}) { + t.Put(Skipped, fmt.Sprintf(format, args...)) +} + +// Errorf records a failed test. +// +// This may be called multiple times if multiple tests inside a behavior +// failed. +func (t *entryT) Errorf(format string, args ...interface{}) { + t.Put(Failed, fmt.Sprintf(format, args...)) +} + +// Successf records a successful test. +// +// This may be called multiple times for multiple successful tests inside a +// behavior. +func (t *entryT) Successf(format string, args ...interface{}) { + t.Put(Passed, fmt.Sprintf(format, args...)) +} + +// Fatalf records a failed test and fails immediately +func (t *entryT) Fatalf(format string, args ...interface{}) { + t.Errorf(format, args...) + t.FailNow() +} diff --git a/vendor/github.com/crossdock/crossdock-go/testify.go b/vendor/github.com/crossdock/crossdock-go/testify.go new file mode 100644 index 000000000..7d6f9e1af --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/testify.go @@ -0,0 +1,640 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import ( + "fmt" + "time" + + "github.com/crossdock/crossdock-go/assert" + "github.com/crossdock/crossdock-go/require" +) + +// Assert builds an Assertions object that logs success or failure for all +// operations to the given T. The behavior will continue executing in case of +// failure. +// +// The following will log exactly len(tests) entries. +// +// assert := Assert(t) +// for _, tt := range tests { +// assert.Equals(tt.want, f(tt.give), "expected f(%v) == %v", tt.give, tt.want) +// } +func Assert(t T) Assertions { + return sinkAssertions{t, assert.New(sinkTestingT{t})} +} + +// Checks builds an Assertions object that logs only failures to the given T. +// The behavior will continue executing in case of failure. +// +// The following will log only as many entries as invalid test cases. +// +// checks := Checks(t) +// for _, tt := range tests { +// checks.Equals(tt.want, f(tt.give), "expected f(%v) == %v", tt.give, tt.want) +// } +func Checks(t T) Assertions { + return assert.New(sinkTestingT{t}) +} + +// Require builds an Assertions object that logs success or failure for all +// operations to the given T. Execution of the behavior will be terminated +// immediately on the first failing assertion. +// +// The following will log one entry for each successful test case starting at +// the first one and the first failure that is encountered. +// +// require := Require(t) +// for _, tt := range tests { +// require.Equals(tt.want, f(tt.give), "expected f(%v) == %v", tt.give, tt.want) +// } +func Require(t T) Assertions { + return sinkAssertions{t, requireAssertions{require.New(sinkTestingT{t})}} +} + +// Fatals builds an Assertions object that logs only failures to the given +// T. Execution of the behavior will be terminated immediately on the first +// failing assertion. +// +// The following will log the first failure encountered or nothing if all test +// cases were succesful. +// +// fatals := Fatals(t) +// for _, tt := range tests { +// fatals.Equals(tt.want, f(tt.give), "expected f(%v) == %v", tt.give, tt.want) +// } +func Fatals(t T) Assertions { + return requireAssertions{require.New(sinkTestingT{t})} +} + +// sinkTestingT adapts a crossdock.T into an {require,assert}.TestingT +type sinkTestingT struct{ t T } + +func (st sinkTestingT) FailNow() { st.t.FailNow() } + +func (st sinkTestingT) Errorf(format string, args ...interface{}) { + // We need to prepend a newline because the error message from testify + // always includes a \r at the start. + st.t.Errorf("\n"+format, args...) +} + +////////////////////////////////////////////////////////////////////////////// +// Assertions + +// Assertions provides helpers to assert conditions in crossdock behaviors. +// +// All assertions can include informative error messages formatted using +// fmt.Sprintf style, +// +// assert := Assert(t) +// assert.Contains(foo, "bar", "expected to find 'bar' in %q", foo) +// +// All assert operations return true if the condition was met and false +// otherwise. This allows gating operations that would otherwise panic behind +// preconditions. +// +// if assert.Error(t, err, "expected failure") { +// assert.Contains(t, err.Error(), "something went wrong", "error message mismatch") +// } +// +// Additionally, in case of failure, all Assertions make an attempt to +// provide a stack trace in the error message. +// +// Four kinds of Assertions objects are offered via the corresponding +// functions: +// +// Assert(T): All asserts will result in a success or failure being logged to the +// crossdock.T. Execution will continue on failure. +// +// Checks(T): Only failures will be logged to crossdock.T. Execution will +// continue on failure. +// +// Require(T): All asserts will result in a success or failure being logged to +// the crossdock.T. Execution of the behavior will be terminated immediately +// on failure. +// +// Fatals(t): Only failures will be logged to crossdock.T. Execution of the +// behavior will be temrinated immediately on failure. +// +// +--------+--------+---------+--------+ +// | Assert | Checks | Require | Fatals | +// +--------------------+--------+--------+---------+--------+ +// | Log on success | Yes | No | Yes | No | +// +--------------------+--------+--------+---------+--------+ +// | Continue execution | Yes | Yes | No | No | +// | on failure | | | | | +// +--------------------+--------+--------+---------+--------+ +// +type Assertions interface { + Condition(comp assert.Comparison, msgAndArgs ...interface{}) bool + Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool + Empty(object interface{}, msgAndArgs ...interface{}) bool + Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool + EqualError(theError error, errString string, msgAndArgs ...interface{}) bool + EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool + Error(err error, msgAndArgs ...interface{}) bool + Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool + Fail(failureMessage string, msgAndArgs ...interface{}) bool + FailNow(failureMessage string, msgAndArgs ...interface{}) bool + False(value bool, msgAndArgs ...interface{}) bool + Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool + InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool + InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool + InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool + InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool + IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool + JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool + Len(object interface{}, length int, msgAndArgs ...interface{}) bool + Nil(object interface{}, msgAndArgs ...interface{}) bool + NoError(err error, msgAndArgs ...interface{}) bool + NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool + NotEmpty(object interface{}, msgAndArgs ...interface{}) bool + NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool + NotNil(object interface{}, msgAndArgs ...interface{}) bool + NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) bool + NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool + NotZero(i interface{}, msgAndArgs ...interface{}) bool + Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) bool + Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool + True(value bool, msgAndArgs ...interface{}) bool + WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool + Zero(i interface{}, msgAndArgs ...interface{}) bool +} + +////////////////////////////////////////////////////////////////////////////// +// T => TestingT + +func formatMsgAndArgs(msgAndArgs []interface{}) string { + if len(msgAndArgs) == 0 { + return "" + } + if len(msgAndArgs) == 1 { + return msgAndArgs[0].(string) + } + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) +} + +type sinkAssertions struct { + // We need to wrap assert rather than using it as-is because we need to + // log success messages. + t T + a Assertions +} + +var _ Assertions = (*sinkAssertions)(nil) + +func (sa sinkAssertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) bool { + if sa.a.Condition(comp, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Contains(s, contains, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Empty(object, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Equal(expected, actual, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + if sa.a.EqualError(theError, errString, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if sa.a.EqualValues(expected, actual, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Error(err error, msgAndArgs ...interface{}) bool { + if sa.a.Error(err, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Exactly(expected, actual, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + if sa.a.Fail(failureMessage, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { + if sa.a.FailNow(failureMessage, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) False(value bool, msgAndArgs ...interface{}) bool { + if sa.a.False(value, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Implements(interfaceObject, object, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if sa.a.InDelta(expected, actual, delta, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if sa.a.InDeltaSlice(expected, actual, delta, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if sa.a.InEpsilon(expected, actual, epsilon, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if sa.a.InEpsilonSlice(expected, actual, delta, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if sa.a.IsType(expectedType, object, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { + if sa.a.JSONEq(expected, actual, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + if sa.a.Len(object, length, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Nil(object, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NoError(err error, msgAndArgs ...interface{}) bool { + if sa.a.NoError(err, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + if sa.a.NotContains(s, contains, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + if sa.a.NotEmpty(object, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if sa.a.NotEqual(expected, actual, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + if sa.a.NotNil(object, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) bool { + if sa.a.NotPanics(f, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if sa.a.NotRegexp(rx, str, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { + if sa.a.NotZero(i, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) bool { + if sa.a.Panics(f, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Regexp(rx, str, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) True(value bool, msgAndArgs ...interface{}) bool { + if sa.a.True(value, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + if sa.a.WithinDuration(expected, actual, delta, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +func (sa sinkAssertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { + if sa.a.Zero(i, msgAndArgs...) { + sa.t.Successf(formatMsgAndArgs(msgAndArgs)) + return true + } + return false +} + +////////////////////////////////////////////////////////////////////////////// +// Require + +// Adapts a require.Assertions into an Assertions. This simply returns true +// for all cases because execution just stops in case of failure. +type requireAssertions struct{ r *require.Assertions } + +var _ Assertions = (*requireAssertions)(nil) + +func (r requireAssertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) bool { + r.r.Condition(comp, msgAndArgs...) + return true +} + +func (r requireAssertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + r.r.Contains(s, contains, msgAndArgs...) + return true +} + +func (r requireAssertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + r.r.Empty(object, msgAndArgs...) + return true +} + +func (r requireAssertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + r.r.Equal(expected, actual, msgAndArgs...) + return true +} + +func (r requireAssertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + r.r.EqualError(theError, errString, msgAndArgs...) + return true +} + +func (r requireAssertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + r.r.EqualValues(expected, actual, msgAndArgs...) + return true +} + +func (r requireAssertions) Error(err error, msgAndArgs ...interface{}) bool { + r.r.Error(err, msgAndArgs...) + return true +} + +func (r requireAssertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + r.r.Exactly(expected, actual, msgAndArgs...) + return true +} + +func (r requireAssertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + r.r.Fail(failureMessage, msgAndArgs...) + return true +} + +func (r requireAssertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { + r.r.FailNow(failureMessage, msgAndArgs...) + return true +} + +func (r requireAssertions) False(value bool, msgAndArgs ...interface{}) bool { + r.r.False(value, msgAndArgs...) + return true +} + +func (r requireAssertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + r.r.Implements(interfaceObject, object, msgAndArgs...) + return true +} + +func (r requireAssertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + r.r.InDelta(expected, actual, delta, msgAndArgs...) + return true +} + +func (r requireAssertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + r.r.InDeltaSlice(expected, actual, delta, msgAndArgs...) + return true +} + +func (r requireAssertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + r.r.InEpsilon(expected, actual, epsilon, msgAndArgs...) + return true +} + +func (r requireAssertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + r.r.InEpsilonSlice(expected, actual, delta, msgAndArgs...) + return true +} + +func (r requireAssertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + r.r.IsType(expectedType, object, msgAndArgs...) + return true +} + +func (r requireAssertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { + r.r.JSONEq(expected, actual, msgAndArgs...) + return true +} + +func (r requireAssertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + r.r.Len(object, length, msgAndArgs...) + return true +} + +func (r requireAssertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + r.r.Nil(object, msgAndArgs...) + return true +} + +func (r requireAssertions) NoError(err error, msgAndArgs ...interface{}) bool { + r.r.NoError(err, msgAndArgs...) + return true +} + +func (r requireAssertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + r.r.NotContains(s, contains, msgAndArgs...) + return true +} + +func (r requireAssertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + r.r.NotEmpty(object, msgAndArgs...) + return true +} + +func (r requireAssertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + r.r.NotEqual(expected, actual, msgAndArgs...) + return true +} + +func (r requireAssertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + r.r.NotNil(object, msgAndArgs...) + return true +} + +func (r requireAssertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) bool { + r.r.NotPanics(f, msgAndArgs...) + return true +} + +func (r requireAssertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + r.r.NotRegexp(rx, str, msgAndArgs...) + return true +} + +func (r requireAssertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { + r.r.NotZero(i, msgAndArgs...) + return true +} + +func (r requireAssertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) bool { + r.r.Panics(f, msgAndArgs...) + return true +} + +func (r requireAssertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + r.r.Regexp(rx, str, msgAndArgs...) + return true +} + +func (r requireAssertions) True(value bool, msgAndArgs ...interface{}) bool { + r.r.True(value, msgAndArgs...) + return true +} + +func (r requireAssertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + r.r.WithinDuration(expected, actual, delta, msgAndArgs...) + return true +} + +func (r requireAssertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { + r.r.Zero(i, msgAndArgs...) + return true +} diff --git a/vendor/github.com/crossdock/crossdock-go/wait.go b/vendor/github.com/crossdock/crossdock-go/wait.go new file mode 100644 index 000000000..e9f48100e --- /dev/null +++ b/vendor/github.com/crossdock/crossdock-go/wait.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package crossdock + +import ( + "log" + "testing" + "time" + + "golang.org/x/net/context" + "golang.org/x/net/context/ctxhttp" +) + +// Wait sends attempts HEAD requests to url +func Wait(t *testing.T, url string, attempts int) { + ctx := context.Background() + + for a := 0; a < attempts; a++ { + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + + log.Println("HEAD", url) + _, err := ctxhttp.Head(ctx, nil, url) + if err == nil { + log.Println("Client is ready, beginning test...") + return + } + + sleepFor := 100 * time.Millisecond + log.Println(err, "- sleeping for", sleepFor) + time.Sleep(sleepFor) + } + + t.Fatalf("could not talk to client in %d attempts", attempts) +} diff --git a/vendor/github.com/go-kit/kit/log/LICENSE b/vendor/github.com/go-kit/kit/log/LICENSE new file mode 100644 index 000000000..9d83342ac --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Peter Bourgon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/go-kit/kit/log/deprecated_levels/levels.go b/vendor/github.com/go-kit/kit/log/deprecated_levels/levels.go new file mode 100644 index 000000000..a03421277 --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/deprecated_levels/levels.go @@ -0,0 +1,127 @@ +package levels + +import "github.com/go-kit/kit/log" + +// Levels provides a leveled logging wrapper around a logger. It has five +// levels: debug, info, warning (warn), error, and critical (crit). If you +// want a different set of levels, you can create your own levels type very +// easily, and you can elide the configuration. +type Levels struct { + logger log.Logger + levelKey string + + // We have a choice between storing level values in string fields or + // making a separate context for each level. When using string fields the + // Log method must combine the base context, the level data, and the + // logged keyvals; but the With method only requires updating one context. + // If we instead keep a separate context for each level the Log method + // must only append the new keyvals; but the With method would have to + // update all five contexts. + + // Roughly speaking, storing multiple contexts breaks even if the ratio of + // Log/With calls is more than the number of levels. We have chosen to + // make the With method cheap and the Log method a bit more costly because + // we do not expect most applications to Log more than five times for each + // call to With. + + debugValue string + infoValue string + warnValue string + errorValue string + critValue string +} + +// New creates a new leveled logger, wrapping the passed logger. +func New(logger log.Logger, options ...Option) Levels { + l := Levels{ + logger: logger, + levelKey: "level", + + debugValue: "debug", + infoValue: "info", + warnValue: "warn", + errorValue: "error", + critValue: "crit", + } + for _, option := range options { + option(&l) + } + return l +} + +// With returns a new leveled logger that includes keyvals in all log events. +func (l Levels) With(keyvals ...interface{}) Levels { + return Levels{ + logger: log.With(l.logger, keyvals...), + levelKey: l.levelKey, + debugValue: l.debugValue, + infoValue: l.infoValue, + warnValue: l.warnValue, + errorValue: l.errorValue, + critValue: l.critValue, + } +} + +// Debug returns a debug level logger. +func (l Levels) Debug() log.Logger { + return log.WithPrefix(l.logger, l.levelKey, l.debugValue) +} + +// Info returns an info level logger. +func (l Levels) Info() log.Logger { + return log.WithPrefix(l.logger, l.levelKey, l.infoValue) +} + +// Warn returns a warning level logger. +func (l Levels) Warn() log.Logger { + return log.WithPrefix(l.logger, l.levelKey, l.warnValue) +} + +// Error returns an error level logger. +func (l Levels) Error() log.Logger { + return log.WithPrefix(l.logger, l.levelKey, l.errorValue) +} + +// Crit returns a critical level logger. +func (l Levels) Crit() log.Logger { + return log.WithPrefix(l.logger, l.levelKey, l.critValue) +} + +// Option sets a parameter for leveled loggers. +type Option func(*Levels) + +// Key sets the key for the field used to indicate log level. By default, +// the key is "level". +func Key(key string) Option { + return func(l *Levels) { l.levelKey = key } +} + +// DebugValue sets the value for the field used to indicate the debug log +// level. By default, the value is "debug". +func DebugValue(value string) Option { + return func(l *Levels) { l.debugValue = value } +} + +// InfoValue sets the value for the field used to indicate the info log level. +// By default, the value is "info". +func InfoValue(value string) Option { + return func(l *Levels) { l.infoValue = value } +} + +// WarnValue sets the value for the field used to indicate the warning log +// level. By default, the value is "warn". +func WarnValue(value string) Option { + return func(l *Levels) { l.warnValue = value } +} + +// ErrorValue sets the value for the field used to indicate the error log +// level. By default, the value is "error". +func ErrorValue(value string) Option { + return func(l *Levels) { l.errorValue = value } +} + +// CritValue sets the value for the field used to indicate the critical log +// level. By default, the value is "crit". +func CritValue(value string) Option { + return func(l *Levels) { l.critValue = value } +} diff --git a/vendor/github.com/go-kit/kit/log/doc.go b/vendor/github.com/go-kit/kit/log/doc.go new file mode 100644 index 000000000..918c0af46 --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/doc.go @@ -0,0 +1,116 @@ +// Package log provides a structured logger. +// +// Structured logging produces logs easily consumed later by humans or +// machines. Humans might be interested in debugging errors, or tracing +// specific requests. Machines might be interested in counting interesting +// events, or aggregating information for off-line processing. In both cases, +// it is important that the log messages are structured and actionable. +// Package log is designed to encourage both of these best practices. +// +// Basic Usage +// +// The fundamental interface is Logger. Loggers create log events from +// key/value data. The Logger interface has a single method, Log, which +// accepts a sequence of alternating key/value pairs, which this package names +// keyvals. +// +// type Logger interface { +// Log(keyvals ...interface{}) error +// } +// +// Here is an example of a function using a Logger to create log events. +// +// func RunTask(task Task, logger log.Logger) string { +// logger.Log("taskID", task.ID, "event", "starting task") +// ... +// logger.Log("taskID", task.ID, "event", "task complete") +// } +// +// The keys in the above example are "taskID" and "event". The values are +// task.ID, "starting task", and "task complete". Every key is followed +// immediately by its value. +// +// Keys are usually plain strings. Values may be any type that has a sensible +// encoding in the chosen log format. With structured logging it is a good +// idea to log simple values without formatting them. This practice allows +// the chosen logger to encode values in the most appropriate way. +// +// Contextual Loggers +// +// A contextual logger stores keyvals that it includes in all log events. +// Building appropriate contextual loggers reduces repetition and aids +// consistency in the resulting log output. With and WithPrefix add context to +// a logger. We can use With to improve the RunTask example. +// +// func RunTask(task Task, logger log.Logger) string { +// logger = log.With(logger, "taskID", task.ID) +// logger.Log("event", "starting task") +// ... +// taskHelper(task.Cmd, logger) +// ... +// logger.Log("event", "task complete") +// } +// +// The improved version emits the same log events as the original for the +// first and last calls to Log. Passing the contextual logger to taskHelper +// enables each log event created by taskHelper to include the task.ID even +// though taskHelper does not have access to that value. Using contextual +// loggers this way simplifies producing log output that enables tracing the +// life cycle of individual tasks. (See the Contextual example for the full +// code of the above snippet.) +// +// Dynamic Contextual Values +// +// A Valuer function stored in a contextual logger generates a new value each +// time an event is logged. The Valuer example demonstrates how this feature +// works. +// +// Valuers provide the basis for consistently logging timestamps and source +// code location. The log package defines several valuers for that purpose. +// See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and +// DefaultCaller. A common logger initialization sequence that ensures all log +// entries contain a timestamp and source location looks like this: +// +// logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) +// logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) +// +// Concurrent Safety +// +// Applications with multiple goroutines want each log event written to the +// same logger to remain separate from other log events. Package log provides +// two simple solutions for concurrent safe logging. +// +// NewSyncWriter wraps an io.Writer and serializes each call to its Write +// method. Using a SyncWriter has the benefit that the smallest practical +// portion of the logging logic is performed within a mutex, but it requires +// the formatting Logger to make only one call to Write per log event. +// +// NewSyncLogger wraps any Logger and serializes each call to its Log method. +// Using a SyncLogger has the benefit that it guarantees each log event is +// handled atomically within the wrapped logger, but it typically serializes +// both the formatting and output logic. Use a SyncLogger if the formatting +// logger may perform multiple writes per log event. +// +// Error Handling +// +// This package relies on the practice of wrapping or decorating loggers with +// other loggers to provide composable pieces of functionality. It also means +// that Logger.Log must return an error because some +// implementations—especially those that output log data to an io.Writer—may +// encounter errors that cannot be handled locally. This in turn means that +// Loggers that wrap other loggers should return errors from the wrapped +// logger up the stack. +// +// Fortunately, the decorator pattern also provides a way to avoid the +// necessity to check for errors every time an application calls Logger.Log. +// An application required to panic whenever its Logger encounters +// an error could initialize its logger as follows. +// +// fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) +// logger := log.LoggerFunc(func(keyvals ...interface{}) error { +// if err := fmtlogger.Log(keyvals...); err != nil { +// panic(err) +// } +// return nil +// }) +package log diff --git a/vendor/github.com/go-kit/kit/log/json_logger.go b/vendor/github.com/go-kit/kit/log/json_logger.go new file mode 100644 index 000000000..66094b4dd --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/json_logger.go @@ -0,0 +1,89 @@ +package log + +import ( + "encoding" + "encoding/json" + "fmt" + "io" + "reflect" +) + +type jsonLogger struct { + io.Writer +} + +// NewJSONLogger returns a Logger that encodes keyvals to the Writer as a +// single JSON object. Each log event produces no more than one call to +// w.Write. The passed Writer must be safe for concurrent use by multiple +// goroutines if the returned Logger will be used concurrently. +func NewJSONLogger(w io.Writer) Logger { + return &jsonLogger{w} +} + +func (l *jsonLogger) Log(keyvals ...interface{}) error { + n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd + m := make(map[string]interface{}, n) + for i := 0; i < len(keyvals); i += 2 { + k := keyvals[i] + var v interface{} = ErrMissingValue + if i+1 < len(keyvals) { + v = keyvals[i+1] + } + merge(m, k, v) + } + return json.NewEncoder(l.Writer).Encode(m) +} + +func merge(dst map[string]interface{}, k, v interface{}) { + var key string + switch x := k.(type) { + case string: + key = x + case fmt.Stringer: + key = safeString(x) + default: + key = fmt.Sprint(x) + } + + // We want json.Marshaler and encoding.TextMarshaller to take priority over + // err.Error() and v.String(). But json.Marshall (called later) does that by + // default so we force a no-op if it's one of those 2 case. + switch x := v.(type) { + case json.Marshaler: + case encoding.TextMarshaler: + case error: + v = safeError(x) + case fmt.Stringer: + v = safeString(x) + } + + dst[key] = v +} + +func safeString(str fmt.Stringer) (s string) { + defer func() { + if panicVal := recover(); panicVal != nil { + if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() { + s = "NULL" + } else { + panic(panicVal) + } + } + }() + s = str.String() + return +} + +func safeError(err error) (s interface{}) { + defer func() { + if panicVal := recover(); panicVal != nil { + if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() { + s = nil + } else { + panic(panicVal) + } + } + }() + s = err.Error() + return +} diff --git a/vendor/github.com/go-kit/kit/log/level/doc.go b/vendor/github.com/go-kit/kit/log/level/doc.go new file mode 100644 index 000000000..feadc4cdc --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/level/doc.go @@ -0,0 +1,22 @@ +// Package level implements leveled logging on top of package log. To use the +// level package, create a logger as per normal in your func main, and wrap it +// with level.NewFilter. +// +// var logger log.Logger +// logger = log.NewLogfmtLogger(os.Stderr) +// logger = level.NewFilter(logger, level.AllowInfo()) // <-- +// logger = log.With(logger, "ts", log.DefaultTimestampUTC) +// +// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error +// helper methods to emit leveled log events. +// +// logger.Log("foo", "bar") // as normal, no level +// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get()) +// if value > 100 { +// level.Error(logger).Log("value", value) +// } +// +// NewFilter allows precise control over what happens when a log event is +// emitted without a level key, or if a squelched level is used. Check the +// Option functions for details. +package level diff --git a/vendor/github.com/go-kit/kit/log/level/level.go b/vendor/github.com/go-kit/kit/log/level/level.go new file mode 100644 index 000000000..fceafc454 --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/level/level.go @@ -0,0 +1,205 @@ +package level + +import "github.com/go-kit/kit/log" + +// Error returns a logger that includes a Key/ErrorValue pair. +func Error(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), ErrorValue()) +} + +// Warn returns a logger that includes a Key/WarnValue pair. +func Warn(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), WarnValue()) +} + +// Info returns a logger that includes a Key/InfoValue pair. +func Info(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), InfoValue()) +} + +// Debug returns a logger that includes a Key/DebugValue pair. +func Debug(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), DebugValue()) +} + +// NewFilter wraps next and implements level filtering. See the commentary on +// the Option functions for a detailed description of how to configure levels. +// If no options are provided, all leveled log events created with Debug, +// Info, Warn or Error helper methods are squelched and non-leveled log +// events are passed to next unmodified. +func NewFilter(next log.Logger, options ...Option) log.Logger { + l := &logger{ + next: next, + } + for _, option := range options { + option(l) + } + return l +} + +type logger struct { + next log.Logger + allowed level + squelchNoLevel bool + errNotAllowed error + errNoLevel error +} + +func (l *logger) Log(keyvals ...interface{}) error { + var hasLevel, levelAllowed bool + for i := 1; i < len(keyvals); i += 2 { + if v, ok := keyvals[i].(*levelValue); ok { + hasLevel = true + levelAllowed = l.allowed&v.level != 0 + break + } + } + if !hasLevel && l.squelchNoLevel { + return l.errNoLevel + } + if hasLevel && !levelAllowed { + return l.errNotAllowed + } + return l.next.Log(keyvals...) +} + +// Option sets a parameter for the leveled logger. +type Option func(*logger) + +// AllowAll is an alias for AllowDebug. +func AllowAll() Option { + return AllowDebug() +} + +// AllowDebug allows error, warn, info and debug level log events to pass. +func AllowDebug() Option { + return allowed(levelError | levelWarn | levelInfo | levelDebug) +} + +// AllowInfo allows error, warn and info level log events to pass. +func AllowInfo() Option { + return allowed(levelError | levelWarn | levelInfo) +} + +// AllowWarn allows error and warn level log events to pass. +func AllowWarn() Option { + return allowed(levelError | levelWarn) +} + +// AllowError allows only error level log events to pass. +func AllowError() Option { + return allowed(levelError) +} + +// AllowNone allows no leveled log events to pass. +func AllowNone() Option { + return allowed(0) +} + +func allowed(allowed level) Option { + return func(l *logger) { l.allowed = allowed } +} + +// ErrNotAllowed sets the error to return from Log when it squelches a log +// event disallowed by the configured Allow[Level] option. By default, +// ErrNotAllowed is nil; in this case the log event is squelched with no +// error. +func ErrNotAllowed(err error) Option { + return func(l *logger) { l.errNotAllowed = err } +} + +// SquelchNoLevel instructs Log to squelch log events with no level, so that +// they don't proceed through to the wrapped logger. If SquelchNoLevel is set +// to true and a log event is squelched in this way, the error value +// configured with ErrNoLevel is returned to the caller. +func SquelchNoLevel(squelch bool) Option { + return func(l *logger) { l.squelchNoLevel = squelch } +} + +// ErrNoLevel sets the error to return from Log when it squelches a log event +// with no level. By default, ErrNoLevel is nil; in this case the log event is +// squelched with no error. +func ErrNoLevel(err error) Option { + return func(l *logger) { l.errNoLevel = err } +} + +// NewInjector wraps next and returns a logger that adds a Key/level pair to +// the beginning of log events that don't already contain a level. In effect, +// this gives a default level to logs without a level. +func NewInjector(next log.Logger, level Value) log.Logger { + return &injector{ + next: next, + level: level, + } +} + +type injector struct { + next log.Logger + level interface{} +} + +func (l *injector) Log(keyvals ...interface{}) error { + for i := 1; i < len(keyvals); i += 2 { + if _, ok := keyvals[i].(*levelValue); ok { + return l.next.Log(keyvals...) + } + } + kvs := make([]interface{}, len(keyvals)+2) + kvs[0], kvs[1] = key, l.level + copy(kvs[2:], keyvals) + return l.next.Log(kvs...) +} + +// Value is the interface that each of the canonical level values implement. +// It contains unexported methods that prevent types from other packages from +// implementing it and guaranteeing that NewFilter can distinguish the levels +// defined in this package from all other values. +type Value interface { + String() string + levelVal() +} + +// Key returns the unique key added to log events by the loggers in this +// package. +func Key() interface{} { return key } + +// ErrorValue returns the unique value added to log events by Error. +func ErrorValue() Value { return errorValue } + +// WarnValue returns the unique value added to log events by Warn. +func WarnValue() Value { return warnValue } + +// InfoValue returns the unique value added to log events by Info. +func InfoValue() Value { return infoValue } + +// DebugValue returns the unique value added to log events by Warn. +func DebugValue() Value { return debugValue } + +var ( + // key is of type interface{} so that it allocates once during package + // initialization and avoids allocating every time the value is added to a + // []interface{} later. + key interface{} = "level" + + errorValue = &levelValue{level: levelError, name: "error"} + warnValue = &levelValue{level: levelWarn, name: "warn"} + infoValue = &levelValue{level: levelInfo, name: "info"} + debugValue = &levelValue{level: levelDebug, name: "debug"} +) + +type level byte + +const ( + levelDebug level = 1 << iota + levelInfo + levelWarn + levelError +) + +type levelValue struct { + name string + level +} + +func (v *levelValue) String() string { return v.name } +func (v *levelValue) levelVal() {} diff --git a/vendor/github.com/go-kit/kit/log/log.go b/vendor/github.com/go-kit/kit/log/log.go new file mode 100644 index 000000000..66a9e2fde --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/log.go @@ -0,0 +1,135 @@ +package log + +import "errors" + +// Logger is the fundamental interface for all log operations. Log creates a +// log event from keyvals, a variadic sequence of alternating keys and values. +// Implementations must be safe for concurrent use by multiple goroutines. In +// particular, any implementation of Logger that appends to keyvals or +// modifies or retains any of its elements must make a copy first. +type Logger interface { + Log(keyvals ...interface{}) error +} + +// ErrMissingValue is appended to keyvals slices with odd length to substitute +// the missing value. +var ErrMissingValue = errors.New("(MISSING)") + +// With returns a new contextual logger with keyvals prepended to those passed +// to calls to Log. If logger is also a contextual logger created by With or +// WithPrefix, keyvals is appended to the existing context. +// +// The returned Logger replaces all value elements (odd indexes) containing a +// Valuer with their generated value for each call to its Log method. +func With(logger Logger, keyvals ...interface{}) Logger { + if len(keyvals) == 0 { + return logger + } + l := newContext(logger) + kvs := append(l.keyvals, keyvals...) + if len(kvs)%2 != 0 { + kvs = append(kvs, ErrMissingValue) + } + return &context{ + logger: l.logger, + // Limiting the capacity of the stored keyvals ensures that a new + // backing array is created if the slice must grow in Log or With. + // Using the extra capacity without copying risks a data race that + // would violate the Logger interface contract. + keyvals: kvs[:len(kvs):len(kvs)], + hasValuer: l.hasValuer || containsValuer(keyvals), + } +} + +// WithPrefix returns a new contextual logger with keyvals prepended to those +// passed to calls to Log. If logger is also a contextual logger created by +// With or WithPrefix, keyvals is prepended to the existing context. +// +// The returned Logger replaces all value elements (odd indexes) containing a +// Valuer with their generated value for each call to its Log method. +func WithPrefix(logger Logger, keyvals ...interface{}) Logger { + if len(keyvals) == 0 { + return logger + } + l := newContext(logger) + // Limiting the capacity of the stored keyvals ensures that a new + // backing array is created if the slice must grow in Log or With. + // Using the extra capacity without copying risks a data race that + // would violate the Logger interface contract. + n := len(l.keyvals) + len(keyvals) + if len(keyvals)%2 != 0 { + n++ + } + kvs := make([]interface{}, 0, n) + kvs = append(kvs, keyvals...) + if len(kvs)%2 != 0 { + kvs = append(kvs, ErrMissingValue) + } + kvs = append(kvs, l.keyvals...) + return &context{ + logger: l.logger, + keyvals: kvs, + hasValuer: l.hasValuer || containsValuer(keyvals), + } +} + +// context is the Logger implementation returned by With and WithPrefix. It +// wraps a Logger and holds keyvals that it includes in all log events. Its +// Log method calls bindValues to generate values for each Valuer in the +// context keyvals. +// +// A context must always have the same number of stack frames between calls to +// its Log method and the eventual binding of Valuers to their value. This +// requirement comes from the functional requirement to allow a context to +// resolve application call site information for a Caller stored in the +// context. To do this we must be able to predict the number of logging +// functions on the stack when bindValues is called. +// +// Two implementation details provide the needed stack depth consistency. +// +// 1. newContext avoids introducing an additional layer when asked to +// wrap another context. +// 2. With and WithPrefix avoid introducing an additional layer by +// returning a newly constructed context with a merged keyvals rather +// than simply wrapping the existing context. +type context struct { + logger Logger + keyvals []interface{} + hasValuer bool +} + +func newContext(logger Logger) *context { + if c, ok := logger.(*context); ok { + return c + } + return &context{logger: logger} +} + +// Log replaces all value elements (odd indexes) containing a Valuer in the +// stored context with their generated value, appends keyvals, and passes the +// result to the wrapped Logger. +func (l *context) Log(keyvals ...interface{}) error { + kvs := append(l.keyvals, keyvals...) + if len(kvs)%2 != 0 { + kvs = append(kvs, ErrMissingValue) + } + if l.hasValuer { + // If no keyvals were appended above then we must copy l.keyvals so + // that future log events will reevaluate the stored Valuers. + if len(keyvals) == 0 { + kvs = append([]interface{}{}, l.keyvals...) + } + bindValues(kvs[:len(l.keyvals)]) + } + return l.logger.Log(kvs...) +} + +// LoggerFunc is an adapter to allow use of ordinary functions as Loggers. If +// f is a function with the appropriate signature, LoggerFunc(f) is a Logger +// object that calls f. +type LoggerFunc func(...interface{}) error + +// Log implements Logger by calling f(keyvals...). +func (f LoggerFunc) Log(keyvals ...interface{}) error { + return f(keyvals...) +} diff --git a/vendor/github.com/go-kit/kit/log/logfmt_logger.go b/vendor/github.com/go-kit/kit/log/logfmt_logger.go new file mode 100644 index 000000000..a00305298 --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/logfmt_logger.go @@ -0,0 +1,62 @@ +package log + +import ( + "bytes" + "io" + "sync" + + "github.com/go-logfmt/logfmt" +) + +type logfmtEncoder struct { + *logfmt.Encoder + buf bytes.Buffer +} + +func (l *logfmtEncoder) Reset() { + l.Encoder.Reset() + l.buf.Reset() +} + +var logfmtEncoderPool = sync.Pool{ + New: func() interface{} { + var enc logfmtEncoder + enc.Encoder = logfmt.NewEncoder(&enc.buf) + return &enc + }, +} + +type logfmtLogger struct { + w io.Writer +} + +// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in +// logfmt format. Each log event produces no more than one call to w.Write. +// The passed Writer must be safe for concurrent use by multiple goroutines if +// the returned Logger will be used concurrently. +func NewLogfmtLogger(w io.Writer) Logger { + return &logfmtLogger{w} +} + +func (l logfmtLogger) Log(keyvals ...interface{}) error { + enc := logfmtEncoderPool.Get().(*logfmtEncoder) + enc.Reset() + defer logfmtEncoderPool.Put(enc) + + if err := enc.EncodeKeyvals(keyvals...); err != nil { + return err + } + + // Add newline to the end of the buffer + if err := enc.EndRecord(); err != nil { + return err + } + + // The Logger interface requires implementations to be safe for concurrent + // use by multiple goroutines. For this implementation that means making + // only one call to l.w.Write() for each call to Log. + if _, err := l.w.Write(enc.buf.Bytes()); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/go-kit/kit/log/nop_logger.go b/vendor/github.com/go-kit/kit/log/nop_logger.go new file mode 100644 index 000000000..1047d626c --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/nop_logger.go @@ -0,0 +1,8 @@ +package log + +type nopLogger struct{} + +// NewNopLogger returns a logger that doesn't do anything. +func NewNopLogger() Logger { return nopLogger{} } + +func (nopLogger) Log(...interface{}) error { return nil } diff --git a/vendor/github.com/go-kit/kit/log/stdlib.go b/vendor/github.com/go-kit/kit/log/stdlib.go new file mode 100644 index 000000000..ff96b5dee --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/stdlib.go @@ -0,0 +1,116 @@ +package log + +import ( + "io" + "log" + "regexp" + "strings" +) + +// StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's +// designed to be passed to a Go kit logger as the writer, for cases where +// it's necessary to redirect all Go kit log output to the stdlib logger. +// +// If you have any choice in the matter, you shouldn't use this. Prefer to +// redirect the stdlib log to the Go kit logger via NewStdlibAdapter. +type StdlibWriter struct{} + +// Write implements io.Writer. +func (w StdlibWriter) Write(p []byte) (int, error) { + log.Print(strings.TrimSpace(string(p))) + return len(p), nil +} + +// StdlibAdapter wraps a Logger and allows it to be passed to the stdlib +// logger's SetOutput. It will extract date/timestamps, filenames, and +// messages, and place them under relevant keys. +type StdlibAdapter struct { + Logger + timestampKey string + fileKey string + messageKey string +} + +// StdlibAdapterOption sets a parameter for the StdlibAdapter. +type StdlibAdapterOption func(*StdlibAdapter) + +// TimestampKey sets the key for the timestamp field. By default, it's "ts". +func TimestampKey(key string) StdlibAdapterOption { + return func(a *StdlibAdapter) { a.timestampKey = key } +} + +// FileKey sets the key for the file and line field. By default, it's "caller". +func FileKey(key string) StdlibAdapterOption { + return func(a *StdlibAdapter) { a.fileKey = key } +} + +// MessageKey sets the key for the actual log message. By default, it's "msg". +func MessageKey(key string) StdlibAdapterOption { + return func(a *StdlibAdapter) { a.messageKey = key } +} + +// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed +// logger. It's designed to be passed to log.SetOutput. +func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer { + a := StdlibAdapter{ + Logger: logger, + timestampKey: "ts", + fileKey: "caller", + messageKey: "msg", + } + for _, option := range options { + option(&a) + } + return a +} + +func (a StdlibAdapter) Write(p []byte) (int, error) { + result := subexps(p) + keyvals := []interface{}{} + var timestamp string + if date, ok := result["date"]; ok && date != "" { + timestamp = date + } + if time, ok := result["time"]; ok && time != "" { + if timestamp != "" { + timestamp += " " + } + timestamp += time + } + if timestamp != "" { + keyvals = append(keyvals, a.timestampKey, timestamp) + } + if file, ok := result["file"]; ok && file != "" { + keyvals = append(keyvals, a.fileKey, file) + } + if msg, ok := result["msg"]; ok { + keyvals = append(keyvals, a.messageKey, msg) + } + if err := a.Logger.Log(keyvals...); err != nil { + return 0, err + } + return len(p), nil +} + +const ( + logRegexpDate = `(?P[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?` + logRegexpTime = `(?P