From c238e28d978c188d30732bed121d9f281f1bec25 Mon Sep 17 00:00:00 2001 From: Carson Anderson Date: Thu, 27 Dec 2018 21:24:53 -0700 Subject: [PATCH] Add Kubernetes topo implementation Signed-off-by: Carson Anderson --- bootstrap.sh | 27 + examples/local/101_initial_cluster.sh | 2 + examples/local/401_teardown.sh | 2 + examples/local/env.sh | 15 +- examples/local/k3s-down.sh | 29 + examples/local/k3s-up.sh | 46 + examples/local/k8s-down.sh | 31 + examples/local/topo-k8s.sh | 21 + examples/local/vttablet-up.sh | 2 +- go.mod | 3 + go.sum | 48 + go/cmd/topo2topo/plugin_kubernetestopo.go | 23 + go/cmd/vtctld/plugin_kubernetestopo.go | 23 + go/cmd/vtgate/plugin_kubernetestopo.go | 23 + go/cmd/vttablet/plugin_kubernetestopo.go | 23 + go/cmd/vtworker/plugin_kubernetestopo.go | 23 + go/vt/topo/kubernetestopo/config.go | 17 + go/vt/topo/kubernetestopo/directory.go | 103 + go/vt/topo/kubernetestopo/election.go | 123 ++ go/vt/topo/kubernetestopo/error.go | 54 + go/vt/topo/kubernetestopo/file.go | 215 ++ go/vt/topo/kubernetestopo/lock.go | 99 + go/vt/topo/kubernetestopo/server.go | 187 ++ go/vt/topo/kubernetestopo/server_test.go | 132 ++ go/vt/topo/kubernetestopo/version.go | 40 + go/vt/topo/kubernetestopo/watch.go | 117 ++ go/vt/vtctl/plugin_kubernetestopo.go | 23 + vendor/vendor.json | 2213 +++++++++++++++++++++ 28 files changed, 3659 insertions(+), 5 deletions(-) create mode 100755 examples/local/k3s-down.sh create mode 100755 examples/local/k3s-up.sh create mode 100644 examples/local/k8s-down.sh create mode 100644 examples/local/topo-k8s.sh create mode 100644 go/cmd/topo2topo/plugin_kubernetestopo.go create mode 100644 go/cmd/vtctld/plugin_kubernetestopo.go create mode 100644 go/cmd/vtgate/plugin_kubernetestopo.go create mode 100644 go/cmd/vttablet/plugin_kubernetestopo.go create mode 100644 go/cmd/vtworker/plugin_kubernetestopo.go create mode 100644 go/vt/topo/kubernetestopo/config.go create mode 100644 go/vt/topo/kubernetestopo/directory.go create mode 100644 go/vt/topo/kubernetestopo/election.go create mode 100644 go/vt/topo/kubernetestopo/error.go create mode 100644 go/vt/topo/kubernetestopo/file.go create mode 100644 go/vt/topo/kubernetestopo/lock.go create mode 100644 go/vt/topo/kubernetestopo/server.go create mode 100644 go/vt/topo/kubernetestopo/server_test.go create mode 100644 go/vt/topo/kubernetestopo/version.go create mode 100644 go/vt/topo/kubernetestopo/watch.go create mode 100644 go/vt/vtctl/plugin_kubernetestopo.go create mode 100644 vendor/vendor.json diff --git a/bootstrap.sh b/bootstrap.sh index 1252e3717b0..025a8afd605 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -194,6 +194,33 @@ function install_etcd() { command -v etcd && echo "etcd already installed" || install_dep "etcd" "v3.3.10" "$VTROOT/dist/etcd" install_etcd +# Download and install k3s, link k3s binary into our root. +function install_k3s() { + local version="$1" + local dist="$2" + + case $(uname) in + Linux) local platform=linux;; + *) echo "ERROR: unsupported platform. K3s only supports running on Linux"; exit 1;; + esac + + case $(get_arch) in + aarch64) local target="-arm64";; + x86_64) local target="";; + *) echo "ERROR: unsupported architecture"; exit 1;; + esac + + download_url=https://github.com/rancher/k3s/releases/download + file="k3s${target}" + + local dest="$dist/k3s${target}-${version}-${platform}" + wget -O $dest "$download_url/$version/$file" + chmod +x $dest + ln -snf $dest "$VTROOT/bin/k3s" +} +command -v k3s || install_dep "k3s" "v1.0.0" "$VTROOT/dist/k3s" install_k3s + + # Download and install consul, link consul binary into our root. function install_consul() { local version="$1" diff --git a/examples/local/101_initial_cluster.sh b/examples/local/101_initial_cluster.sh index 1a484d98d5d..7cfdd500246 100755 --- a/examples/local/101_initial_cluster.sh +++ b/examples/local/101_initial_cluster.sh @@ -26,6 +26,8 @@ source "${script_root}/env.sh" # start topo server if [ "${TOPO}" = "zk2" ]; then CELL=zone1 "$script_root/zk-up.sh" +elif [ "${TOPO}" = "k8s" ]; then + CELL=zone1 "$script_root/k3s-up.sh" else CELL=zone1 "$script_root/etcd-up.sh" fi diff --git a/examples/local/401_teardown.sh b/examples/local/401_teardown.sh index b0168ae133d..1da37893eea 100755 --- a/examples/local/401_teardown.sh +++ b/examples/local/401_teardown.sh @@ -32,6 +32,8 @@ done; if [ "${TOPO}" = "zk2" ]; then CELL=zone1 "$script_root/zk-down.sh" +elif [ "${TOPO}" = "k8s" ]; then + CELL=zone1 "$script_root/k3s-down.sh" else CELL=zone1 "$script_root/etcd-down.sh" fi diff --git a/examples/local/env.sh b/examples/local/env.sh index 0211bcbbc71..f8ce76e7b17 100644 --- a/examples/local/env.sh +++ b/examples/local/env.sh @@ -29,7 +29,7 @@ fi # mysqld might be in /usr/sbin which will not be in the default PATH PATH="/usr/sbin:$PATH" -for binary in mysqld etcd etcdctl curl vtctlclient vttablet vtgate vtctld mysqlctl; do +for binary in mysqld etcd etcdctl curl vtctlclient vttablet vtgate vtctld vtctl mysqlctl; do command -v "$binary" > /dev/null || fail "${binary} is not installed in PATH. See https://vitess.io/docs/get-started/local/ for install instructions." done; @@ -52,12 +52,19 @@ if [ "${TOPO}" = "zk2" ]; then ZK_SERVER="localhost:21811,localhost:21812,localhost:21813" # shellcheck disable=SC2034 TOPOLOGY_FLAGS="-topo_implementation zk2 -topo_global_server_address ${ZK_SERVER} -topo_global_root /vitess/global" - - mkdir -p $VTDATAROOT/tmp +elif [ "${TOPO}" = "k8s" ]; then + # Set topology environment parameters. + K8S_ADDR="localhost" + K8S_PORT="8443" + K8S_KUBECONFIG=$VTDATAROOT/tmp/k8s.kubeconfig + # shellcheck disable=SC2034 + TOPOLOGY_FLAGS="-topo_implementation k8s -topo_k8s_kubeconfig ${K8S_KUBECONFIG} -topo_global_server_address ${K8S_ADDR}:${K8S_PORT} -topo_global_root /vitess/global" else ETCD_SERVER="localhost:2379" TOPOLOGY_FLAGS="-topo_implementation etcd2 -topo_global_server_address $ETCD_SERVER -topo_global_root /vitess/global" - mkdir -p "${VTDATAROOT}/tmp" mkdir -p "${VTDATAROOT}/etcd" fi + +# Create a tmp dir +mkdir -p "${VTDATAROOT}/tmp" diff --git a/examples/local/k3s-down.sh b/examples/local/k3s-down.sh new file mode 100755 index 00000000000..3f3fbbbd178 --- /dev/null +++ b/examples/local/k3s-down.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the k3s server started by k3s-up.sh. + +set -e + +script_root=`dirname "${BASH_SOURCE}"` +source $script_root/env.sh + +# Stop K3s server. +echo "Stopping k3s server..." + +pid=`cat $VTDATAROOT/tmp/k3s.pid` +echo "Stopping k3s..." +kill -9 $pid diff --git a/examples/local/k3s-up.sh b/examples/local/k3s-up.sh new file mode 100755 index 00000000000..fb4c78d80d9 --- /dev/null +++ b/examples/local/k3s-up.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that creates a Kubernetes api for topo use by running k3s + +set -e +cell=${CELL:-'test'} + +script_root=$(dirname "${BASH_SOURCE[0]}") + +# shellcheck source=./env.sh +# shellcheck disable=SC1091 +source "${script_root}/env.sh" + +k3s server --disable-agent --data-dir "${VTDATAROOT}/k3s/" --https-listen-port "${K8S_PORT}" --write-kubeconfig "${K8S_KUBECONFIG}" > "${VTDATAROOT}"/tmp/k3s.out 2>&1 & +PID=$! +echo $PID > "${VTDATAROOT}/tmp/k3s.pid" +disown -a +echo "Waiting for k3s server to start" +sleep 15 + +# Use k3s built-in kubectl with custom config +KUBECTL="k3s kubectl --kubeconfig=${K8S_KUBECONFIG}" + +# Add the CellInfo description for the cell +set +e +echo "add $cell CellInfo" +vtctl $TOPOLOGY_FLAGS AddCellInfo \ + -root /vitess/$cell \ + $cell +set -e + +echo "k3s start done..." diff --git a/examples/local/k8s-down.sh b/examples/local/k8s-down.sh new file mode 100644 index 00000000000..4575cf5b579 --- /dev/null +++ b/examples/local/k8s-down.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the k3s server started by k3s-up.sh. + +set -e + +script_root=`dirname "${BASH_SOURCE}"` +source $script_root/env.sh + +# Stop K3s server. +echo "Stopping k3s server..." + +pid=`cat $VTDATAROOT/tmp/k3s.pid` +echo "Stopping k3s..." +set +e +kill -9 $pid +rm ${K8S_KUBECONFIG} diff --git a/examples/local/topo-k8s.sh b/examples/local/topo-k8s.sh new file mode 100644 index 00000000000..92e14ba4d69 --- /dev/null +++ b/examples/local/topo-k8s.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that creates a single shard vttablet deployment. + +export TOPO='k8s' + + diff --git a/examples/local/vttablet-up.sh b/examples/local/vttablet-up.sh index 4914a65493b..590e709e785 100755 --- a/examples/local/vttablet-up.sh +++ b/examples/local/vttablet-up.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash # Copyright 2019 The Vitess Authors. # diff --git a/go.mod b/go.mod index 5310d66e0b1..1228bf986d2 100644 --- a/go.mod +++ b/go.mod @@ -94,6 +94,9 @@ require ( gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect gopkg.in/ldap.v2 v2.5.0 honnef.co/go/tools v0.0.1-2019.2.3 + k8s.io/api v0.0.0-20190819141258-3544db3b9e44 + k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d + k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77 mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2 // indirect sourcegraph.com/sqs/pbtypes v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 12ffff34b90..e4cbd999e53 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,7 @@ cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5 h1:7tNlRGC3pUEPKS3DwgX5L0s+cBloaq/JBoi9ceN1MCM= github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= @@ -93,6 +94,13 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= @@ -142,6 +150,7 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw= github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -150,6 +159,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -197,12 +207,15 @@ github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039 h1:XQKc8IYQOeRwVs github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -216,6 +229,9 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -227,6 +243,7 @@ github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:J github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3 h1:iwp+5/UAyzQSFgQ4uR2sni99sJ8Eo9DEacKWM5pekIg= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= @@ -269,6 +286,8 @@ github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZa github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= @@ -283,7 +302,9 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= @@ -352,11 +373,14 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= @@ -368,6 +392,7 @@ github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984/go.mod h1:v github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= @@ -387,6 +412,7 @@ github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzI github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pires/go-proxyproto v0.0.0-20191211124218-517ecdf5bb2b h1:JPLdtNmpXbWytipbGwYz7zXZzlQNASEiFw5aGAM75us= github.com/pires/go-proxyproto v0.0.0-20191211124218-517ecdf5bb2b/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -467,6 +493,7 @@ github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -535,6 +562,7 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -580,11 +608,13 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 h1:qPnAdmjNA41t3QBTx2mFGf/SD1IoslhYu7AmdsVzCcs= golang.org/x/net v0.0.0-20190926025831-c00fd9afed17/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -619,8 +649,10 @@ golang.org/x/sys v0.0.0-20191218084908-4a24b4065292 h1:Y8q0zsdcgAd+JU8VUA8p8Qv2Y golang.org/x/sys v0.0.0-20191218084908-4a24b4065292/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -702,6 +734,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= +gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.41.0 h1:Ka3ViY6gNYSKiVy71zXBEqKplnV35ImDLVG+8uoIklE= gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= @@ -726,6 +760,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069z honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.0.0-20190819141258-3544db3b9e44 h1:7Gz7/nQ7X2qmPXMyN0bNq7Zm9Uip+UnFuMZTd2l3vms= +k8s.io/api v0.0.0-20190819141258-3544db3b9e44/go.mod h1:AOxZTnaXR/xiarlQL0JUfwQPxjmKDvVYoRp58cA7lUo= +k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d h1:7Kns6qqhMAQWvGkxYOLSLRZ5hJO0/5pcE5lPGP2fxUw= +k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d/go.mod h1:3jediapYqJ2w1BFw7lAZPCx7scubsTfosqHkhXCWJKw= +k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77 h1:w1BoabVnPpPqQCY3sHK4qVwa12Lk8ip1pKMR1C+qbdo= +k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77/go.mod h1:DmkJD5UDP87MVqUQ5VJ6Tj9Oen8WzXPhk3la4qpyG4g= +k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= +k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30 h1:TRb4wNWoBVrH9plmkp2q86FIDppkbrEXdXlxU3a3BMI= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/utils v0.0.0-20190221042446-c2654d5206da h1:ElyM7RPonbKnQqOcw7dG2IK5uvQQn3b/WPHqD5mBvP4= +k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= @@ -735,6 +781,8 @@ mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZI mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2 h1:K7wru2CfJGumS5hkiguQ0Rb9ebKM2Jo8s5d4Jm9lFaM= mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2/go.mod h1:rCqoQrfAmpTX/h2APczwM7UymU/uvaOluiVPIYCSY/k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= sourcegraph.com/sqs/pbtypes v1.0.0 h1:f7lAwqviDEGvON4kRv0o5V7FT/IQK+tbkF664XMbP3o= diff --git a/go/cmd/topo2topo/plugin_kubernetestopo.go b/go/cmd/topo2topo/plugin_kubernetestopo.go new file mode 100644 index 00000000000..fde96f23f03 --- /dev/null +++ b/go/cmd/topo2topo/plugin_kubernetestopo.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// This plugin imports kubernetestopo to register the kubernetes implementation of TopoServer. + +import ( + _ "vitess.io/vitess/go/vt/topo/kubernetestopo" +) diff --git a/go/cmd/vtctld/plugin_kubernetestopo.go b/go/cmd/vtctld/plugin_kubernetestopo.go new file mode 100644 index 00000000000..3b07cbbca5c --- /dev/null +++ b/go/cmd/vtctld/plugin_kubernetestopo.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// Imports and register the 'kubernetes' topo.Server. + +import ( + _ "vitess.io/vitess/go/vt/topo/kubernetestopo" +) diff --git a/go/cmd/vtgate/plugin_kubernetestopo.go b/go/cmd/vtgate/plugin_kubernetestopo.go new file mode 100644 index 00000000000..fde96f23f03 --- /dev/null +++ b/go/cmd/vtgate/plugin_kubernetestopo.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// This plugin imports kubernetestopo to register the kubernetes implementation of TopoServer. + +import ( + _ "vitess.io/vitess/go/vt/topo/kubernetestopo" +) diff --git a/go/cmd/vttablet/plugin_kubernetestopo.go b/go/cmd/vttablet/plugin_kubernetestopo.go new file mode 100644 index 00000000000..fde96f23f03 --- /dev/null +++ b/go/cmd/vttablet/plugin_kubernetestopo.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// This plugin imports kubernetestopo to register the kubernetes implementation of TopoServer. + +import ( + _ "vitess.io/vitess/go/vt/topo/kubernetestopo" +) diff --git a/go/cmd/vtworker/plugin_kubernetestopo.go b/go/cmd/vtworker/plugin_kubernetestopo.go new file mode 100644 index 00000000000..fde96f23f03 --- /dev/null +++ b/go/cmd/vtworker/plugin_kubernetestopo.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// This plugin imports kubernetestopo to register the kubernetes implementation of TopoServer. + +import ( + _ "vitess.io/vitess/go/vt/topo/kubernetestopo" +) diff --git a/go/vt/topo/kubernetestopo/config.go b/go/vt/topo/kubernetestopo/config.go new file mode 100644 index 00000000000..e6374d79b8a --- /dev/null +++ b/go/vt/topo/kubernetestopo/config.go @@ -0,0 +1,17 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubernetestopo diff --git a/go/vt/topo/kubernetestopo/directory.go b/go/vt/topo/kubernetestopo/directory.go new file mode 100644 index 00000000000..1b94b18d94b --- /dev/null +++ b/go/vt/topo/kubernetestopo/directory.go @@ -0,0 +1,103 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreedto 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 kubernetestopo + +import ( + "path/filepath" + "sort" + "strings" + + "golang.org/x/net/context" + + corev1 "k8s.io/api/core/v1" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" +) + +// ListDir is part of the topo.Conn interface. +// It uses an internal cache to find all the objects matching a specific key and returns +// a slice of results sorted alphabetically to emulate the behavior of etcd, zk, consul, etc +func (s *Server) ListDir(ctx context.Context, dirPath string, full bool) ([]topo.DirEntry, error) { + dirPath = filepath.Join(s.root, dirPath) + + log.V(7).Infof("Listing dir at: '%s', full: %v", dirPath, full) + + dirMap := map[string]topo.DirEntry{} + + if children, err := s.memberIndexer.ByIndex("by_parent", dirPath); err == nil { + for _, obj := range children { + m := obj.(*corev1.ConfigMap) + if key, ok := m.Data["key"]; ok { + // skip duplicates + if _, ok := dirMap[key]; ok { + continue + } + + // new empty entry + e := topo.DirEntry{} + + // Clean dirPath from key to get name + key = strings.TrimPrefix(key, dirPath+"/") + + // If the key represents a directory + if strings.Contains(key, "/") { + if full { + e.Type = topo.TypeDirectory + } + + // get first part of path as name + key = strings.Split(filepath.Dir(key), "/")[0] + } else if full { + e.Type = topo.TypeFile + } + + // set name + e.Name = key + + // add to results + dirMap[e.Name] = e + } else { + log.Warningf("invalid ConfigMap in index") + } + } + } else { + return nil, err + } + + // An empty map means not found + if len(dirMap) == 0 { + return nil, topo.NewError(topo.NoNode, dirPath) + } + + // Get slice of keys + var keys []string + for key := range dirMap { + keys = append(keys, key) + } + + // sort keys + sort.Strings(keys) + + // Get ordered result + var result []topo.DirEntry + for _, k := range keys { + result = append(result, dirMap[k]) + } + + return result, nil +} diff --git a/go/vt/topo/kubernetestopo/election.go b/go/vt/topo/kubernetestopo/election.go new file mode 100644 index 00000000000..c24d3140038 --- /dev/null +++ b/go/vt/topo/kubernetestopo/election.go @@ -0,0 +1,123 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubernetestopo + +import ( + "path" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" +) + +const electionsPath = "elections" + +// NewMasterParticipation is part of the topo.Server interface +func (s *Server) NewMasterParticipation(name, id string) (topo.MasterParticipation, error) { + return &kubernetesMasterParticipation{ + s: s, + name: name, + id: id, + stop: make(chan struct{}), + done: make(chan struct{}), + }, nil +} + +// kubernetesMasterParticipation implements topo.MasterParticipation. +// +// We use a directory (in global election path, with the name) with +// ephemeral files in it, that contains the id. The oldest revision +// wins the election. +type kubernetesMasterParticipation struct { + // s is our parent kubernetes topo Server + s *Server + + // name is the name of this MasterParticipation + name string + + // id is the process's current id. + id string + + // stop is a channel closed when Stop is called. + stop chan struct{} + + // done is a channel closed when we're done processing the Stop + done chan struct{} +} + +func (mp *kubernetesMasterParticipation) getElectionPath() string { + return path.Join(mp.s.root, electionsPath, mp.name) +} + +// WaitForMastership is part of the topo.MasterParticipation interface. +func (mp *kubernetesMasterParticipation) WaitForMastership() (context.Context, error) { + // If Stop was already called, mp.done is closed, so we are interrupted. + select { + case <-mp.done: + return nil, topo.NewError(topo.Interrupted, "mastership") + default: + } + + electionPath := mp.getElectionPath() + var ld topo.LockDescriptor + + // We use a cancelable context here. If stop is closed, + // we just cancel that context. + lockCtx, lockCancel := context.WithCancel(context.Background()) + go func() { + <-mp.stop + if ld != nil { + if err := ld.Unlock(context.Background()); err != nil { + log.Errorf("failed to unlock electionPath %v: %v", electionPath, err) + } + } + lockCancel() + close(mp.done) + }() + + // Try to get the mastership, by getting a lock. + var err error + ld, err = mp.s.lock(lockCtx, electionPath, mp.id, true) + if err != nil { + // It can be that we were interrupted. + return nil, err + } + + // We got the lock. Return the lockContext. If Stop() is called, + // it will cancel the lockCtx, and cancel the returned context. + return lockCtx, nil +} + +// Stop is part of the topo.MasterParticipation interface +func (mp *kubernetesMasterParticipation) Stop() { + close(mp.stop) + <-mp.done +} + +// GetCurrentMasterID is part of the topo.MasterParticipation interface +func (mp *kubernetesMasterParticipation) GetCurrentMasterID(ctx context.Context) (string, error) { + id, _, err := mp.s.Get(ctx, mp.getElectionPath()) + if err != nil { + // NoNode means nobody is the master + if topo.IsErrType(err, topo.NoNode) { + return "", nil + } + return "", err + } + return string(id), nil +} diff --git a/go/vt/topo/kubernetestopo/error.go b/go/vt/topo/kubernetestopo/error.go new file mode 100644 index 00000000000..fdddf4985ef --- /dev/null +++ b/go/vt/topo/kubernetestopo/error.go @@ -0,0 +1,54 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubernetestopo + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/errors" + + "vitess.io/vitess/go/vt/topo" +) + +// convertError converts errors into a topo error. All errors +// are either application-level errors, or context errors. +func convertError(err error, nodePath string) error { + if err == nil { + return nil + } + + // Check for specific kubernetes errors + if errors.IsAlreadyExists(err) { + return topo.NewError(topo.NodeExists, nodePath) + } + if errors.IsNotFound(err) { + return topo.NewError(topo.NoNode, nodePath) + } + if errors.IsServerTimeout(err) { + return topo.NewError(topo.Timeout, nodePath) + } + + // Convert specific context sentinel values. + switch err { + case context.Canceled: + return topo.NewError(topo.Interrupted, nodePath) + case context.DeadlineExceeded: + return topo.NewError(topo.Timeout, nodePath) + } + + return err +} diff --git a/go/vt/topo/kubernetestopo/file.go b/go/vt/topo/kubernetestopo/file.go new file mode 100644 index 00000000000..50c5f6af9aa --- /dev/null +++ b/go/vt/topo/kubernetestopo/file.go @@ -0,0 +1,215 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreedto 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 kubernetestopo + +import ( + "encoding/base64" + "fmt" + "hash/fnv" + "path/filepath" + "strconv" + "time" + + "golang.org/x/net/context" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" +) + +// NodeReference contains the data relating to a node +type NodeReference struct { + id string + key string + value string +} + +// ToData converts a nodeReference to the data type used in the ConfigMap +func (n *NodeReference) ToData() map[string]string { + return map[string]string{ + "key": n.key, + "value": base64.StdEncoding.EncodeToString([]byte(n.value)), + } +} + +func getHash(parent string) string { + hasher := fnv.New64a() + hasher.Write([]byte(parent)) + return strconv.FormatUint(hasher.Sum64(), 10) +} + +func (s *Server) newNodeReference(key string) *NodeReference { + key = filepath.Join(s.root, key) + + node := &NodeReference{ + id: fmt.Sprintf("vt-%s", getHash(key)), + key: key, + } + + return node +} + +func (s *Server) buildFileResource(filePath string, contents []byte) *corev1.ConfigMap { + node := s.newNodeReference(filePath) + + // create data + node.value = string(contents) + + // Create "file" object + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: node.id, + Namespace: s.namespace, + }, + Data: node.ToData(), + } +} + +// Create is part of the topo.Conn interface. +func (s *Server) Create(ctx context.Context, filePath string, contents []byte) (topo.Version, error) { + log.V(7).Infof("Create at '%s' Contents: '%s'", filePath, string(contents)) + + resource := s.buildFileResource(filePath, contents) + + final, err := s.resourceClient.Create(resource) + if err != nil { + return nil, convertError(err, filePath) + } + + // Update the internal cache + err = s.memberIndexer.Update(final) + if err != nil { + return nil, convertError(err, filePath) + } + + return KubernetesVersion(final.GetResourceVersion()), nil +} + +// Update is part of the topo.Conn interface. +func (s *Server) Update(ctx context.Context, filePath string, contents []byte, version topo.Version) (topo.Version, error) { + log.V(7).Infof("Update at '%s' Contents: '%s'", filePath, string(contents)) + + resource := s.buildFileResource(filePath, contents) + + result, err := s.resourceClient.Get(resource.Name, metav1.GetOptions{}) + if err != nil && errors.IsNotFound(err) && version == nil { + // Update should create objects when the version is nil and the object is not found + result, err := s.resourceClient.Create(resource) + if err != nil { + return nil, convertError(err, filePath) + } + return KubernetesVersion(result.GetResourceVersion()), nil + } + + // If a non-nil version is given to update, fail on mismatched version + if version != nil && KubernetesVersion(result.GetResourceVersion()) != version { + return nil, topo.NewError(topo.BadVersion, filePath) + } + + // set new contents + result.Data["value"] = resource.Data["value"] + + // get result or err + final, err := s.resourceClient.Update(result) + if err != nil { + return nil, convertError(err, filePath) + } + + // Update the internal cache + err = s.memberIndexer.Update(final) + if err != nil { + return nil, convertError(err, filePath) + } + + return KubernetesVersion(final.GetResourceVersion()), nil +} + +// Get is part of the topo.Conn interface. +func (s *Server) Get(ctx context.Context, filePath string) ([]byte, topo.Version, error) { + log.V(7).Infof("Get at '%s'", filePath) + + node := s.newNodeReference(filePath) + + result, err := s.resourceClient.Get(node.id, metav1.GetOptions{}) + if err != nil { + return []byte{}, nil, convertError(err, filePath) + } + + c, hasContents := result.Data["value"] + if !hasContents { + return []byte{}, nil, convertError(fmt.Errorf("object found but has no contents"), filePath) + } + + out, err := base64.StdEncoding.DecodeString(c) + if err != nil { + return []byte{}, nil, convertError(fmt.Errorf("unable to decode object contents"), filePath) + } + + return out, KubernetesVersion(result.GetResourceVersion()), nil +} + +// Delete is part of the topo.Conn interface. +func (s *Server) Delete(ctx context.Context, filePath string, version topo.Version) error { + log.V(7).Infof("Delete at '%s'", filePath) + + node := s.newNodeReference(filePath) + + // Check version before delete + current, err := s.resourceClient.Get(node.id, metav1.GetOptions{}) + if err != nil { + return convertError(err, filePath) + } + if version != nil { + if KubernetesVersion(current.GetResourceVersion()) != version { + return topo.NewError(topo.BadVersion, filePath) + } + } + + err = s.resourceClient.Delete(node.id, &metav1.DeleteOptions{}) + if err != nil { + return convertError(err, filePath) + } + + // Wait for one of the following conditions + // 1. Context is cancelled + // 2. The object is no longer in the cache + // 3. The object in the cache has a new uid (was deleted but recreated since we last checked) + for { + select { + case <-ctx.Done(): + return convertError(ctx.Err(), filePath) + case <-time.After(50 * time.Millisecond): + } + + obj, ok, err := s.memberIndexer.Get(current) + if err != nil { // error getting from cache + return convertError(err, filePath) + } + if !ok { // deleted from cache + break + } + cached := obj.(*corev1.ConfigMap) + if cached.GetUID() != current.GetUID() { + break // deleted and recreated + } + } + + return nil +} diff --git a/go/vt/topo/kubernetestopo/lock.go b/go/vt/topo/kubernetestopo/lock.go new file mode 100644 index 00000000000..68abce4b6e2 --- /dev/null +++ b/go/vt/topo/kubernetestopo/lock.go @@ -0,0 +1,99 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubernetestopo + +import ( + "time" + + "golang.org/x/net/context" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "vitess.io/vitess/go/vt/topo" +) + +// kubernetesLockDescriptor implements topo.LockDescriptor. +type kubernetesLockDescriptor struct { + s *Server + leaseID string + leasePath string +} + +// Lock is part of the topo.Conn interface. +func (s *Server) Lock(ctx context.Context, dirPath, contents string) (topo.LockDescriptor, error) { + return s.lock(ctx, dirPath, contents, false) +} + +// lock is used by both Lock() and master election. +// it blocks until the lock is taken, interrupted, or times out +func (s *Server) lock(ctx context.Context, nodePath, contents string, createMissing bool) (topo.LockDescriptor, error) { + // Satisfy the topo.Conn interface + if !createMissing { + // Per the topo.Conn interface: + // "Returns ErrNoNode if the directory doesn't exist (meaning + // there is no existing file under that directory)." + if _, err := s.ListDir(ctx, nodePath, false); err != nil { + return nil, convertError(err, nodePath) + } + } + + resource := s.buildFileResource(nodePath, []byte(contents)) + + for { + // Try and and create the resource. The kube api will handle the actual atomic lock creation + _, err := s.resourceClient.Create(resource) + if errors.IsAlreadyExists(err) { + select { + case <-time.After(10 * time.Millisecond): + continue // retry + case <-ctx.Done(): + return nil, convertError(ctx.Err(), nodePath) + } + } else if err != nil { + return nil, convertError(err, nodePath) + } + + break + } + + return &kubernetesLockDescriptor{ + s: s, + leaseID: resource.Name, + leasePath: resource.Data["key"], + }, nil +} + +// Check is part of the topo.LockDescriptor interface. +func (ld *kubernetesLockDescriptor) Check(ctx context.Context) error { + // Get the object and ensure the leaseid + _, err := ld.s.resourceClient.Get(ld.leaseID, metav1.GetOptions{}) // TODO namespacing + if err != nil { + return convertError(err, ld.leasePath) + + } + + return nil +} + +// Unlock is part of the topo.LockDescriptor interface. +func (ld *kubernetesLockDescriptor) Unlock(ctx context.Context) error { + err := ld.s.resourceClient.Delete(ld.leaseID, &metav1.DeleteOptions{}) // TODO namespacing + if err != nil { + return convertError(err, ld.leasePath) + } + return nil +} diff --git a/go/vt/topo/kubernetestopo/server.go b/go/vt/topo/kubernetestopo/server.go new file mode 100644 index 00000000000..7139f1e3641 --- /dev/null +++ b/go/vt/topo/kubernetestopo/server.go @@ -0,0 +1,187 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package kubernetestopo implements topo.Server with the Kubernetes API as the backend. + +We expect the following behavior from the kubernetes client library: + + - TODO + +We follow these conventions within this package: + + - TODO +*/ +package kubernetestopo + +import ( + "flag" + "fmt" + "path/filepath" + "strings" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/clientcmd" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" +) + +var ( + // inCluster is a bool used to decide how to get Kubernetes api information + inCluster = flag.Bool("topo_k8s_in_cluster", false, "Use in-cluster Kubernetes configuration.") + + // kubeconfigPath is a string that gives the location of a valid kubeconfig file + kubeconfigPath = flag.String("topo_k8s_kubeconfig", "/etc/kubeconfig", "Path to a valid kubeconfig file.") +) + +// Factory is the Kubernetes topo.Factory implementation. +type Factory struct{} + +// HasGlobalReadOnlyCell is part of the topo.Factory interface. +func (f Factory) HasGlobalReadOnlyCell(serverAddr, root string) bool { + return false +} + +// Create is part of the topo.Factory interface. +func (f Factory) Create(cell, serverAddr, root string) (topo.Conn, error) { + return NewServer(serverAddr, root) +} + +// Server is the implementation of topo.Server for Kubernetes. +type Server struct { + // kubeClient is the entire kubernetes interface + kubeClient kubernetes.Interface + + // resource is a scoped-down kubernetes.Interface used for convenience + resourceClient v1.ConfigMapInterface + + // stopChan is used to tell the client-go informers to quit + stopChan chan struct{} + + // memberInformer is the controller that syncronized the cache of data + memberInformer cache.Controller + + // memberIndexer is the cache of tree data + memberIndexer cache.Indexer + + // namespace is the Kubernetes namespace to be used for all resources + namespace string + + // root is the root path for this client. + // used for resource prefixing + root string +} + +// Close implements topo.Server.Close. +// It will nil out the global and cells fields, so any attempt to +// re-use this server will panic. +func (s *Server) Close() { + close(s.stopChan) +} +func getKeyParents(key string) []string { + parents := []string{""} + parent := []string{} + for _, segment := range strings.Split(filepath.Dir(key), "/") { + parent = append(parent, segment) + parents = append(parents, strings.Join(parent, "/")) + } + return parents +} + +func indexByParent(obj interface{}) ([]string, error) { + if key, ok := obj.(*corev1.ConfigMap).Data["key"]; ok { + return getKeyParents(key), nil + } + return []string{""}, nil +} + +// syncTree starts and syncs the member objects that form the directory "tree" +func (s *Server) syncTree() error { + // Create the informer / indexer + restClient := s.kubeClient.CoreV1().RESTClient() + listwatch := cache.NewListWatchFromClient(restClient, "configmaps", s.namespace, fields.Everything()) + + // set up index funcs + indexers := cache.Indexers{} + indexers["by_parent"] = indexByParent + + s.memberIndexer, s.memberInformer = cache.NewIndexerInformer(listwatch, &corev1.ConfigMap{}, 0, + cache.ResourceEventHandlerFuncs{}, indexers) + + // Start indexer + go s.memberInformer.Run(s.stopChan) + + // Wait for sync + log.Info("Waiting for Kubernetes topo cache sync") + if !cache.WaitForCacheSync(s.stopChan, s.memberInformer.HasSynced) { + return fmt.Errorf("timed out waiting for caches to sync") + } + log.Info("Kubernetes topo cache sync completed") + + return nil +} + +// NewServer returns a new kubernetestopo.Server. +func NewServer(serverAddr, root string) (*Server, error) { + log.Info("Creating new Kubernetes topo server at ", serverAddr, " root:", root) + var config *rest.Config + var err error + if *inCluster { + config, err = rest.InClusterConfig() + if err != nil { + return nil, fmt.Errorf("error getting Kubernetes in-cluster client config: %s", err) + } + } else { + // use the current context in kubeconfig + config, err = clientcmd.BuildConfigFromFlags("", *kubeconfigPath) + if err != nil { + return nil, fmt.Errorf("error getting Kubernetes client config: %s", err) + } + } + + // create the kubernetes client + kubeClientset, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, fmt.Errorf("error creating Kubernetes client: %s", err) + } + + // Create the server + namespace := "default" // TODO: namespace from config context? + s := &Server{ + namespace: namespace, + kubeClient: kubeClientset, + resourceClient: kubeClientset.CoreV1().ConfigMaps(namespace), + root: root, + stopChan: make(chan struct{}), + } + + // Sync cache + if err = s.syncTree(); err != nil { + return nil, err + } + + return s, nil +} + +func init() { + topo.RegisterFactory("k8s", Factory{}) +} diff --git a/go/vt/topo/kubernetestopo/server_test.go b/go/vt/topo/kubernetestopo/server_test.go new file mode 100644 index 00000000000..ef1dd117024 --- /dev/null +++ b/go/vt/topo/kubernetestopo/server_test.go @@ -0,0 +1,132 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubernetestopo + +import ( + "context" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path" + "time" + + "testing" + + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/test" +) + +func TestKubernetesTopo(t *testing.T) { + // Create a data dir for test data + testDataDir, err := ioutil.TempDir("", "vt-test-k3s") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(testDataDir) // clean up + + // Gen a temp file name for the config + testConfig, err := ioutil.TempFile("", "vt-test-k3s-config") + if err != nil { + t.Fatal(err) + } + testConfigPath := testConfig.Name() + defer os.Remove(testConfigPath) // clean up + + k3sArgs := []string{ + "server", "start", + "--write-kubeconfig=" + testConfigPath, + "--data-dir=" + testDataDir, + "--https-listen-port=6663", + "--disable-agent", "--flannel-backend=none", + "--disable-network-policy", + "--disable-cloud-controller", + "--disable-scheduler", + "--no-deploy=coredns,servicelb,traefik,local-storage,metrics-server", + "--kube-controller-manager-arg=port=10253", + + "--log=/tmp/k3svtlog", + } + + // Start a minimal k3s daemon, and close it after all tests are done. + ctx, killK3s := context.WithCancel(context.Background()) + c := exec.CommandContext(ctx, "k3s", k3sArgs...) + + // Start in the background and kill when tests end + t.Log("Starting k3s") + err = c.Start() + if err != nil { + t.Fatal("Unable to start k3s", err) + } + defer killK3s() + + // Wait for server to be ready + for { + t.Log("Waiting for server to be ready") + time.Sleep(time.Second) + config, err := clientcmd.BuildConfigFromFlags("", testConfigPath) + if err != nil { + continue + } + + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + log.Fatal("Invalid kubeconfig", config) + } + + _, err = clientset.ServerVersion() + if err != nil { + t.Log(err) + } + + break + } + + serverAddr := "default" + flag.Set("topo_k8s_kubeconfig", testConfigPath) + + // Run the test suite. + testIndex := 0 + test.TopoServerTestSuite(t, func() *topo.Server { + // Each test will use its own sub-directories. + // The directories will be created when used the first time. + testRoot := fmt.Sprintf("/test-%v", testIndex) + testIndex++ + + globalRoot := path.Join(testRoot, topo.GlobalCell) + cellRoot := path.Join(testRoot, test.LocalCellName) + + ts, err := topo.OpenServer("k8s", serverAddr, globalRoot) + if err != nil { + t.Fatalf("OpenServer() failed: %v", err) + } + if err := ts.CreateCellInfo(context.Background(), test.LocalCellName, &topodatapb.CellInfo{ + ServerAddress: serverAddr, + Root: cellRoot, + }); err != nil { + t.Fatalf("CreateCellInfo() failed: %v", err) + } + + return ts + }) +} diff --git a/go/vt/topo/kubernetestopo/version.go b/go/vt/topo/kubernetestopo/version.go new file mode 100644 index 00000000000..20f06cd3d80 --- /dev/null +++ b/go/vt/topo/kubernetestopo/version.go @@ -0,0 +1,40 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreedto 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 kubernetestopo + +import ( + "vitess.io/vitess/go/vt/topo" +) + +// KubernetesVersion is Kubernetes's idea of a version. +// It implements topo.Version. +type KubernetesVersion string + +// String is part of the topo.Version interface. +func (v KubernetesVersion) String() string { + return string(v) +} + +// VersionFromInt is used by old-style functions to create a proper +// Version: if version is -1, returns nil. Otherwise returns the +// KubernetesVersion object. +func VersionFromInt(version int64) topo.Version { + if version == -1 { + return nil + } + return KubernetesVersion(version) +} diff --git a/go/vt/topo/kubernetestopo/watch.go b/go/vt/topo/kubernetestopo/watch.go new file mode 100644 index 00000000000..ad129c1f15f --- /dev/null +++ b/go/vt/topo/kubernetestopo/watch.go @@ -0,0 +1,117 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreedto 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 kubernetestopo + +import ( + "encoding/base64" + + "golang.org/x/net/context" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/client-go/tools/cache" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" +) + +// Watch is part of the topo.Conn interface. +func (s *Server) Watch(ctx context.Context, filePath string) (*topo.WatchData, <-chan *topo.WatchData, topo.CancelFunc) { + log.Info("Starting Kubernetes topo Watch") + + current := &topo.WatchData{} + + // get current + contents, ver, err := s.Get(ctx, filePath) + if err != nil { + // Per the topo.Conn interface: + // "If the initial read fails, or the file doesn't + // exist, current.Err is set, and 'changes'/'cancel' are nil." + current.Err = err + return current, nil, nil + } + current.Contents = contents + current.Version = ver + + // Create a context, will be used to cancel the watch. + watchCtx, watchCancel := context.WithCancel(context.Background()) + + // Create the changes channel + changes := make(chan *topo.WatchData, 10) + + // Create a signal channel for non-interrupt shutdowns + gracefulShutdown := make(chan struct{}) + + // Create the informer / indexer to watch the single resource + restClient := s.kubeClient.CoreV1().RESTClient() + listwatch := cache.NewListWatchFromClient(restClient, "configmaps", s.namespace, fields.OneTermEqualSelector("metadata.name", s.buildFileResource(filePath, []byte{}).Name)) + + s.memberIndexer, s.memberInformer = cache.NewIndexerInformer(listwatch, &corev1.ConfigMap{}, 0, + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + cm := obj.(*corev1.ConfigMap) + out, err := base64.StdEncoding.DecodeString(cm.Data["value"]) + if err != nil { + changes <- &topo.WatchData{Err: err} + close(gracefulShutdown) + } else { + changes <- &topo.WatchData{ + Contents: out, + Version: KubernetesVersion(cm.GetResourceVersion()), + } + } + }, + UpdateFunc: func(oldObj, newObj interface{}) { + cm := newObj.(*corev1.ConfigMap) + out, err := base64.StdEncoding.DecodeString(cm.Data["value"]) + if err != nil { + changes <- &topo.WatchData{Err: err} + close(gracefulShutdown) + } else { + changes <- &topo.WatchData{ + Contents: out, + Version: KubernetesVersion(cm.GetResourceVersion()), + } + } + }, + DeleteFunc: func(obj interface{}) { + cm := obj.(*corev1.ConfigMap) + changes <- &topo.WatchData{Err: topo.NewError(topo.NoNode, cm.Name)} + close(gracefulShutdown) + }, + }, cache.Indexers{}) + + // create control chan for informer and start it + informerChan := make(chan struct{}) + go s.memberInformer.Run(informerChan) + + // Handle interrupts + go closeOnDone(watchCtx, filePath, informerChan, gracefulShutdown, changes) + + return current, changes, topo.CancelFunc(watchCancel) +} + +func closeOnDone(ctx context.Context, filePath string, informerChan chan struct{}, gracefulShutdown chan struct{}, changes chan *topo.WatchData) { + select { + case <-ctx.Done(): + if err := ctx.Err(); err != nil && err == context.Canceled { + changes <- &topo.WatchData{Err: topo.NewError(topo.Interrupted, filePath)} + } + case <-gracefulShutdown: + } + close(informerChan) + close(changes) +} diff --git a/go/vt/vtctl/plugin_kubernetestopo.go b/go/vt/vtctl/plugin_kubernetestopo.go new file mode 100644 index 00000000000..b7d94cdb475 --- /dev/null +++ b/go/vt/vtctl/plugin_kubernetestopo.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreedto 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 vtctl + +import ( + // Imports kubernetestopo to register the kubernetes implementation of + // TopoServer. + _ "vitess.io/vitess/go/vt/topo/kubernetestopo" +) diff --git a/vendor/vendor.json b/vendor/vendor.json new file mode 100644 index 00000000000..978ca5d504e --- /dev/null +++ b/vendor/vendor.json @@ -0,0 +1,2213 @@ +{ + "comment": "", + "ignore": "appengine test", + "package": [ + { + "checksumSHA1": "ZLRh6zW4/DnVsGpgtt+ZiIaEFKc=", + "path": "cloud.google.com/go/compute/metadata", + "revision": "686f0e89858ea78eae54d4b2021e6bfc7d3a30ca", + "revisionTime": "2016-12-16T21:27:53Z" + }, + { + "checksumSHA1": "4iounbuF7SMZdx/MlKSUuhnV848=", + "path": "cloud.google.com/go/internal", + "revision": "686f0e89858ea78eae54d4b2021e6bfc7d3a30ca", + "revisionTime": "2016-12-16T21:27:53Z" + }, + { + "checksumSHA1": "W2xJ0+fvugRhRi1PMi64bYofBbU=", + "path": "cloud.google.com/go/internal/optional", + "revision": "686f0e89858ea78eae54d4b2021e6bfc7d3a30ca", + "revisionTime": "2016-12-16T21:27:53Z" + }, + { + "checksumSHA1": "9q9/aJWq19uF6NE4tx4qJvP5Uho=", + "path": "cloud.google.com/go/internal/testutil", + "revision": "686f0e89858ea78eae54d4b2021e6bfc7d3a30ca", + "revisionTime": "2016-12-16T21:27:53Z" + }, + { + "checksumSHA1": "cHbMVt14iTMFZHeZMM9Q06dSV+M=", + "path": "cloud.google.com/go/storage", + "revision": "686f0e89858ea78eae54d4b2021e6bfc7d3a30ca", + "revisionTime": "2016-12-16T21:27:53Z" + }, + { + "checksumSHA1": "t5pzf8AGtuCmECrPlJM9oAky+dk=", + "path": "github.com/aws/aws-sdk-go/aws", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", + "path": "github.com/aws/aws-sdk-go/aws/awserr", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", + "path": "github.com/aws/aws-sdk-go/aws/awsutil", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "wGf8GkrbZe2VFXOo28K0jq68A+g=", + "path": "github.com/aws/aws-sdk-go/aws/client", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", + "path": "github.com/aws/aws-sdk-go/aws/client/metadata", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "U2W3pMTHfONS6R/QP/Zg18+89TQ=", + "path": "github.com/aws/aws-sdk-go/aws/corehandlers", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "Y+cPwQL0dZMyqp3wI+KJWmA9KQ8=", + "path": "github.com/aws/aws-sdk-go/aws/credentials", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", + "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", + "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "JEYqmF83O5n5bHkupAzA6STm0no=", + "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "OnU/n7R33oYXiB4SAGd5pK7I0Bs=", + "path": "github.com/aws/aws-sdk-go/aws/defaults", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "pDnK93CqjQ4ROSW8Y/RuHXjv52M=", + "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "dUurC4Vz9SYV3ZSSP+aM+DH4F14=", + "path": "github.com/aws/aws-sdk-go/aws/endpoints", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "FpjCPoRNsVKM1hOg9EpC7jn5pRI=", + "path": "github.com/aws/aws-sdk-go/aws/request", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "DIn7B+oP++/nw603OB95fmupzu8=", + "path": "github.com/aws/aws-sdk-go/aws/session", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "4gwCpxPnVQISJGF/skyWpzzxFAc=", + "path": "github.com/aws/aws-sdk-go/aws/signer/v4", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "MxSiiCoPpY1mCRjyEFClUu3e14w=", + "path": "github.com/aws/aws-sdk-go/awstesting", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "iOAj9X968hli6R2oCTjFVQPH5Ug=", + "path": "github.com/aws/aws-sdk-go/awstesting/mock", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "MIp5H1niMhCZFAwYsjJx9NxmHIc=", + "path": "github.com/aws/aws-sdk-go/awstesting/unit", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "MYLldFRnsZh21TfCkgkXCT3maPU=", + "path": "github.com/aws/aws-sdk-go/internal/sdkrand", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "04ypv4x12l4q0TksA1zEVsmgpvw=", + "path": "github.com/aws/aws-sdk-go/internal/shareddefaults", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "sgft7A0lRCVD7QBogydg46lr3NM=", + "path": "github.com/aws/aws-sdk-go/private/endpoints", + "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", + "revisionTime": "2016-06-13T21:28:44Z" + }, + { + "checksumSHA1": "NStHCXEvYqG72GknZyv1jaKaeH0=", + "path": "github.com/aws/aws-sdk-go/private/protocol", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", + "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "yHfT5DTbeCLs4NE2Rgnqrhe15ls=", + "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", + "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", + "path": "github.com/aws/aws-sdk-go/private/protocol/query", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "9V1PvtFQ9MObZTc3sa86WcuOtOU=", + "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "pkeoOfZpHRvFG/AOZeTf0lwtsFg=", + "path": "github.com/aws/aws-sdk-go/private/protocol/rest", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "Rpu8KBtHZgvhkwHxUfaky+qW+G4=", + "path": "github.com/aws/aws-sdk-go/private/protocol/restjson", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", + "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "0qYPUga28aQVkxZgBR3Z86AbGUQ=", + "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "wZbHPxkyYsr5h6GW5OVh9qIMZR8=", + "path": "github.com/aws/aws-sdk-go/private/signer/v4", + "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", + "revisionTime": "2016-06-13T21:28:44Z" + }, + { + "checksumSHA1": "01b4hmyUzoReoOyEDylDinWBSdA=", + "path": "github.com/aws/aws-sdk-go/private/util", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", + "path": "github.com/aws/aws-sdk-go/private/waiter", + "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", + "revisionTime": "2016-06-13T21:28:44Z" + }, + { + "checksumSHA1": "0nPnGWlegQG7bn/iIIfjJFoljyU=", + "path": "github.com/aws/aws-sdk-go/service/cloudfront", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "8JiVrxMjFSdBOfVWCy1QU+JzB08=", + "path": "github.com/aws/aws-sdk-go/service/dynamodb", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "/I6I2nR59isqKtSpEnTfLRWZ8Mc=", + "path": "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "roq8pXva49Jq13gh5n6iiZ+LXBc=", + "path": "github.com/aws/aws-sdk-go/service/ec2", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "SZ7yLDZ6RvMhpWe0Goyem64kgyA=", + "path": "github.com/aws/aws-sdk-go/service/elastictranscoder", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "DfzNze8B3ME2tV3TtXP7eQXUjD0=", + "path": "github.com/aws/aws-sdk-go/service/kinesis", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "KPRDrVt4hrFBmJ2le8HebKphfjE=", + "path": "github.com/aws/aws-sdk-go/service/route53", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "fXQn3V0ZRBZpTXUEHl4/yOjR4mQ=", + "path": "github.com/aws/aws-sdk-go/service/s3", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "ZP6QI0X9BNKk8o1p3AyLfjabS20=", + "path": "github.com/aws/aws-sdk-go/service/s3/s3iface", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "N+U01iPy566cfzEY+dliw/fYEdE=", + "path": "github.com/aws/aws-sdk-go/service/s3/s3manager", + "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", + "revisionTime": "2018-02-23T17:39:05Z" + }, + { + "checksumSHA1": "x7HCNPJnQi+4P6FKpBTY1hm3m6o=", + "path": "github.com/aws/aws-sdk-go/service/sts", + "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", + "revisionTime": "2018-02-23T18:40:12Z" + }, + { + "checksumSHA1": "4QnLdmB1kG3N+KlDd1N+G9TWAGQ=", + "path": "github.com/beorn7/perks/quantile", + "revision": "3ac7bf7a47d159a033b107610db8a1b6575507a4", + "revisionTime": "2016-02-29T21:34:45Z" + }, + { + "checksumSHA1": "7BC2/27NId9xaPDB5w3nWN2mn9A=", + "path": "github.com/coreos/etcd/auth/authpb", + "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", + "revisionTime": "2017-06-26T01:50:32Z" + }, + { + "checksumSHA1": "MljqP0GJ8+FxtIDFxmCtkmt+Auo=", + "path": "github.com/coreos/etcd/clientv3", + "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", + "revisionTime": "2017-06-26T01:50:32Z" + }, + { + "checksumSHA1": "PnBbh5xS4/RtluD+Vatock/WZts=", + "path": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", + "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", + "revisionTime": "2017-06-26T01:50:32Z" + }, + { + "checksumSHA1": "7xBiCrhCPYjgh2TAsZP9hBLzDgA=", + "path": "github.com/coreos/etcd/etcdserver/etcdserverpb", + "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", + "revisionTime": "2017-06-26T01:50:32Z" + }, + { + "checksumSHA1": "JAkX9DfIBrSe0vUa07xl5cikxVQ=", + "path": "github.com/coreos/etcd/mvcc/mvccpb", + "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", + "revisionTime": "2017-06-26T01:50:32Z" + }, + { + "checksumSHA1": "Ggn+h7g45yWJ9QWZtZ3Vu2qevcQ=", + "path": "github.com/coreos/go-etcd/etcd", + "revision": "f02171fbd43c7b9b53ce8679b03235a1ef3c7b12", + "revisionTime": "2015-04-16T20:55:17Z", + "version": "=v2.0.0", + "versionExact": "v2.0.0" + }, + { + "checksumSHA1": "5rPfda8jFccr3A6heL+JAmi9K9g=", + "path": "github.com/davecgh/go-spew/spew", + "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d", + "revisionTime": "2015-11-05T21:09:06Z" + }, + { + "checksumSHA1": "a2yC46a1qsJomgY6rb+FkTFiqmE=", + "path": "github.com/davecgh/go-spew/spew/testdata", + "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d", + "revisionTime": "2015-11-05T21:09:06Z" + }, + { + "checksumSHA1": "zU2dfs0DHHfogk+nq4STY3+AVmY=", + "path": "github.com/evanphx/json-patch", + "revision": "e2b4af1181aee3588b4fefcda56e9e9d98ea913f", + "revisionTime": "2018-10-01T23:40:57Z" + }, + { + "checksumSHA1": "muGVyM8mY3/gcap6kr4Ib3F5Xn4=", + "path": "github.com/ghodss/yaml", + "revision": "04f313413ffd65ce25f2541bfd2b2ceec5c0908c", + "revisionTime": "2016-12-07T00:33:20Z" + }, + { + "checksumSHA1": "FfdxnQ4CZVJJvG4BC1fWavgperI=", + "path": "github.com/go-ini/ini", + "revision": "72ba3e6b9e6b87e0c74c9a7a4dc86e8dd8ba4355", + "revisionTime": "2016-06-01T19:11:21Z" + }, + { + "checksumSHA1": "HmbftipkadrLlCfzzVQ+iFHbl6g=", + "path": "github.com/golang/glog", + "revision": "23def4e6c14b4da8ac2ed8007337bc5eb5007998", + "revisionTime": "2016-01-25T20:49:56Z" + }, + { + "checksumSHA1": "M3BUApw7nNipzKvYbHSpxqE04FY=", + "path": "github.com/golang/mock/gomock", + "revision": "13f360950a79f5864a972c786a10a50e44b69541", + "revisionTime": "2017-07-22T14:45:13Z", + "version": "v1.0.0", + "versionExact": "v1.0.0" + }, + { + "checksumSHA1": "ks9nCA68MefWDMUIjIF/zJwpTuw=", + "path": "github.com/golang/mock/gomock/mock_matcher", + "revision": "bd3c8e81be01eef76d4b503f5e687d2d1354d2d9", + "revisionTime": "2016-01-21T18:51:14Z" + }, + { + "checksumSHA1": "BP2buXHHOKxI5eYS2xELVng2kf4=", + "path": "github.com/golang/protobuf/jsonpb", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "3QpmjZApyomODlDRgXomf4DgsJU=", + "path": "github.com/golang/protobuf/jsonpb/jsonpb_test_proto", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "mE9XW26JSpe4meBObM6J/Oeq0eg=", + "path": "github.com/golang/protobuf/proto", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "DlygQR0Ml7JuGquUo2U4C0MJLBs=", + "path": "github.com/golang/protobuf/proto/proto3_proto", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "jI4LkaFUi2rO9vZwvIJJ9tCY6mM=", + "path": "github.com/golang/protobuf/proto/test_proto", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "A0DxiyxXV4u8PmwUwlVkQ2CKyiQ=", + "path": "github.com/golang/protobuf/proto/testdata", + "revision": "1909bc2f63dc92bb931deace8b8312c4db72d12f", + "revisionTime": "2017-08-08T02:16:21Z" + }, + { + "checksumSHA1": "iqWBA0GWNr+cwAdF2KVy1eq9mlU=", + "path": "github.com/golang/protobuf/protoc-gen-go", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "DA2cyOt1W92RTyXAqKQ4JWKGR8U=", + "path": "github.com/golang/protobuf/protoc-gen-go/descriptor", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "+BH6O73wJlqOQtPGpmnT+5l3tAw=", + "path": "github.com/golang/protobuf/protoc-gen-go/generator", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "uY4dEtqaAe5gsU8gbpCI1JgEIII=", + "path": "github.com/golang/protobuf/protoc-gen-go/generator/internal/remap", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "EGcFhhLBcZ2f7hTDhtkuK6q1MUc=", + "path": "github.com/golang/protobuf/protoc-gen-go/grpc", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "h4PLbJDYnRmcUuf56USJ5K3xJOg=", + "path": "github.com/golang/protobuf/protoc-gen-go/plugin", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "/vLtyN6HK5twSZIFerD199YTmjk=", + "path": "github.com/golang/protobuf/protoc-gen-go/testdata/multi", + "revision": "2bc9827a78f95c6665b5fe0abd1fd66b496ae2d8", + "revisionTime": "2016-11-03T22:44:32Z" + }, + { + "checksumSHA1": "tkJPssYejSjuAwE2tdEnoEIj93Q=", + "path": "github.com/golang/protobuf/ptypes", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "G0aiY+KmzFsQLTNzRAGRhJNSj7A=", + "path": "github.com/golang/protobuf/ptypes/any", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "kjVDCbK5/WiHqP1g4GMUxm75jos=", + "path": "github.com/golang/protobuf/ptypes/duration", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "VCwyXqpYo81QNvC7z6nsp+yczc4=", + "path": "github.com/golang/protobuf/ptypes/struct", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "FdeygjOuyR2p5v9b0kNOtzfpjS4=", + "path": "github.com/golang/protobuf/ptypes/timestamp", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "7sWfJ35gaddpCbcKYZRG2nL6eQo=", + "path": "github.com/golang/protobuf/ptypes/wrappers", + "revision": "aa810b61a9c79d51363740d207bb46cf8e620ed5", + "revisionTime": "2018-08-14T21:14:27Z", + "version": "v1.2.0", + "versionExact": "v1.2.0" + }, + { + "checksumSHA1": "p/8vSviYF91gFflhrt5vkyksroo=", + "path": "github.com/golang/snappy", + "revision": "553a641470496b2327abcac10b36396bd98e45c9", + "revisionTime": "2017-02-15T23:32:05Z" + }, + { + "checksumSHA1": "V/53BpqgOkSDZCX6snQCAkdO2fM=", + "path": "github.com/googleapis/gax-go", + "revision": "da06d194a00e19ce00d9011a13931c3f6f6887c7", + "revisionTime": "2016-11-07T00:24:06Z" + }, + { + "checksumSHA1": "P3zGmsNjW8m15a+nks4FdVpFKwE=", + "path": "github.com/gopherjs/gopherjs/js", + "revision": "a727a4a1dd2f292e948cebe6ec9aef1a7863f145", + "revisionTime": "2016-06-12T21:17:59Z" + }, + { + "checksumSHA1": "klfNfdEPsrWYLps2qBkLgfJsNYI=", + "path": "github.com/gorilla/websocket", + "revision": "2d1e4548da234d9cb742cc3628556fef86aafbac", + "revisionTime": "2016-09-12T15:30:41Z" + }, + { + "checksumSHA1": "9dP53doJ/haDqTJyD0iuv8g0XFs=", + "path": "github.com/grpc-ecosystem/go-grpc-prometheus", + "revision": "39de4380c2e0353a115b80b1c730719c79bfb771", + "revisionTime": "2018-04-18T17:09:36Z" + }, + { + "checksumSHA1": "LoEQ+t5UoMm4InaYVPVn0XqHPwA=", + "path": "github.com/grpc-ecosystem/grpc-gateway/runtime", + "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", + "revisionTime": "2016-11-28T00:20:07Z" + }, + { + "checksumSHA1": "x396LPNfci/5x8aVJbliQHH11HQ=", + "path": "github.com/grpc-ecosystem/grpc-gateway/runtime/internal", + "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", + "revisionTime": "2016-11-28T00:20:07Z" + }, + { + "checksumSHA1": "vqiK5r5dntV7JNZ+ZsGlD0Samos=", + "path": "github.com/grpc-ecosystem/grpc-gateway/utilities", + "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", + "revisionTime": "2016-11-28T00:20:07Z" + }, + { + "checksumSHA1": "LQOVduohnld12Px2o0MfYDPI7oQ=", + "path": "github.com/hashicorp/consul/api", + "revision": "0bddfa23a2ebe3c0773d917fc104f53d74f7a5ec", + "revisionTime": "2018-11-14T22:37:47Z", + "version": "v1.4.0", + "versionExact": "v1.4.0" + }, + { + "checksumSHA1": "Uzyon2091lmwacNsl1hCytjhHtg=", + "path": "github.com/hashicorp/go-cleanhttp", + "revision": "ad28ea4487f05916463e2423a55166280e8254b5", + "revisionTime": "2016-04-07T17:41:26Z" + }, + { + "checksumSHA1": "A1PcINvF3UiwHRKn8UcgARgvGRs=", + "path": "github.com/hashicorp/go-rootcerts", + "revision": "6bb64b370b90e7ef1fa532be9e591a81c3493e00", + "revisionTime": "2016-05-03T14:34:40Z" + }, + { + "checksumSHA1": "4K1LTDKblIXwDEhNQULXcRKMbB0=", + "path": "github.com/hashicorp/golang-lru", + "revision": "20f1fb78b0740ba8c3cb143a61e86ba5c8669768", + "revisionTime": "2018-08-30T03:29:55Z" + }, + { + "checksumSHA1": "NvkV52M5EFd0kT4U+9A2Eu/kKr8=", + "path": "github.com/hashicorp/golang-lru/simplelru", + "revision": "20f1fb78b0740ba8c3cb143a61e86ba5c8669768", + "revisionTime": "2018-08-30T03:29:55Z" + }, + { + "checksumSHA1": "E3Xcanc9ouQwL+CZGOUyA/+giLg=", + "path": "github.com/hashicorp/serf/coordinate", + "revision": "d3a67ab21bc8a4643fa53a3633f2d951dd50c6ca", + "revisionTime": "2016-12-07T01:17:43Z" + }, + { + "checksumSHA1": "yw6trQTxmryPs2hvnI5LHNw3xjc=", + "path": "github.com/imdario/mergo", + "revision": "ca3dcc1022bae9b5510f3c83705b72db1b1a96f9", + "revisionTime": "2018-11-07T19:11:38Z" + }, + { + "checksumSHA1": "fe0NspvyJjx6DhmTjIpO0zmR+kg=", + "path": "github.com/influxdb/influxdb/client", + "revision": "afde71eb1740fd763ab9450e1f700ba0e53c36d0", + "revisionTime": "2014-12-28T19:15:54Z", + "version": "=v0.8.8", + "versionExact": "v0.8.8" + }, + { + "checksumSHA1": "0ZrwvB6KoGPj2PoDNSEJwxQ6Mog=", + "path": "github.com/jmespath/go-jmespath", + "revision": "0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74", + "revisionTime": "2016-02-02T18:50:14Z" + }, + { + "checksumSHA1": "tewA7jXVGCw1zb5mA0BDecWi4iQ=", + "path": "github.com/jtolds/gls", + "revision": "8ddce2a84170772b95dd5d576c48d517b22cac63", + "revisionTime": "2016-01-05T22:08:40Z" + }, + { + "checksumSHA1": "rmCbOBewXcbEdHRerzoanS+kI2U=", + "path": "github.com/klauspost/compress/flate", + "revision": "b50017755d442260d792c34c7c43216d9ba7ffc7", + "revisionTime": "2018-08-01T09:52:37Z" + }, + { + "checksumSHA1": "vGHBCcWkLCbAc3PJcRs7vFbvaYM=", + "path": "github.com/klauspost/cpuid", + "revision": "e7e905edc00ea8827e58662220139109efea09db", + "revisionTime": "2018-04-05T13:32:22Z" + }, + { + "checksumSHA1": "6/zXof97s7P9tlNp3mUioXgeEVI=", + "path": "github.com/klauspost/crc32", + "revision": "bab58d77464aa9cf4e84200c3276da0831fe0c03", + "revisionTime": "2017-06-28T07:24:49Z" + }, + { + "checksumSHA1": "N4EMcnfxHl1f4TQsKQWX/yLF/BE=", + "path": "github.com/klauspost/pgzip", + "revision": "c4ad2ed77aece7b3270909769a30a3fcea262a66", + "revisionTime": "2018-07-17T08:42:24Z" + }, + { + "checksumSHA1": "DdH3xAkzAWJ4B/LGYJyCeRsly2I=", + "path": "github.com/mattn/go-runewidth", + "revision": "d6bea18f789704b5f83375793155289da36a3c7f", + "revisionTime": "2016-03-15T04:07:12Z" + }, + { + "checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=", + "path": "github.com/matttproud/golang_protobuf_extensions/pbutil", + "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", + "revisionTime": "2016-04-24T11:30:07Z" + }, + { + "checksumSHA1": "fROk3NEFAz88JXptqo4kpwD15Ic=", + "path": "github.com/matttproud/golang_protobuf_extensions/testdata", + "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", + "revisionTime": "2016-04-24T11:30:07Z" + }, + { + "checksumSHA1": "Oi8lZYAVzy67goiwBWBDot28s6k=", + "path": "github.com/minio/minio-go", + "revision": "9f282f76643244430e3d0b69dc7285628a8db8a7", + "revisionTime": "2016-07-19T21:19:03Z", + "version": "v2.0.1", + "versionExact": "v2.0.1" + }, + { + "checksumSHA1": "V/quM7+em2ByJbWBLOsEwnY3j/Q=", + "path": "github.com/mitchellh/go-homedir", + "revision": "b8bc1bf767474819792c23f32d8286a45736f1c6", + "revisionTime": "2016-12-03T19:45:07Z" + }, + { + "checksumSHA1": "J+g0oZePWp2zSIISD2dZZKTxmgg=", + "path": "github.com/mitchellh/mapstructure", + "revision": "3536a929edddb9a5b34bd6861dc4a9647cb459fe", + "revisionTime": "2018-10-05T04:51:35Z" + }, + { + "checksumSHA1": "txj5yUDiaSATtBLDlT0f6uaiIP8=", + "path": "github.com/olekukonko/tablewriter", + "revision": "cca8bbc0798408af109aaaa239cbd2634846b340", + "revisionTime": "2016-01-15T11:10:02Z" + }, + { + "checksumSHA1": "mhvIMH8oAtOiEyg37zWKmgb+6v4=", + "path": "github.com/pborman/uuid", + "revision": "b984ec7fa9ff9e428bd0cf0abf429384dfbe3e37", + "revisionTime": "2016-08-24T21:06:00Z" + }, + { + "checksumSHA1": "LuFv4/jlrmFNnDb/5SCSEPAM9vU=", + "path": "github.com/pmezard/go-difflib/difflib", + "revision": "792786c7400a136282c1664665ae0a8db921c6c2", + "revisionTime": "2016-01-10T10:55:54Z" + }, + { + "checksumSHA1": "I87tkF1e/hrl4d/XIKFfkPRq1ww=", + "path": "github.com/prometheus/client_golang/prometheus", + "revision": "d49167c4b9f3c4451707560c5c71471ff5291aaa", + "revisionTime": "2018-03-19T13:17:21Z" + }, + { + "checksumSHA1": "mIWVz1E1QJ6yZnf7ELNwLboyK4w=", + "path": "github.com/prometheus/client_golang/prometheus/promhttp", + "revision": "d49167c4b9f3c4451707560c5c71471ff5291aaa", + "revisionTime": "2018-03-19T13:17:21Z" + }, + { + "checksumSHA1": "DvwvOlPNAgRntBzt3b3OSRMS2N4=", + "path": "github.com/prometheus/client_model/go", + "revision": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6", + "revisionTime": "2015-02-12T10:17:44Z" + }, + { + "checksumSHA1": "m+nrHcRrjgi0wEa5PODKnY5yNX8=", + "path": "github.com/prometheus/common/expfmt", + "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", + "revisionTime": "2016-06-07T09:43:39Z" + }, + { + "checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=", + "path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", + "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", + "revisionTime": "2016-06-07T09:43:39Z" + }, + { + "checksumSHA1": "Jx0GXl5hGnO25s3ryyvtdWHdCpw=", + "path": "github.com/prometheus/common/model", + "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", + "revisionTime": "2016-06-07T09:43:39Z" + }, + { + "checksumSHA1": "W218eJZPXJG783fUr/z6IaAZyes=", + "path": "github.com/prometheus/procfs", + "revision": "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5", + "revisionTime": "2016-04-11T19:08:41Z" + }, + { + "checksumSHA1": "dF3fORwN1HTgrlrdmll9K2cOjOg=", + "path": "github.com/samuel/go-zookeeper/zk", + "revision": "e64db453f3512cade908163702045e0f31137843", + "revisionTime": "2016-06-16T02:49:54Z" + }, + { + "checksumSHA1": "zmC8/3V4ls53DJlNTKDZwPSC/dA=", + "path": "github.com/satori/go.uuid", + "revision": "0aa62d5ddceb50dbcb909d790b5345affd3669b6", + "revisionTime": "2016-07-13T18:03:06Z" + }, + { + "checksumSHA1": "v7C+aJ1D/z3MEeCte6bxvpoGjM4=", + "path": "github.com/sergi/go-diff/diffmatchpatch", + "revision": "feef008d51ad2b3778f85d387ccf91735543008d", + "revisionTime": "2017-04-09T07:17:39Z" + }, + { + "checksumSHA1": "6AYg4fjEvFuAVN3wHakGApjhZAM=", + "path": "github.com/smartystreets/assertions", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "Vzb+dEH/LTYbvr8RXHmt6xJHz04=", + "path": "github.com/smartystreets/assertions/internal/go-render/render", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "SLC6TfV4icQA9l8YJQu8acJYbuo=", + "path": "github.com/smartystreets/assertions/internal/oglematchers", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "SrDo9JDu6DyZ7I+4uQABY6EkW90=", + "path": "github.com/smartystreets/assertions/internal/oglemock", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "fqmDhb1Vu5Ian6bKOIK/qKHbfDY=", + "path": "github.com/smartystreets/assertions/internal/oglemock/sample/mock_io", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "iZ6XlO018Wjbq08EmI/gF98wWuI=", + "path": "github.com/smartystreets/assertions/internal/ogletest", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "Ji1ubfT/e0/n/ABIjm+SkAnB2nI=", + "path": "github.com/smartystreets/assertions/internal/ogletest/srcutil", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "Lq4IjivEPadH4fnuG/3uXyMZHEQ=", + "path": "github.com/smartystreets/assertions/internal/reqtrace", + "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", + "revisionTime": "2016-04-22T19:53:51Z" + }, + { + "checksumSHA1": "/mwAihy9AmznMzmbPQ5nWJXBiRU=", + "path": "github.com/smartystreets/goconvey/convey", + "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", + "revisionTime": "2016-05-23T15:31:47Z" + }, + { + "checksumSHA1": "9LakndErFi5uCXtY1KWl0iRnT4c=", + "path": "github.com/smartystreets/goconvey/convey/gotest", + "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", + "revisionTime": "2016-05-23T15:31:47Z" + }, + { + "checksumSHA1": "FWDhk37bhAwZ2363D/L2xePwR64=", + "path": "github.com/smartystreets/goconvey/convey/reporting", + "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", + "revisionTime": "2016-05-23T15:31:47Z" + }, + { + "checksumSHA1": "VK+UsykzUMkaKl2ankiyutolraE=", + "path": "github.com/spf13/pflag", + "revision": "24fa6976df40757dce6aea913e7b81ade90530e1", + "revisionTime": "2018-12-23T18:29:23Z" + }, + { + "checksumSHA1": "Bn333k9lTndxU3D6n/G5c+GMcYY=", + "path": "github.com/stretchr/testify/assert", + "revision": "8d64eb7173c7753d6419fd4a9caf057398611364", + "revisionTime": "2016-05-24T23:42:29Z" + }, + { + "checksumSHA1": "P9FJpir2c4G5PA46qEkaWy3l60U=", + "path": "github.com/stretchr/testify/require", + "revision": "8d64eb7173c7753d6419fd4a9caf057398611364", + "revisionTime": "2016-05-24T23:42:29Z" + }, + { + "checksumSHA1": "fi13nRs6FDnhY5kL/9eMcNF8rQ8=", + "path": "github.com/tchap/go-patricia/patricia", + "revision": "dd168db6051b704a01881df7e003cb7ec9a7a440", + "revisionTime": "2016-07-29T07:16:56Z" + }, + { + "checksumSHA1": "8Kj0VH496b0exuyv4wAF4CXa7Y4=", + "path": "github.com/yudai/gojsondiff", + "revision": "081cda2ee95045a2c26da52c2ba80860838549de", + "revisionTime": "2017-06-26T13:12:58Z" + }, + { + "checksumSHA1": "50gdo5Kq0/gEKG1A4agCPOZ26JA=", + "path": "github.com/yudai/gojsondiff/formatter", + "revision": "081cda2ee95045a2c26da52c2ba80860838549de", + "revisionTime": "2017-06-26T13:12:58Z" + }, + { + "checksumSHA1": "5xoBoioS8LWHn9FC0pL+vo7wDjs=", + "path": "github.com/yudai/golcs", + "revision": "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68", + "revisionTime": "2017-03-16T03:48:04Z" + }, + { + "checksumSHA1": "N5fb5y92DFIP+wUhi1rSwPp9vyk=", + "path": "golang.org/x/crypto/ssh/terminal", + "revision": "1777f3ba8c1fed80fcaec3317e3aaa4f627764d2", + "revisionTime": "2016-03-18T12:12:46Z" + }, + { + "checksumSHA1": "GtamqiJoL7PGHsN454AoffBFMa8=", + "path": "golang.org/x/net/context", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "EJMLw8rk55bsqmIpSMtVORJpSGo=", + "path": "golang.org/x/net/context/ctxhttp", + "revision": "fb93926129b8ec0056f2f458b1f519654814edf0", + "revisionTime": "2016-04-12T22:48:50Z" + }, + { + "checksumSHA1": "pCY4YtdNKVBYRbNvODjx8hj0hIs=", + "path": "golang.org/x/net/http/httpguts", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "QmfYRV9T2HIj1cvl2ZQCd6bXXKo=", + "path": "golang.org/x/net/http2", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "KZniwnfpWkaTPhUQDUTvgex/7y0=", + "path": "golang.org/x/net/http2/hpack", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "RcrB7tgYS/GMW4QrwVdMOTNqIU8=", + "path": "golang.org/x/net/idna", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "UxahDzW2v4mf/+aFxruuupaoIwo=", + "path": "golang.org/x/net/internal/timeseries", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=", + "path": "golang.org/x/net/lex/httplex", + "revision": "5f8847ae0d0e90b6a9dc8148e7ad616874625171", + "revisionTime": "2017-06-23T17:10:45Z" + }, + { + "checksumSHA1": "4vGl3N46SAJwQl/uSlQvZQvc734=", + "path": "golang.org/x/net/trace", + "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", + "revisionTime": "2018-11-14T21:44:15Z" + }, + { + "checksumSHA1": "4q+J7KldqFG28gkuEdHTyHgNcz4=", + "path": "golang.org/x/oauth2", + "revision": "04e1573abc896e70388bd387a69753c378d46466", + "revisionTime": "2016-07-30T22:43:56Z" + }, + { + "checksumSHA1": "Ml9aUD6MMJOwU2ZndUEWjQZA6cs=", + "path": "golang.org/x/oauth2/google", + "revision": "04e1573abc896e70388bd387a69753c378d46466", + "revisionTime": "2016-07-30T22:43:56Z" + }, + { + "checksumSHA1": "D3v/aqfB9swlaZcSksCoF+lbOqo=", + "path": "golang.org/x/oauth2/internal", + "revision": "04e1573abc896e70388bd387a69753c378d46466", + "revisionTime": "2016-07-30T22:43:56Z" + }, + { + "checksumSHA1": "A/8+i+ZrWYF+ihbus3fjWVi7u6I=", + "path": "golang.org/x/oauth2/jws", + "revision": "04e1573abc896e70388bd387a69753c378d46466", + "revisionTime": "2016-07-30T22:43:56Z" + }, + { + "checksumSHA1": "McqNj0/805YfYQJQGomeB0s+EcU=", + "path": "golang.org/x/oauth2/jwt", + "revision": "04e1573abc896e70388bd387a69753c378d46466", + "revisionTime": "2016-07-30T22:43:56Z" + }, + { + "checksumSHA1": "QmmEQv1jLvjlVGPsWewqeNYNoyk=", + "path": "golang.org/x/sys/unix", + "revision": "62eef0e2fa9b2c385f7b2778e763486da6880d37", + "revisionTime": "2018-11-22T14:36:24Z" + }, + { + "checksumSHA1": "Gwx30TD3lMSgskBCmXTDXbICPRQ=", + "path": "golang.org/x/text/collate", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "gRurdsue4RAi2xYzy89YDzO2c2I=", + "path": "golang.org/x/text/collate/build", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "fM/n4f1c26uIh3wB9g+1flJkSAo=", + "path": "golang.org/x/text/internal/colltab", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "ZQdHbB9VYCXwQ+9/CmZPhJv0+SM=", + "path": "golang.org/x/text/internal/gen", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "hyNCcTwMQnV6/MK8uUW9E5H0J0M=", + "path": "golang.org/x/text/internal/tag", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "47nwiUyVBY2RKoEGXmCSvusY4Js=", + "path": "golang.org/x/text/internal/triegen", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "Yd5wMObzagIfCiKLpZbtBIrOUA4=", + "path": "golang.org/x/text/internal/ucd", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "ckawpDnd22U/0HjSPKF4yY5pIeg=", + "path": "golang.org/x/text/language", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "CbpjEkkOeh0fdM/V8xKDdI0AA88=", + "path": "golang.org/x/text/secure/bidirule", + "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", + "revisionTime": "2018-10-29T18:00:05Z" + }, + { + "checksumSHA1": "o3YChxWLvyCmkAn/ZNBj9HC9zKw=", + "path": "golang.org/x/text/transform", + "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", + "revisionTime": "2018-10-29T18:00:05Z" + }, + { + "checksumSHA1": "qjFbU4RWY+Caxaa5/TlMJW82E+A=", + "path": "golang.org/x/text/unicode/bidi", + "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", + "revisionTime": "2018-10-29T18:00:05Z" + }, + { + "checksumSHA1": "+U+vu5UQXoIB4egXy7uX3GYBxVo=", + "path": "golang.org/x/text/unicode/cldr", + "revision": "fc7fa097411d30e6708badff276c4c164425590c", + "revisionTime": "2017-03-23T10:04:54Z" + }, + { + "checksumSHA1": "vAScJLvb0ucuuclyN9vmJUyWTBA=", + "path": "golang.org/x/text/unicode/norm", + "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", + "revisionTime": "2018-10-29T18:00:05Z" + }, + { + "checksumSHA1": "bLoGyjxHeYpHKEzU1g9f3m5qsnQ=", + "path": "golang.org/x/text/unicode/rangetable", + "revision": "4e9ab9ee170f2a39bd66c92b3e0a47ff47a4bc77", + "revisionTime": "2017-06-09T11:26:06Z" + }, + { + "checksumSHA1": "eFQDEix/mGnhwnFu/Hq63zMfrX8=", + "path": "golang.org/x/time/rate", + "revision": "f51c12702a4d776e4c1fa9b0fabab841babae631", + "revisionTime": "2016-10-28T04:02:39Z" + }, + { + "checksumSHA1": "I1JSeU5OMapl+4s2VrnBkMon3Bw=", + "path": "google.golang.org/api/gensupport", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "BWKmb7kGYbfbvXO6E7tCpTh9zKE=", + "path": "google.golang.org/api/googleapi", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "1K0JxrUfDqAB3MyRiU1LKjfHyf4=", + "path": "google.golang.org/api/googleapi/internal/uritemplates", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "Mr2fXhMRzlQCgANFm91s536pG7E=", + "path": "google.golang.org/api/googleapi/transport", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "nefIfmUzE2DJD4Tpodz+WHQLfeE=", + "path": "google.golang.org/api/internal", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "slcGOTGSdukEPPSN81Q5WZGmhog=", + "path": "google.golang.org/api/iterator", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "7u58UYArY+urG47WScM0HFdBahs=", + "path": "google.golang.org/api/iterator/testing", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "kEQSHsbkLxyIijEvp5W2SF3uqsU=", + "path": "google.golang.org/api/option", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "xygm9BwoCg7vc0PPgAPdxNKJ38c=", + "path": "google.golang.org/api/storage/v1", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "ztaquTYXuYLb5Kc6mtF64yrsA7E=", + "path": "google.golang.org/api/transport", + "revision": "55146ba61254fdb1c26d65ff3c04bc1611ad73fb", + "revisionTime": "2016-12-12T20:09:13Z" + }, + { + "checksumSHA1": "MgYFT27I9gfAtSVBpGVqkCYOj3U=", + "path": "google.golang.org/genproto/googleapis/rpc/status", + "revision": "b5d43981345bdb2c233eb4bf3277847b48c6fdc6", + "revisionTime": "2018-11-09T15:42:31Z" + }, + { + "checksumSHA1": "O6SQTcVdhL+4betKp/7ketCc/AU=", + "path": "google.golang.org/grpc", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "9KEKKMRAdFnz2sMBXbb33ZLS8Oo=", + "path": "google.golang.org/grpc/balancer", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "lw+L836hLeH8+//le+C+ycddCCU=", + "path": "google.golang.org/grpc/balancer/base", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "DJ1AtOk4Pu7bqtUMob95Hw8HPNw=", + "path": "google.golang.org/grpc/balancer/roundrobin", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "R3tuACGAPyK4lr+oSNt1saUzC0M=", + "path": "google.golang.org/grpc/codes", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "XH2WYcDNwVO47zYShREJjcYXm0Y=", + "path": "google.golang.org/grpc/connectivity", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "5r6NIQY1c3NjwLtxUOo/BcUOqFo=", + "path": "google.golang.org/grpc/credentials", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "QbufP1o0bXrtd5XecqdRCK/Vl0M=", + "path": "google.golang.org/grpc/credentials/oauth", + "revision": "8dea3dc473e90c8179e519d91302d0597c0ca1d1", + "revisionTime": "2018-09-11T17:48:51Z", + "version": "v1.15.0", + "versionExact": "v1.15.0" + }, + { + "checksumSHA1": "cfLb+pzWB+Glwp82rgfcEST1mv8=", + "path": "google.golang.org/grpc/encoding", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "LKKkn7EYA+Do9Qwb2/SUKLFNxoo=", + "path": "google.golang.org/grpc/encoding/proto", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "H7SuPUqbPcdbNqgl+k3ohuwMAwE=", + "path": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", + "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", + "revisionTime": "2018-04-04T21:41:50Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "ZPPSFisPDz2ANO4FBZIft+fRxyk=", + "path": "google.golang.org/grpc/grpclog", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "QyasSHZlgle+PHSIQ2/p+fr+ihY=", + "path": "google.golang.org/grpc/grpclog/glogger", + "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", + "revisionTime": "2018-04-04T21:41:50Z", + "version": "v1.11.2", + "versionExact": "v1.11.2" + }, + { + "checksumSHA1": "LVvnj/+AVrdZMDw0DZ8D/vI24+M=", + "path": "google.golang.org/grpc/internal", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "uDJA7QK2iGnEwbd9TPqkLaM+xuU=", + "path": "google.golang.org/grpc/internal/backoff", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "V6eyqZJfYh+cX+I/AxPVjkQLjTM=", + "path": "google.golang.org/grpc/internal/channelz", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "5dFUCEaPjKwza9kwKqgljp8ckU4=", + "path": "google.golang.org/grpc/internal/envconfig", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "70gndc/uHwyAl3D45zqp7vyHWlo=", + "path": "google.golang.org/grpc/internal/grpcrand", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "0r7S4jTgUIatKqL/8ra0J7Q5iO0=", + "path": "google.golang.org/grpc/internal/transport", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "350+v+N+AuknxomqjND19nR969g=", + "path": "google.golang.org/grpc/keepalive", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "OjIAi5AzqlQ7kLtdAyjvdgMf6hc=", + "path": "google.golang.org/grpc/metadata", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "VvGBoawND0urmYDy11FT+U1IHtU=", + "path": "google.golang.org/grpc/naming", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "n5EgDdBqFMa2KQFhtl+FF/4gIFo=", + "path": "google.golang.org/grpc/peer", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "GEq6wwE1qWLmkaM02SjxBmmnHDo=", + "path": "google.golang.org/grpc/resolver", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "grHAHa6Fi3WBsXJpmlEOlRbWWVg=", + "path": "google.golang.org/grpc/resolver/dns", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "zs9M4xE8Lyg4wvuYvR00XoBxmuw=", + "path": "google.golang.org/grpc/resolver/passthrough", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "YclPgme2gT3S0hTkHVdE1zAxJdo=", + "path": "google.golang.org/grpc/stats", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "hFyBO5vgsMamKhUOSyPCqROk1vo=", + "path": "google.golang.org/grpc/status", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "qvArRhlrww5WvRmbyMF2mUfbJew=", + "path": "google.golang.org/grpc/tap", + "revision": "2e463a05d100327ca47ac218281906921038fd95", + "revisionTime": "2018-10-23T17:37:47Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "sg7RY87LaWXaZMj0cuLQQaJJQYo=", + "path": "google.golang.org/grpc/transport", + "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", + "revisionTime": "2018-04-04T21:41:50Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "wSu8owMAP7GixsYoSZ4CmKUVhnU=", + "path": "gopkg.in/asn1-ber.v1", + "revision": "4e86f4367175e39f69d9358a5f17b4dda270378d", + "revisionTime": "2015-09-24T05:17:56Z" + }, + { + "checksumSHA1": "itYnRitfdzJjy2mZlvJ+hCJZvtY=", + "path": "gopkg.in/ldap.v2", + "revision": "8168ee085ee43257585e50c6441aadf54ecb2c9f", + "revisionTime": "2016-12-01T20:47:33Z" + }, + { + "checksumSHA1": "QqDq2x8XOU7IoOR98Cx1eiV5QY8=", + "path": "gopkg.in/yaml.v2", + "revision": "51d6538a90f86fe93ac480b35f37b2be17fef232", + "revisionTime": "2018-11-15T11:05:04Z" + }, + { + "checksumSHA1": "SKu9eS1cdg5bhRh6wH1n1RPNJ0Y=", + "path": "k8s.io/apimachinery/pkg/apis/meta/internalversion", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "1ufnWmjIV06+kIedtpUTD1P6XNI=", + "path": "k8s.io/apimachinery/pkg/util/cache", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "CX718PEuZSqd0wdl7XLwvXVDU0Q=", + "path": "k8s.io/apimachinery/pkg/util/diff", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "fczERLZcUAAgUx1CsBZxJWxA9jI=", + "path": "k8s.io/apimachinery/pkg/util/mergepatch", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "NzT7FlqpjsvcFg4g6hIzaQrIxqM=", + "path": "k8s.io/apimachinery/pkg/util/strategicpatch", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "WD+qdO4Qb6u0vJtDHV9tDAxyt+o=", + "path": "k8s.io/apimachinery/pkg/util/wait", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "Z0LTjblQqzGRHcnruaPaC6kBIiQ=", + "path": "k8s.io/apimachinery/third_party/forked/golang/json", + "revision": "9c4c366543346abeca2a5cd2c40cf1a30d19a2ec", + "revisionTime": "2018-12-27T06:29:47Z" + }, + { + "checksumSHA1": "c7siAy70Q7zFyMHPPQmUBxRhcps=", + "path": "k8s.io/client-go/discovery", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "TJF5qJbpD31iDClBkiboCqbGUOU=", + "path": "k8s.io/client-go/discovery/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "u7x85zvhgpeDGdjAb62wm21Z8DE=", + "path": "k8s.io/client-go/kubernetes", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "e10VuB0ZB7rz+2enlQ1CNTWgVH8=", + "path": "k8s.io/client-go/kubernetes/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "/5CSu81BakTuQZCrG+R0NJFbHXY=", + "path": "k8s.io/client-go/kubernetes/scheme", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "jsoiNHN9Z03/4K9KdwWAO9s3rPo=", + "path": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "ORWmQCeZYj7CZbv8RsFRjj3MYqw=", + "path": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "pmmsHaBIeDlD1LSw/KM2wVdYh2I=", + "path": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "OnHoXn4oYwnqW3DxpzuStMrgQVM=", + "path": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "t7UdbYz8ir1FewYR53Izec0Sivw=", + "path": "k8s.io/client-go/kubernetes/typed/apps/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "XgvgGhxs4wQGLNefoL+hLG4sUEU=", + "path": "k8s.io/client-go/kubernetes/typed/apps/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "JU//A2Vhtt2lmEJvjPSzotPbax4=", + "path": "k8s.io/client-go/kubernetes/typed/apps/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "tyFGxPkEpNKEX/iWDrYZr+Kzj9g=", + "path": "k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "09lwkraBQBm444xRhFCgefu8kck=", + "path": "k8s.io/client-go/kubernetes/typed/apps/v1beta2", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "2WyxOtZRM7jFlZxZoJpWrYWQ6Qw=", + "path": "k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "sSK15WvG4aK3PcUrDU1F5O94z4Q=", + "path": "k8s.io/client-go/kubernetes/typed/auditregistration/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "Op4a4nnnvCMcl/TLYBGEc6Npeks=", + "path": "k8s.io/client-go/kubernetes/typed/auditregistration/v1alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "z8RBQhqz0ef52GAYcGnHbdkRLQw=", + "path": "k8s.io/client-go/kubernetes/typed/authentication/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "FQdMfDrQILCK3PEEQVwM+hM2Sno=", + "path": "k8s.io/client-go/kubernetes/typed/authentication/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "xNCsaw6UsrEtSjg+2rMYZueCBIM=", + "path": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "COsWrq4VbNfuFe+xPfSIA8vvmXs=", + "path": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "m8sWDYsVaRB+meitgU1dx+1P0ow=", + "path": "k8s.io/client-go/kubernetes/typed/authorization/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "9PnX4JYlW448kQkKr9EZCxW0Ff8=", + "path": "k8s.io/client-go/kubernetes/typed/authorization/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "XucNO6BHSXXNkSQAM1ZdiwDmksc=", + "path": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "89z3RD2/yK6XDKRY8z6wC5hDbn0=", + "path": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "g6sY+YnoyJ+YKuJ23A7kBES6T+I=", + "path": "k8s.io/client-go/kubernetes/typed/autoscaling/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "yFhZxvXl0H6/8sBUJS/KNuGhKnc=", + "path": "k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "KH7kRVstgAg+9L6HoO/pggR9+eI=", + "path": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "DvNBHcSUgtkI5KDNKx5/fFaEJvo=", + "path": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "1gmsRcUU069YjYPVh42BxUugxlU=", + "path": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "mn/dtGqRkYE4pcMJ5iEzRq0hgZI=", + "path": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "u+SQV91fDXsbT35x1qDurWjWhOM=", + "path": "k8s.io/client-go/kubernetes/typed/batch/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "ily/PUET8aVOYOr6bpYgLwgqLqM=", + "path": "k8s.io/client-go/kubernetes/typed/batch/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "ydEd57JAnwWWXbOL6Y9XgOds7jE=", + "path": "k8s.io/client-go/kubernetes/typed/batch/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "+W2CkMniyX2YjxBiG5fdgx3LH2k=", + "path": "k8s.io/client-go/kubernetes/typed/batch/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "XbaL6H8hcf613bHRpLl8O8Ax1sQ=", + "path": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "LGxsJV5Brkg2qJHPM4MYvvjGMzQ=", + "path": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "4nR+ErKIrCr77OvOFJ3iqArk7Cc=", + "path": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "aGOsa/Af1HSTyO8i2VPLO6nG93A=", + "path": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "UnCB9l/X/xvB22kpT+Fyg0P80Rc=", + "path": "k8s.io/client-go/kubernetes/typed/coordination/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "w75NYIjszhN/JW42X1ukv631x5k=", + "path": "k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "8o+F1NeIfq4NY+AyeDcM7NyIKqw=", + "path": "k8s.io/client-go/kubernetes/typed/core/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "amuLV11aXO7W7QzCSaB5X0kyPKo=", + "path": "k8s.io/client-go/kubernetes/typed/core/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "ykLmGOjvLCr/URumft1aG8pkujo=", + "path": "k8s.io/client-go/kubernetes/typed/events/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "FmSgncp8EVHnSBQpClPCkLhEVVg=", + "path": "k8s.io/client-go/kubernetes/typed/events/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "HvngFdOekeng/h5wmYnmKQDLTEw=", + "path": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "eWzdOZw6UPhvK8uRzKLKTlxp/ec=", + "path": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "6gtdIT3Qp6z/kwgF0T3l+a1Ns4g=", + "path": "k8s.io/client-go/kubernetes/typed/networking/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "GHNO7bzp4qdqlVxv/sVzam20ai4=", + "path": "k8s.io/client-go/kubernetes/typed/networking/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "dVba4gvzMK97tqCVwwF69bue8tg=", + "path": "k8s.io/client-go/kubernetes/typed/policy/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "tE38c9HN26PThqfmlf5K0ZYIJYk=", + "path": "k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "8mzr6jmw61rtVvJ0aerLF91qQd0=", + "path": "k8s.io/client-go/kubernetes/typed/rbac/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "WHI6dE72BovTQsHIIUJ/nAP1xjg=", + "path": "k8s.io/client-go/kubernetes/typed/rbac/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "9Vdi03QcPkw8fOxMy8MwO1uHbl0=", + "path": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "qoGelOdykBNOraHNrJhttzqCus0=", + "path": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "+wa2e0UKWqLWJNajZ1/hHxvCe94=", + "path": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "40LMjBpNU4AN/dB/Meb+VNC5/J4=", + "path": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "44fHtB2fH5krsp71kJy6u10dj5s=", + "path": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "Xohs26o8BPS3szToOZIc6ByaqqE=", + "path": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "6y5FUtAVxgACmJIR98cB0tVzLbI=", + "path": "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "h2p3oD25cqUe0JOlTShpZHkfVGc=", + "path": "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "tIaveHngAO+OYXfaBtOLolwJiRs=", + "path": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "CORatE3iDZFSWD0X3L4Zx3RJMCs=", + "path": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "svzkNqhp1FHxdNd/iYojR/ZNdEU=", + "path": "k8s.io/client-go/kubernetes/typed/storage/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "EosiOVorOONkgIJUaStn7/2agzE=", + "path": "k8s.io/client-go/kubernetes/typed/storage/v1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "+DQkr+rhP6CAV5/PBa9mOkzBBbU=", + "path": "k8s.io/client-go/kubernetes/typed/storage/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "4VskhfAIAre2P//XeoiaBpWIsas=", + "path": "k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "wauHj3XgKuSoAOuuDqudqovY4jQ=", + "path": "k8s.io/client-go/kubernetes/typed/storage/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "r6gc9IJ5zWyYbHNtpKr6lN9atbs=", + "path": "k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "h3FUW5WICS1Nz9oLCDzjNsvqeM4=", + "path": "k8s.io/client-go/pkg/apis/clientauthentication", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "3vv7i98z1FygCauLZ4mg9RsT9Lk=", + "path": "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "6DMbz5JnwquAwMbT/w5aYt4D3Hc=", + "path": "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "ktNfV92Lly2Tp/6VBE/3iFH0ns8=", + "path": "k8s.io/client-go/pkg/version", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "d3gPzoqPqze/wfPs1jXitWCDybg=", + "path": "k8s.io/client-go/plugin/pkg/client/auth/exec", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "zTiUphCTUlvaFgDfv4eO9+GsSmg=", + "path": "k8s.io/client-go/rest", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "+wYCwQaVc1GvMWwOWc3wXd2GT5s=", + "path": "k8s.io/client-go/rest/watch", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "BTx9tqYtsDtZfBTm5925g5QiL2Y=", + "path": "k8s.io/client-go/testing", + "revision": "8145e5e321111a0a98d0ad71d8e54a5a93e12fd1", + "revisionTime": "2018-12-28T16:17:06Z" + }, + { + "checksumSHA1": "gx6Hc17LJ8Q/NPNm7ameWaldfEQ=", + "path": "k8s.io/client-go/tools/auth", + "revision": "e88b66d04fb772c1810357e9e0ca473f7e8bf243", + "revisionTime": "2018-12-21T18:03:36Z" + }, + { + "checksumSHA1": "wETbYjGOiPguU04+AS0sRSwYwqU=", + "path": "k8s.io/client-go/tools/cache", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "QNCZA1r4GlrjWq61ZNDc9pYf900=", + "path": "k8s.io/client-go/tools/clientcmd", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "4KsMHoSucjQi0FW3kqkFIPgssyk=", + "path": "k8s.io/client-go/tools/clientcmd/api", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "REsiLFxKYUjcTcPnDBwgr4GkArg=", + "path": "k8s.io/client-go/tools/clientcmd/api/latest", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "gOq6PL80JftrypouhV+xxbf/WUo=", + "path": "k8s.io/client-go/tools/clientcmd/api/v1", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "rRC9GCWXfyIXKHBCeKpw7exVybE=", + "path": "k8s.io/client-go/tools/metrics", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "E8JeIq/Zl3X94M8aPZuvYI0S8gg=", + "path": "k8s.io/client-go/tools/pager", + "revision": "8145e5e321111a0a98d0ad71d8e54a5a93e12fd1", + "revisionTime": "2018-12-28T16:17:06Z" + }, + { + "checksumSHA1": "n2h6CjJR1o+JM2snIIsCdcMMDWs=", + "path": "k8s.io/client-go/tools/reference", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "+kHJLa7t232fEEmjysMeRy5JYzs=", + "path": "k8s.io/client-go/transport", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "lTGzV+HgAXM6vWKFfedFLlIl94E=", + "path": "k8s.io/client-go/util/buffer", + "revision": "8145e5e321111a0a98d0ad71d8e54a5a93e12fd1", + "revisionTime": "2018-12-28T16:17:06Z" + }, + { + "checksumSHA1": "hDGF2m/JJN43zHnEnamwbYVmM54=", + "path": "k8s.io/client-go/util/cert", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "KSB22yQOaax0P/RkHCDp80u+Jcs=", + "path": "k8s.io/client-go/util/connrotation", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "yXKT7cJNCv5vjwGKhpc/DUsQg+A=", + "path": "k8s.io/client-go/util/flowcontrol", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "WRb0rXGx56fwcCisVW7GoI6gO/A=", + "path": "k8s.io/client-go/util/homedir", + "revision": "e88b66d04fb772c1810357e9e0ca473f7e8bf243", + "revisionTime": "2018-12-21T18:03:36Z" + }, + { + "checksumSHA1": "W6bJiNAwgNwNJC+y+TPtacgUGlY=", + "path": "k8s.io/client-go/util/integer", + "revision": "e64494209f554a6723674bd494d69445fb76a1d4", + "revisionTime": "2018-12-04T00:07:44Z", + "version": "=v10.0.0", + "versionExact": "v10.0.0" + }, + { + "checksumSHA1": "VK8XBxAuEr0Vp9W96bH1niYlLvc=", + "path": "k8s.io/client-go/util/retry", + "revision": "8145e5e321111a0a98d0ad71d8e54a5a93e12fd1", + "revisionTime": "2018-12-28T16:17:06Z" + }, + { + "checksumSHA1": "h2W7fCaCOwCsXxBgmm7pjzT/akk=", + "path": "k8s.io/kube-openapi/pkg/util/proto", + "revision": "0317810137be915b9cf888946c6e115c1bfac693", + "revisionTime": "2018-11-14T23:30:23Z" + } + ], + "rootPath": "vitess.io/vitess" +}